Section 16.2 General Quadratic Congruences
ΒΆQuestion 16.2.1.
For what primes p is there a solution to x2β‘k (mod p)?
solve_mod
works, if a little naively.
xxxxxxxxxx
solve_mod([x^2-2*x+3==0],9)
Sage note 16.2.2. Commands of more sophistication.
Notice that the solve_mod
command is more complicated than divmod
. solve_mod
returns a list of tuples, where a tuple of length one has a comma to indicate it's a tuple. (If you tried to solve a multivariate congruence you would find it returns a longer tuple.)
Subsection 16.2.1 Completing the square solves our woes
ΒΆThe key is completing the square! First let's do an example.Example 16.2.3.
Completing the square for x2β2x+3 is done by
so solving the original congruence reduces to solving
Then assuming I have a square root s of β2 (mod n), I just compute s+1 and I'm done! Go ahead and try this for a few different n, including of course n=9, with Sage.
xxxxxxxxxx
solve_mod([x^2==-2],9)
Algorithm 16.2.4. Completing the square modulo n.
To complete the square for ax2+bx+cβ‘0, the key thing to keep in mind is that we do not actually divide by 2a, but instead multiply by (2a)β1. Here are the steps.
Multiply by four and a: 4a2x2+4abx+4acβ‘0
Factor the square: (2ax+b)2βb2+4acβ‘0
Isolate the square: (2ax+b)2β‘b2β4ac
So to solve, we'll need that 2a is a unit (more or less requiring that n is odd), and then to find all square roots of b2β4ac in Zn.
Fact 16.2.5.
The full solution to
is the same as the set of solutions to
Note that this means gcd(2a,n)=1 must be true and that s2β‘b2β4ac must have a solution.
Example 16.2.6.
Let's do all this with x2+3x+5β‘0 (mod n). Notice that b2β4ac=9β20=β11, so this equation does not have a solution over the integers, or indeed over the real numbers. Does it have a solution in Zn for some n, though?
xxxxxxxxxx
L = [(n,solve_mod([x^2==-11],n)) for n in prime_range(3,100)]
for l in L:
L1 = [m[0] for m in l[1]]
modulus = l[0]
pretty_print(html(r"Modulo $%s$, $x^2\equiv -11$ has the solutions: %s"%(modulus,L1)))
if L1 != []:
try:
LS = [mod(2*1,modulus)^(-1)*(m-3) for m in L1]
pretty_print(html(r"For each of these, $x\equiv (2\cdot 1)^{-1}(s-3)$: %s"%(LS)))
LS = [ls^2+3*ls+5 for ls in LS]
pretty_print(html("And $x^2+3x+5$ gives for each of these: %s\n\n"%(LS)))
except ZeroDivisionError:
pretty_print(html("Since 2 doesn't have an inverse modulo $%s$, we can't use this.\n\n"%modulus))