Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Trac #13630: implement padic (x)gcd for fixed mod polynomials
Browse files Browse the repository at this point in the history
  • Loading branch information
saraedum authored and nilesjohnson committed Jan 28, 2014
1 parent abc6b02 commit c4b3743
Show file tree
Hide file tree
Showing 2 changed files with 998 additions and 2 deletions.
182 changes: 181 additions & 1 deletion src/sage/rings/padics/generic_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@
AUTHORS:
- David Roe
- Julian Rueth (2012-09-05): (x)gcd for polynomials
"""
#*****************************************************************************
# Copyright (C) 2009 David Roe <roed@math.harvard.edu>
# 2012 Julian Rueth <julian.rueth@fsfe.org>
#
# Distributed under the terms of the GNU General Public License (GPL)
# as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
# http://www.gnu.org/licenses/
#*****************************************************************************

from sage.rings.padics.local_generic import LocalGeneric
from sage.rings.padics.padic_generic import pAdicGeneric
Expand Down Expand Up @@ -229,7 +240,176 @@ class pAdicFieldGeneric(pAdicGeneric, Field):
# raise NotImplementedError

class pAdicFixedModRingGeneric(pAdicRingGeneric, FixedModGeneric):
pass
def _gcd_univariate_polynomial(self, f, g):
"""
Compute a greatest common divisor of the polynomials ``f`` and ``g``.
This is a helper method for
:meth:`sage.rings.polynomial.polynomial_element.Polynomial.gcd`. Its
implementation relies on
:meth:`sage.rings.padics.padic_generic.pAdicGeneric._gcd_univariate_polynomial_fixed`
which should be consulted for further details and examples.
INPUT:
- ``f``, ``g`` -- two polynomials defined over ``self``.
OUTPUT:
A polynomial defined over ``self``, and the precision to which this
result is accurate (see
:meth:`sage.rings.padics.padic_generic.pAdicGeneric.__xgcd_univariate_polynomial_fixed`
for the precise meaning of this accuracy.)
AUTHORS:
- Julian Rueth (2012-09-05): initial version
EXAMPLES::
sage: R.<t> = ZpFM(3,20)[]
sage: (t + 1).gcd( (t - 1) * (t + 1) )
((1 + O(3^20))*t + (1 + O(3^20)), 20)
sage: (t^3).gcd( t^5 )
((1 + O(3^20))*t^3, 20)
Also works over extensions::
sage: K = ZpFM(3,20)
sage: R.<a> = K[]
sage: L.<a> = K.extension( a^2 - 3 ) # Eisenstein extension
sage: R.<t> = L[]
sage: a0,a1,a2 = 12345678+a,90123456-a,78901234*a
sage: f = (t - a0) * (t - a1)^2 * (t - a2)^3
sage: g,prec = f.gcd(f.derivative())
sage: h = ((t - a1) * (t - a2)^2) # the correct result
sage: g.degree() == h.degree()
True
sage: all([(c1-c2).is_zero(prec) for c1,c2 in zip(list(g),list(h))]) # g and h are equal mod a^prec
True
sage: R.<a> = K[]
sage: L.<a> = K.extension( a^2 - 2 ) # unramified extension
sage: R.<t> = L[]
sage: a0,a1,a2 = 12345678+a,90123456-a,78901234*a
sage: f = (t - a0) * (t - a1)^2 * (t - a2)^3
sage: g,prec = f.gcd(f.derivative())
sage: h = ((t - a1) * (t - a2)^2) # the correct result
sage: g.degree() == h.degree()
True
sage: all([(c1-c2).is_zero(prec) for c1,c2 in zip(list(g),list(h))]) # g and h are equal mod p^prec
True
TESTS:
Check that the examples from :trac:`13439` work::
sage: R.<t> = ZpFM(3,3)[]
sage: f = 3*t + 7
sage: g = 5*t + 9
sage: f.gcd(f*g)
((3 + O(3^3))*t + (1 + 2*3 + O(3^3)), 2)
sage: R.<t> = ZpFM(3,20)[]
sage: f = 729*490473657*t + 257392844
sage: g = 225227399*t - 59049*8669753175
sage: h,prec = f.gcd(f*g)
sage: h.degree() == f.degree()
True
sage: h *= f.leading_coefficient().unit_part()
sage: all([(c1-c2).is_zero(prec) for c1,c2 in zip(list(f),list(h))]) # f and h are equal mod p^prec
True
"""
return self._gcd_univariate_polynomial_fixed(f, g)

def _xgcd_univariate_polynomial(self, f, g):
"""
Compute an extended greatest common divisor of the polynomials ``f``
and ``g``.
This is a helper method for
:meth:`sage.rings.polynomial.polynomial_element.Polynomial.xgcd`. Its
implementation relies on
:meth:`sage.rings.padics.padic_generic.pAdicGeneric._xgcd_univariate_polynomial_fixed`
which should be consulted for further details and examples.
INPUT:
- ``f``, ``g`` -- two polynomials defined over ``self``.
OUTPUT:
A tuple ``r,prec,s,t`` which satisfies ``r = s*f + t*g`` when reduced
to precision ``prec``. (see
:meth:`sage.rings.padics.padic_generic.pAdicGeneric.__xgcd_univariate_polynomial_fixed`
for the precise meaning of the precision ``prec``.)
AUTHORS:
- Julian Rueth (2012-10-22): initial version
EXAMPLES::
sage: R.<t> = ZpFM(3,20)[]
sage: (t + 1).xgcd( (t - 1) * (t + 1) )
((1 + O(3^20))*t + (1 + O(3^20)), 20, (1 + O(3^20)), 0)
sage: (t^3).xgcd( t^5 )
((1 + O(3^20))*t^3, 20, (1 + O(3^20)), 0)
Also works over extensions::
sage: K = ZpFM(3,20)
sage: R.<a> = K[]
sage: L.<a> = K.extension( a^2 - 3 ) # Eisenstein extension
sage: R.<t> = L[]
sage: a0,a1,a2 = 12345678+a,90123456-a,78901234*a
sage: f = (t - a0) * (t - a1)^2 * (t - a2)^3
sage: g,prec,u,v = f.xgcd(f.derivative())
sage: h = (t - a1) * (t - a2)^2 # the correct result
sage: g.degree() == h.degree()
True
sage: h *= g.leading_coefficient()
sage: all([(c1-c2).is_zero(prec) for c1,c2 in zip(list(g),list(h))]) # g and h are equal mod a^prec
True
sage: all([(c1-c2).is_zero(prec) for c1,c2 in zip(list(g),list(u*f+v*f.derivative()))]) # the equation g = u*f + v*f.derivative() is satisfied mod a^prec
True
sage: R.<a> = K[]
sage: L.<a> = K.extension( a^2 - 2 ) # unramified extension
sage: R.<t> = L[]
sage: a0,a1,a2 = 12345678+a,90123456-a,78901234*a
sage: f = (t - a0) * (t - a1)^2 * (t - a2)^3
sage: g,prec,u,v = f.xgcd(f.derivative())
sage: h = (t - a1) * (t - a2)^2 # the correct result
sage: g.degree() == h.degree()
True
sage: h *= g.leading_coefficient()
sage: all([(c1-c2).is_zero(prec) for c1,c2 in zip(list(g),list(h))]) # g and h are equal mod a^prec
True
sage: all([(c1-c2).is_zero(prec) for c1,c2 in zip(list(g),list(u*f+v*f.derivative()))]) # the equation g = u*f + v*f.derivative() is satisfied mod a^prec
True
TESTS:
Check that the examples from :trac:`13439` work::
sage: R.<t> = ZpFM(3,3)[]
sage: f = 3*t + 7
sage: g = 5*t + 9
sage: f.xgcd(f*g)
((3 + O(3^3))*t + (1 + 2*3 + O(3^3)), 2, (1 + O(3^3)), 0)
sage: R.<t> = ZpFM(3,20)[]
sage: f = 729*490473657*t + 257392844
sage: g = 225227399*t - 59049*8669753175
sage: h,_,_,_ = f.xgcd(f*g)
sage: h.degree() == f.degree()
True
"""
return self._xgcd_univariate_polynomial_fixed(f, g)

class pAdicCappedAbsoluteRingGeneric(pAdicRingGeneric, CappedAbsoluteGeneric):
pass
class pAdicCappedRelativeRingGeneric(pAdicRingGeneric, CappedRelativeRingGeneric):
Expand Down
Loading

0 comments on commit c4b3743

Please sign in to comment.