Ternary Quadratic Form with integer coefficients.¶

AUTHOR:

• Gustavo Rama

Based in code of Gonzalo Tornaria

The form $$a*x^2 + b*y^2 + c*z^2 + r*yz + s*xz + t*xy$$ is stored as a tuple (a, b, c, r, s, t) of integers.

The TernaryQF class represents a quadratic form in 3 variables with coefficients in Z.

INPUT:

• $$v$$ – a list or tuple of 6 entries: [a,b,c,r,s,t]

OUTPUT:

• the ternary quadratic form a*x^2 + b*y^2 + c*z^2 + r*y*z + s*x*z + t*x*y.

EXAMPLES:

sage: Q = TernaryQF([1, 2, 3, 4, 5, 6])
sage: Q
Ternary quadratic form with integer coefficients:
[1 2 3]
[4 5 6]
sage: A = matrix(ZZ, 3, [1, -7, 1, 0, -2, 1, 0, -1, 0])
sage: Q(A)
Ternary quadratic form with integer coefficients:
[1 187 9]
[-85 8 -31]
sage: TestSuite(TernaryQF).run()

Returns the adjoint form associated to the given ternary quadratic form. That is, the Hessian matrix of the adjoint form is twice the classical adjoint matrix of the Hessian matrix of the given form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 17, 0, 0, 1])
Ternary quadratic form with integer coefficients:
[68 68 3]
[0 0 -68]
True
automorphism_spin_norm(A)

Return the spin norm of the automorphism A.

EXAMPLES:

sage: Q = TernaryQF([9, 12, 30, -26, -28, 20])
sage: A = matrix(ZZ, 3, [9, 10, -10, -6, -7, 6, 2, 2, -3])
sage: A.det()
1
sage: Q(A) == Q
True
sage: Q.automorphism_spin_norm(A)
7
automorphism_symmetries(A)

Given the automorphism A, returns two vectors v1, v2 if A is not the identity. Such that the product of the symmetries of the ternary quadratic form given by the two vectors is A.

EXAMPLES:

sage: Q = TernaryQF([9, 12, 30, -26, -28, 20])
sage: A = matrix(ZZ, 3, [9, 10, -10, -6, -7, 6, 2, 2, -3])
sage: Q(A) == Q
True
sage: v1, v2 = Q.automorphism_symmetries(A)
sage: v1, v2
((8, -6, 2), (1, -5/4, -1/4))
sage: A1 = Q.symmetry(v1)
sage: A1
[    9     9   -13]
[   -6 -23/4  39/4]
[    2   9/4  -9/4]
sage: A2 = Q.symmetry(v2)
sage: A2
[    1     1     3]
[    0  -1/4 -15/4]
[    0  -1/4   1/4]
sage: A1*A2 == A
True
sage: Q.automorphism_symmetries(identity_matrix(ZZ,3))
[]
automorphisms(slow=True)

Returns a list with the automorphisms of the definite ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 7, 0, 0, 0])
sage: auts = Q.automorphisms()
sage: auts
[
[-1  0  0]  [-1  0  0]  [ 0 -1  0]  [ 0 -1  0]  [ 0  1  0]  [ 0  1  0]
[ 0 -1  0]  [ 0  1  0]  [-1  0  0]  [ 1  0  0]  [-1  0  0]  [ 1  0  0]
[ 0  0  1], [ 0  0 -1], [ 0  0 -1], [ 0  0  1], [ 0  0  1], [ 0  0 -1],
[ 1  0  0]  [1 0 0]
[ 0 -1  0]  [0 1 0]
[ 0  0 -1], [0 0 1]
]
sage: all(Q == Q(A) for A in auts)
True
sage: Q = TernaryQF([3, 4, 5, 3, 3, 2])
sage: Q.automorphisms(slow = False)
[
[1 0 0]
[0 1 0]
[0 0 1]
]
sage: Q = TernaryQF([4, 2, 4, 3, -4, -5])
sage: auts = Q.automorphisms(slow = False)
sage: auts
[
[1 0 0]  [ 2 -1 -1]
[0 1 0]  [ 3 -2 -1]
[0 0 1], [ 0  0 -1]
]
sage: A = auts
sage: Q(A) == Q
True
sage: Qr, M_red = Q.reduced_form_eisenstein()
sage: Qr
Ternary quadratic form with integer coefficients:
[1 2 3]
[-1 0 -1]
sage: Q(A*M_red) == Qr
True
basic_lemma(p)

Finds a number represented by self and coprime to the prime p.

EXAMPLES:

sage: Q = TernaryQF([3, 3, 3, -2, 0, -1])
sage: Q.basic_lemma(3)
4
coefficient(n)

Return the n-th coefficient of the ternary quadratic form, with 0<=n<=5.

EXAMPLES:

sage: Q = TernaryQF([1, 2, 3, 4, 5, 6])
sage: Q
Ternary quadratic form with integer coefficients:
[1 2 3]
[4 5 6]
sage: Q.coefficient(2)
3
sage: Q.coefficient(5)
6
coefficients()

Return the list coefficients of the ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([1, 2, 3, 4, 5, 6])
sage: Q
Ternary quadratic form with integer coefficients:
[1 2 3]
[4 5 6]
sage: Q.coefficients()
(1, 2, 3, 4, 5, 6)
content()

Returns the greatest common divisor of the coefficients of the given ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 2, 0, 0, 0])
sage: Q.content()
1
sage: Q = TernaryQF([2, 4, 6, 0, 0, 0])
sage: Q.content()
2
sage: Q.scale_by_factor(100).content()
200
delta()

Returns the omega of the adjoint of the given ternary quadratic form, which is the same as the omega of the reciprocal form.

EXAMPLES:

sage: Q = TernaryQF([1, 2, 2, -1, 0, -1])
sage: Q.delta()
208
208
sage: Q = TernaryQF([1, -1, 1, 0, 0, 0])
sage: Q.delta()
4
sage: Q.omega()
4
disc()

Return the discriminant of the ternary quadratic form, this is the determinant of the matrix divided by 2.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 2, 0, -1, 4])
sage: Q.disc()
-25
sage: Q.matrix().det()
-50
divisor()

Returns the content of the adjoint form associated to the given form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 17, 0, 0, 0])
sage: Q.divisor()
4
find_p_neighbor_from_vec(p, v, mat=False)

Finds the reduced equivalent of the p-neighbor of this ternary quadratic form associated to a given vector v satisfying:

1. Q(v) = 0 mod p
2. v is a non-singular point of the conic Q(v) = 0 mod p.

Reference: Gonzalo Tornaria’s Thesis, Thrm 3.5, p34.

EXAMPLES:

sage: Q = TernaryQF([1, 3, 3, -2, 0, -1])
sage: Q
Ternary quadratic form with integer coefficients:
[1 3 3]
[-2 0 -1]
sage: Q.disc()
29
sage: v = (9, 7, 1)
sage: v in Q.find_zeros_mod_p(11)
True
sage: Q11, M = Q.find_p_neighbor_from_vec(11, v, mat = True)
sage: Q11
Ternary quadratic form with integer coefficients:
[1 2 4]
[-1 -1 0]
sage: M
[    -1  -5/11   7/11]
[     0 -10/11   3/11]
[     0  -3/11  13/11]
sage: Q(M) == Q11
True
find_p_neighbors(p, mat=False)

Find a list with all the reduced equivalent of the p-neighbors of this ternary quadratic form, given by the zeros mod p of the form. See find_p_neighbor_from_vec for more information.

EXAMPLES:

sage: Q0 = TernaryQF([1, 3, 3, -2, 0, -1])
sage: Q0
Ternary quadratic form with integer coefficients:
[1 3 3]
[-2 0 -1]
sage: neig = Q0.find_p_neighbors(5)
sage: len(neig)
6
sage: Q1 = TernaryQF([1, 1, 10, 1, 1, 1])
sage: Q2 = TernaryQF([1, 2, 4, -1, -1, 0])
sage: neig.count(Q0)
2
sage: neig.count(Q1)
1
sage: neig.count(Q2)
3
find_zeros_mod_p(p)

Find the zeros of the given ternary quadratic positive definite form modulo a prime p, where p doesn’t divides the discriminant of the form.

EXAMPLES:

sage: Q = TernaryQF([4, 7, 8, -4, -1, -3])
sage: Q.is_positive_definite()
True
sage: Q.disc().factor()
3 * 13 * 19
sage: Q.find_zeros_mod_p(2)
[(1, 0, 0), (1, 1, 0), (0, 0, 1)]
sage: zeros_17 = Q.find_zeros_mod_p(17)
sage: len(zeros_17)
18
sage: [Q(v)%17 for v in zeros_17]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
is_definite()

Determines if the ternary quadratic form is definite.

EXAMPLES:

sage: Q = TernaryQF([10, 10, 1, -1, 2, 3])
sage: Q.is_definite()
True
sage: (-Q).is_definite()
True
sage: Q = TernaryQF([1, 1, 2, -3, 0, -1])
sage: Q.is_definite()
False
is_eisenstein_reduced()

Determines if the ternary quadratic form is Eisenstein reduced. That is, if we have a ternary quadratic form:

[a b c]
[r s t]

then

1- a<=b<=c;
2- r, s, and t are all positive or all nonpositive;
3- a>=|t|; a>=|s|; b>=|r|;
4- a+b+r+s+t>=0;
5- a=t implies s<=2*r; a=s implies t<=2*r; b=r implies t<=2*s;
6- a=-t implies s=0; a=-s implies t=0; b=-r implies t=0;
7- a+b+r+s+t=0 implies 2*a+2*s+t<=0;
8- a=b implies |r|<=|s|; b=c implies |s|<=|t|.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 1, 0, 0, 0])
sage: Q.is_eisenstein_reduced()
True
sage: Q = TernaryQF([34, 14, 44, 12, 25, -22])
sage: Q.is_eisenstein_reduced()
False
is_negative_definite()

Determine if the ternary quadratic form is negative definite.

EXAMPLES:

sage: Q = TernaryQF([-8, -9, -10, 1, 9, -3])
sage: Q.is_negative_definite()
True
sage: Q = TernaryQF([-4, -1, 6, -5, 1, -5])
sage: Q((0, 0, 1))
6
sage: Q.is_negative_definite()
False
is_positive_definite()

Determines if the ternary quadratic form is positive definite.

EXAMPLES:

sage: Q = TernaryQF([10, 10, 1, -1, 2, 3])
sage: Q.is_positive_definite()
True
sage: (-Q).is_positive_definite()
False
sage: Q = TernaryQF([1, 1, 0, 0, 0, 0])
sage: Q.is_positive_definite()
False
sage: Q = TernaryQF([1, 1, 1, -1, -2, -3])
sage: Q((1,1,1))
-3
sage: Q.is_positive_definite()
False
is_primitive()

Determines if the ternary quadratic form is primitive, i.e. the greatest common divisor of the coefficients of the form is 1.

EXAMPLES:

sage: Q = TernaryQF([1, 2, 3, 4, 5, 6])
sage: Q.is_primitive()
True
sage: Q.content()
1
sage: Q = TernaryQF([10, 10, 10, 5, 5, 5])
sage: Q.content()
5
sage: Q.is_primitive()
False
level()

Returns the level of the ternary quadratic form, which is 4 times the discriminant divided by the divisor.

EXAMPLES:

sage: Q = TernaryQF([1, 2, 2, -1, 0, -1])
sage: Q.level()
52
sage: 4*Q.disc()/Q.divisor()
52
matrix()

Return the Hessian matrix associated to the ternary quadratic form. That is, if Q is a ternary quadratic form, Q(x,y,z) = a*x^2 + b*y^2 + c*z^2 + r*y*z + s*x*z + t*x*y, then the Hessian matrix associated to Q is

[2*a t s]
[t 2*b r]
[s r 2*c]

EXAMPLES:

sage: Q = TernaryQF([1,1,2,0,-1,4])
sage: Q
Ternary quadratic form with integer coefficients:
[1 1 2]
[0 -1 4]
sage: M = Q.matrix()
sage: M
[ 2  4 -1]
[ 4  2  0]
[-1  0  4]
sage: v = vector((1, 2, 3))
sage: Q(v)
28
sage: (v*M*v.column())//2
28
number_of_automorphisms(slow=True)

Return the number of automorphisms of the definite ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 7, 0, 0, 0])
sage: A = matrix(ZZ, 3, [0, 1, 0, -1, 5, 0, -8, -1, 1])
sage: A.det()
1
sage: Q1 = Q(A)
sage: Q1
Ternary quadratic form with integer coefficients:
[449 33 7]
[-14 -112 102]
sage: Q1.number_of_automorphisms()
8
sage: Q = TernaryQF([-19, -7, -6, -12, 20, 23])
sage: Q.is_negative_definite()
True
sage: Q.number_of_automorphisms(slow = False)
24
omega()

Returns the content of the adjoint of the primitive associated ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([4, 11, 12, 0, -4, 0])
sage: Q.omega()
176
176
polynomial(names='x, y, z')

Return the polynomial associated to the ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 0, 2, -3, -1])
sage: Q
Ternary quadratic form with integer coefficients:
[1 1 0]
[2 -3 -1]
sage: p = Q.polynomial()
sage: p
x^2 - x*y + y^2 - 3*x*z + 2*y*z
sage: p.parent()
Multivariate Polynomial Ring in x, y, z over Integer Ring
primitive()

Returns the primitive version of the ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([2, 2, 2, 1, 1, 1])
sage: Q.is_primitive()
True
sage: Q.primitive()
Ternary quadratic form with integer coefficients:
[2 2 2]
[1 1 1]
sage: Q.primitive() == Q
True
sage: Q = TernaryQF([10, 10, 10, 5, 5, 5])
sage: Q.primitive()
Ternary quadratic form with integer coefficients:
[2 2 2]
[1 1 1]
pseudorandom_primitive_zero_mod_p(p)

Returns a tuple of the form v = (a, b, 1) such that is a zero of the given ternary quadratic positive definite form modulo an odd prime p, where p doesn’t divides the discriminant of the form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 11, 0, -1, 0])
sage: Q.disc()
43
sage: Q.pseudorandom_primitive_zero_mod_p(3)  ## RANDOM
(1, 2, 1)
sage: Q((1, 2, 1))
15
sage: v = Q.pseudorandom_primitive_zero_mod_p(1009)
sage: Q(v) % 1009
0
sage: v
1

Return the object QuadraticForm with the same coefficients as Q over ZZ.

EXAMPLES:

sage: Q = TernaryQF([1, 2, 3, 1, 1, 1])
sage: QF1 = Q.quadratic_form()
sage: QF1
Quadratic form in 3 variables over Integer Ring with coefficients:
[ 1 1 1 ]
[ * 2 1 ]
[ * * 3 ]
sage: QF2 = QuadraticForm(ZZ, 3, [1, 1, 1, 2, 1, 3])
sage: bool(QF1 == QF2)
True
reciprocal()

Gives the reciprocal quadratic form associated to the given form. This is defined as the multiple of the primitive adjoint with the same content as the given form.

EXAMPLES:

sage: Q = TernaryQF([2, 2, 14, 0, 0, 0])
sage: Q.reciprocal()
Ternary quadratic form with integer coefficients:
[14 14 2]
[0 0 0]
sage: Q.content()
2
sage: Q.reciprocal().content()
2
16
reciprocal_reduced()

Returns the reduced form of the reciprocal form of the given ternary quadratic form.

EXAMPLES:

sage: Q = TernaryQF([1, 1, 3, 0, -1, 0])
sage: Qrr = Q.reciprocal_reduced()
sage: Qrr
Ternary quadratic form with integer coefficients:
[4 11 12]
[0 -4 0]
sage: Q.is_eisenstein_reduced()
True
sage: Qr = Q.reciprocal()
sage: Qr.reduced_form_eisenstein(matrix = False) == Qrr
True
reduced_form_eisenstein(matrix=True)

Returns the eisenstein reduced form equivalent to the given positive ternary quadratic form, which is unique.

EXAMPLES:

sage: Q = TernaryQF([293, 315, 756, 908, 929, 522])
sage: Qr, m = Q.reduced_form_eisenstein()
sage: Qr
Ternary quadratic form with integer coefficients:
[1 2 2]
[-1 0 -1]
sage: Qr.is_eisenstein_reduced()
True
sage: m
[ -54  137  -38]
[ -23   58  -16]
[  47 -119   33]
sage: m.det()
1
sage: Q(m) == Qr
True
sage: Q = TernaryQF([12,36,3,14,-7,-19])
sage: Q.reduced_form_eisenstein(matrix = False)
Ternary quadratic form with integer coefficients:
[3 8 20]
[3 2 1]
scale_by_factor(k)

Scale the values of the ternary quadratic form by the number c, if c times the content of the ternary quadratic form is an integer it returns a ternary quadratic form, otherwise returns a quadratic form of dimension 3.

EXAMPLES:

sage: Q = TernaryQF([2, 2, 4, 0, -2, 8])
sage: Q
Ternary quadratic form with integer coefficients:
[2 2 4]
[0 -2 8]
sage: Q.scale_by_factor(5)
Ternary quadratic form with integer coefficients:
[10 10 20]
[0 -10 40]
sage: Q.scale_by_factor(1/2)
Ternary quadratic form with integer coefficients:
[1 1 2]
[0 -1 4]
sage: Q.scale_by_factor(1/3)
Quadratic form in 3 variables over Rational Field with coefficients:
[ 2/3 8/3 -2/3 ]
[ * 2/3 0 ]
[ * * 4/3 ]
symmetry(v)

Returns A the automorphism of the ternary quadratic form such that:

• A*v = -v.
• A*u = 0, if u is orthogonal to v.

where v is a given vector.

EXAMPLES:

sage: Q = TernaryQF([4, 5, 8, 5, 2, 2])
sage: v = vector((1,1,1))
sage: M = Q.symmetry(v)
sage: M
[  7/13 -17/26 -23/26]
[ -6/13   9/26 -23/26]
[ -6/13 -17/26   3/26]
sage: M.det()
-1
sage: M*v
(-1, -1, -1)
sage: v1 = vector((23, 0, -12))
sage: v2 = vector((0, 23, -17))
sage: v1*Q.matrix()*v
0
sage: v2*Q.matrix()*v
0
sage: M*v1 == v1
True
sage: M*v2 == v2
True
xi(p)

Return the value of the genus characters Xi_p… which may be missing one character. We allow -1 as a prime.

Reference: Dickson’s “Studies in the Theory of Numbers”

EXAMPLES:

sage: Q1 = TernaryQF([26, 42, 53, -36, -17, -3])
sage: Q2 = Q1.find_p_neighbors(2)
sage: Q1.omega()
3
sage: Q1.xi(3), Q2.xi(3)
(-1, -1)
xi_rec(p)

Returns Xi(p) for the reciprocal form.

EXAMPLES:

sage: Q1 = TernaryQF([1, 1, 7, 0, 0, 0])
sage: Q2 = Q1.find_p_neighbors(3)
sage: Q1.delta()
28
sage: Q1.xi_rec(7), Q2.xi_rec(7)
(1, 1)

Find a reduced ternary quadratic form given its discriminant d and level N. If N|4d and d|N^2, then it may be a form with that discriminant and level.

EXAMPLES:

sage: Q1 = find_a_ternary_qf_by_level_disc(44, 11)
sage: Q1
Ternary quadratic form with integer coefficients:
[1 1 3]
[0 -1 0]
sage: Q2 = find_a_ternary_qf_by_level_disc(44, 11^2 * 16)
sage: Q2
Ternary quadratic form with integer coefficients:
[3 15 15]
[-14 -2 -2]
sage: Q1.is_eisenstein_reduced()
True
sage: Q1.level()
44
sage: Q1.disc()
11
sage: find_a_ternary_qf_by_level_disc(44, 22)
sage: find_a_ternary_qf_by_level_disc(44, 33)
Traceback (most recent call last):
...
ValueError: There are no ternary forms of this level and discriminant

Find the coefficients of all the reduced ternary quadratic forms given its discriminant d and level N. If N|4d and d|N^2, then it may be some forms with that discriminant and level.

EXAMPLES:

sage: find_all_ternary_qf_by_level_disc(44, 11)
[Ternary quadratic form with integer coefficients:
[1 1 3]
[0 -1 0], Ternary quadratic form with integer coefficients:
[1 1 4]
[1 1 1]]
sage: find_all_ternary_qf_by_level_disc(44, 11^2 * 16)
[Ternary quadratic form with integer coefficients:
[3 15 15]
[-14 -2 -2], Ternary quadratic form with integer coefficients:
[4 11 12]
[0 -4 0]]
sage: Q = TernaryQF([1, 1, 3, 0, -1, 0])
sage: Q.is_eisenstein_reduced()
True
sage: Q.reciprocal_reduced()
Ternary quadratic form with integer coefficients:
[4 11 12]
[0 -4 0]
sage: find_all_ternary_qf_by_level_disc(44, 22)
[]
sage: find_all_ternary_qf_by_level_disc(44, 33)
Traceback (most recent call last):
...
ValueError: There are no ternary forms of this level and discriminant