Skip to content

Commit b5c9fed

Browse files
author
Release Manager
committed
Trac #34863: construct QuadraticForm and BinaryQF objects from polynomial
`QuadraticForm` and `BinaryQF` objects have a `.polynomial()` method to return the quadratic form represented as a multivariate polynomial, but the converse is not currently available. This patch adds it. URL: https://trac.sagemath.org/34863 Reported by: lorenz Ticket author(s): Lorenz Panny Reviewer(s): Matthias Koeppe
2 parents 17b7b0e + 9224d7e commit b5c9fed

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/sage/quadratic_forms/binary_qf.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,48 @@ def polynomial(self):
495495
self._poly = self(ZZ['x, y'].gens())
496496
return self._poly
497497

498+
@staticmethod
499+
def from_polynomial(poly):
500+
r"""
501+
Construct a :class:`BinaryQF` from a bivariate polynomial
502+
with integer coefficients. Inverse of :meth:`polynomial`.
503+
504+
EXAMPLES::
505+
506+
sage: R.<u,v> = ZZ[]
507+
sage: f = u^2 + 419*v^2
508+
sage: Q = BinaryQF.from_polynomial(f); Q
509+
x^2 + 419*y^2
510+
sage: Q.polynomial()
511+
x^2 + 419*y^2
512+
sage: Q.polynomial()(R.gens()) == f
513+
True
514+
515+
The method fails if the given polynomial is not a quadratic form::
516+
517+
sage: BinaryQF.from_polynomial(u^3 - 5*v)
518+
Traceback (most recent call last):
519+
...
520+
ValueError: polynomial has monomials of degree != 2
521+
522+
...or if the coefficients aren't integers::
523+
524+
sage: BinaryQF.from_polynomial(u^2/7 + v^2)
525+
Traceback (most recent call last):
526+
...
527+
TypeError: no conversion of this rational to integer
528+
"""
529+
R = poly.parent()
530+
from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base
531+
if not isinstance(R, MPolynomialRing_base) or R.ngens() != 2:
532+
raise TypeError(f'not a bivariate polynomial ring: {R}')
533+
if not all(mon.degree() == 2 for mon in poly.monomials()):
534+
raise ValueError(f'polynomial has monomials of degree != 2')
535+
x,y = R.gens()
536+
coeffs = (poly.monomial_coefficient(mon) for mon in (x**2, x*y, y**2))
537+
a,b,c = map(ZZ, coeffs)
538+
return BinaryQF(a, b, c)
539+
498540
@cached_method
499541
def discriminant(self):
500542
"""

src/sage/quadratic_forms/quadratic_form.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,46 @@ def polynomial(self,names='x'):
13001300
P = (V*M).dot_product(V)
13011301
return P
13021302

1303+
@staticmethod
1304+
def from_polynomial(poly):
1305+
r"""
1306+
Construct a :class:`QuadraticForm` from a multivariate
1307+
polynomial. Inverse of :meth:`polynomial`.
1308+
1309+
EXAMPLES::
1310+
1311+
sage: R.<x,y,z> = ZZ[]
1312+
sage: f = 5*x^2 - x*z - 3*y*z - 2*y^2 + 9*z^2
1313+
sage: Q = QuadraticForm.from_polynomial(f); Q
1314+
Quadratic form in 3 variables over Integer Ring with coefficients:
1315+
[ 5 0 -1 ]
1316+
[ * -2 -3 ]
1317+
[ * * 9 ]
1318+
sage: Q.polynomial()
1319+
5*x0^2 - 2*x1^2 - x0*x2 - 3*x1*x2 + 9*x2^2
1320+
sage: Q.polynomial()(R.gens()) == f
1321+
True
1322+
1323+
The method fails if the given polynomial is not a quadratic form::
1324+
1325+
sage: QuadraticForm.from_polynomial(x^3 + x*z + 5*y^2)
1326+
Traceback (most recent call last):
1327+
...
1328+
ValueError: polynomial has monomials of degree != 2
1329+
"""
1330+
R = poly.parent()
1331+
from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base
1332+
if not isinstance(R, MPolynomialRing_base):
1333+
raise TypeError(f'not a multivariate polynomial ring: {R}')
1334+
if not all(mon.degree() == 2 for mon in poly.monomials()):
1335+
raise ValueError(f'polynomial has monomials of degree != 2')
1336+
base = R.base_ring()
1337+
vs = R.gens()
1338+
coeffs = []
1339+
for i,v in enumerate(vs):
1340+
for w in vs[i:]:
1341+
coeffs.append(poly.monomial_coefficient(v*w))
1342+
return QuadraticForm(base, len(vs), coeffs)
13031343

13041344

13051345

0 commit comments

Comments
 (0)