Solving quadratic equations

Interface to the PARI/GP quadratic forms code of Denis Simon.

AUTHORS:

  • Denis Simon (GP code)

  • Nick Alexander (Sage interface)

  • Jeroen Demeyer (2014-09-23): use PARI instead of GP scripts, return vectors instead of tuples (trac ticket #16997).

  • Tyler Gaona (2015-11-14): added the \(solve\) method

sage.quadratic_forms.qfsolve.qfparam(G, sol)

Parametrizes the conic defined by the matrix G.

INPUT:

  • G – a \(3 \times 3\)-matrix over \(\QQ\).

  • sol – a triple of rational numbers providing a solution to sol*G*sol^t = 0.

OUTPUT:

A triple of polynomials that parametrizes all solutions of x*G*x^t = 0 up to scaling.

ALGORITHM:

Uses PARI/GP function qfparam.

EXAMPLES:

sage: from sage.quadratic_forms.qfsolve import qfsolve, qfparam
sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
[  0   0 -12]
[  0 -12   0]
[-12   0  -1]
sage: sol = qfsolve(M)
sage: ret = qfparam(M, sol); ret
(-12*t^2 - 1, 24*t, 24)
sage: ret.parent()
Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in t over Rational Field
sage.quadratic_forms.qfsolve.qfsolve(G)

Find a solution \(x = (x_0,...,x_n)\) to \(x G x^t = 0\) for an \(n \times n\)-matrix G over \(\QQ\).

OUTPUT:

If a solution exists, return a vector of rational numbers \(x\). Otherwise, returns \(-1\) if no solution exists over the reals or a prime \(p\) if no solution exists over the \(p\)-adic field \(\QQ_p\).

ALGORITHM:

Uses PARI/GP function qfsolve.

EXAMPLES:

sage: from sage.quadratic_forms.qfsolve import qfsolve
sage: M = Matrix(QQ, [[0, 0, -12], [0, -12, 0], [-12, 0, -1]]); M
[  0   0 -12]
[  0 -12   0]
[-12   0  -1]
sage: sol = qfsolve(M); sol
(1, 0, 0)
sage: sol.parent()
Vector space of dimension 3 over Rational Field

sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
sage: ret = qfsolve(M); ret
-1
sage: ret.parent()
Integer Ring

sage: M = Matrix(QQ, [[1, 0, 0], [0, 1, 0], [0, 0, -7]])
sage: qfsolve(M)
7

sage: M = Matrix(QQ, [[3, 0, 0, 0], [0, 5, 0, 0], [0, 0, -7, 0], [0, 0, 0, -11]])
sage: qfsolve(M)
(3, -4, -3, -2)
sage.quadratic_forms.qfsolve.solve(self, c=0)

Return a vector \(x\) such that self(x) == c.

INPUT:

  • c – (default: 0) a rational number.

OUTPUT:

  • A non-zero vector \(x\) satisfying self(x) == c.

ALGORITHM:

Uses PARI’s qfsolve(). Algorithm described by Jeroen Demeyer; see comments on trac ticket #19112

EXAMPLES:

sage: F = DiagonalQuadraticForm(QQ, [1, -1]); F
Quadratic form in 2 variables over Rational Field with coefficients:
[ 1 0 ]
[ * -1 ]
sage: F.solve()
(1, 1)
sage: F.solve(1)
(1, 0)
sage: F.solve(2)
(3/2, -1/2)
sage: F.solve(3)
(2, -1)
sage: F = DiagonalQuadraticForm(QQ, [1, 1, 1, 1])
sage: F.solve(7)
(1, 2, -1, -1)
sage: F.solve()
Traceback (most recent call last):
...
ArithmeticError: no solution found (local obstruction at -1)
sage: Q = QuadraticForm(QQ, 2, [17, 94, 130])
sage: x = Q.solve(5); x
(17, -6)
sage: Q(x)
5

sage: Q.solve(6)
Traceback (most recent call last):
...
ArithmeticError: no solution found (local obstruction at 3)

sage: G = DiagonalQuadraticForm(QQ, [5, -3, -2])
sage: x = G.solve(10); x
(3/2, -1/2, 1/2)
sage: G(x)
10

sage: F = DiagonalQuadraticForm(QQ, [1, -4])
sage: x = F.solve(); x
(2, 1)
sage: F(x)
0
sage: F = QuadraticForm(QQ, 4, [0, 0, 1, 0, 0, 0, 1, 0, 0, 0]); F
Quadratic form in 4 variables over Rational Field with coefficients:
[ 0 0 1 0 ]
[ * 0 0 1 ]
[ * * 0 0 ]
[ * * * 0 ]
sage: F.solve(23)
(23, 0, 1, 0)

Other fields besides the rationals are currently not supported:

sage: F = DiagonalQuadraticForm(GF(11), [1, 1])
sage: F.solve()
Traceback (most recent call last):
...
TypeError: solving quadratic forms is only implemented over QQ