Univariate skew polynomials¶
This module provides the
SkewPolynomial.
In the class hierarchy in Sage, the locution Skew Polynomial is used
for a Ore polynomial without twisting derivation.
Warning
The current semantics of
__call__()
are experimental, so a warning is thrown when a skew polynomial is evaluated
for the first time in a session. See the method documentation for details.
AUTHORS:
Xavier Caruso (2012-06-29): initial version
Arpit Merchant (2016-08-04): improved docstrings, fixed doctests and refactored classes and methods
Johan Rosenkilde (2016-08-03): changes for bug fixes, docstring and doctest errors
- class sage.rings.polynomial.skew_polynomial_element.SkewPolynomial_generic_dense[source]¶
Bases:
OrePolynomial_generic_denseGeneric implementation of dense skew polynomial supporting any valid base ring and twisting morphism.
- conjugate(n)[source]¶
Return
selfconjugated by \(x^n\), where \(x\) is the variable ofself.The conjugate is obtained from
selfby applying the \(n\)-th iterate of the twisting morphism to each of its coefficients.INPUT:
n– integer; the power of conjugation
EXAMPLES:
sage: R.<t> = QQ[] sage: K = R.fraction_field() sage: sigma = K.hom([1 + 1/t]) sage: S.<x> = K['x',sigma] sage: a = t*x^3 + (t^2 + 1)*x^2 + 2*t sage: b = a.conjugate(2); b ((2*t + 1)/(t + 1))*x^3 + ((5*t^2 + 6*t + 2)/(t^2 + 2*t + 1))*x^2 + (4*t + 2)/(t + 1) sage: x^2*a == b*x^2 True
>>> from sage.all import * >>> R = QQ['t']; (t,) = R._first_ngens(1) >>> K = R.fraction_field() >>> sigma = K.hom([Integer(1) + Integer(1)/t]) >>> S = K['x',sigma]; (x,) = S._first_ngens(1) >>> a = t*x**Integer(3) + (t**Integer(2) + Integer(1))*x**Integer(2) + Integer(2)*t >>> b = a.conjugate(Integer(2)); b ((2*t + 1)/(t + 1))*x^3 + ((5*t^2 + 6*t + 2)/(t^2 + 2*t + 1))*x^2 + (4*t + 2)/(t + 1) >>> x**Integer(2)*a == b*x**Integer(2) True
In principle, negative values for \(n\) are allowed, but Sage needs to be able to invert the twisting morphism:
sage: b = a.conjugate(-1) Traceback (most recent call last): ... NotImplementedError: inverse not implemented for morphisms of Fraction Field of Univariate Polynomial Ring in t over Rational Field
>>> from sage.all import * >>> b = a.conjugate(-Integer(1)) Traceback (most recent call last): ... NotImplementedError: inverse not implemented for morphisms of Fraction Field of Univariate Polynomial Ring in t over Rational Field
Here is a working example:
sage: # needs sage.rings.finite_rings sage: k.<t> = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: T.<y> = k['y',Frob] sage: u = T.random_element() sage: v = u.conjugate(-1) sage: u*y == y*v True
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> T = k['y',Frob]; (y,) = T._first_ngens(1) >>> u = T.random_element() >>> v = u.conjugate(-Integer(1)) >>> u*y == y*v True
- left_power_mod(exp, modulus)[source]¶
Return the remainder of
self**expin the left euclidean division bymodulus.INPUT:
exp– an Integermodulus– a skew polynomial in the same ring asself
OUTPUT:
Remainder of
self**expin the left euclidean division bymodulus.REMARK:
The quotient of the underlying skew polynomial ring by the principal ideal generated by
modulusis in general not a ring.As a consequence, Sage first computes exactly
self**expand then reduce it modulomodulus.EXAMPLES:
sage: # needs sage.rings.finite_rings sage: k.<t> = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S.<x> = k['x',Frob] sage: a = x + t sage: modulus = x^3 + t*x^2 + (t+3)*x - 2 sage: a.left_power_mod(100,modulus) (4*t^2 + t + 1)*x^2 + (t^2 + 4*t + 1)*x + 3*t^2 + 3*t
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x',Frob]; (x,) = S._first_ngens(1) >>> a = x + t >>> modulus = x**Integer(3) + t*x**Integer(2) + (t+Integer(3))*x - Integer(2) >>> a.left_power_mod(Integer(100),modulus) (4*t^2 + t + 1)*x^2 + (t^2 + 4*t + 1)*x + 3*t^2 + 3*t
- multi_point_evaluation(eval_pts)[source]¶
Evaluate
selfat list of evaluation points.INPUT:
eval_pts– list of points at whichselfis to be evaluated
OUTPUT: list of values of
selfat theeval_ptsTodo
This method currently trivially calls the evaluation function repeatedly. If fast skew polynomial multiplication is available, an asymptotically faster method is possible using standard divide and conquer techniques and
minimal_vanishing_polynomial().EXAMPLES:
sage: # needs sage.rings.finite_rings sage: k.<t> = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S.<x> = k['x',Frob] sage: a = x + t sage: eval_pts = [1, t, t^2] sage: c = a.multi_point_evaluation(eval_pts); c [t + 1, 3*t^2 + 4*t + 4, 4*t] sage: c == [ a(e) for e in eval_pts ] True
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x',Frob]; (x,) = S._first_ngens(1) >>> a = x + t >>> eval_pts = [Integer(1), t, t**Integer(2)] >>> c = a.multi_point_evaluation(eval_pts); c [t + 1, 3*t^2 + 4*t + 4, 4*t] >>> c == [ a(e) for e in eval_pts ] True
- operator_eval(eval_pt)[source]¶
Evaluate
selfateval_ptby the operator evaluation method.INPUT:
eval_pt– element of the base ring ofself
OUTPUT: the value of the polynomial at the point specified by the argument
EXAMPLES:
sage: # needs sage.rings.finite_rings sage: k.<t> = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: T.<x> = k['x',Frob] sage: a = 3*t^2*x^2 + (t + 1)*x + 2 sage: a(t) #indirect test 2*t^2 + 2*t + 3 sage: a.operator_eval(t) 2*t^2 + 2*t + 3
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> T = k['x',Frob]; (x,) = T._first_ngens(1) >>> a = Integer(3)*t**Integer(2)*x**Integer(2) + (t + Integer(1))*x + Integer(2) >>> a(t) #indirect test 2*t^2 + 2*t + 3 >>> a.operator_eval(t) 2*t^2 + 2*t + 3
Evaluation points outside the base ring is usually not possible due to the twisting morphism:
sage: R.<t> = QQ[] sage: sigma = R.hom([t+1]) sage: S.<x> = R['x',sigma] sage: a = t*x + 1 sage: a.operator_eval(1/t) Traceback (most recent call last): ... TypeError: 1/t fails to convert into the map's domain Univariate Polynomial Ring in t over Rational Field, but a `pushforward` method is not properly implemented
>>> from sage.all import * >>> R = QQ['t']; (t,) = R._first_ngens(1) >>> sigma = R.hom([t+Integer(1)]) >>> S = R['x',sigma]; (x,) = S._first_ngens(1) >>> a = t*x + Integer(1) >>> a.operator_eval(Integer(1)/t) Traceback (most recent call last): ... TypeError: 1/t fails to convert into the map's domain Univariate Polynomial Ring in t over Rational Field, but a `pushforward` method is not properly implemented
- right_power_mod(exp, modulus)[source]¶
Return the remainder of
self**expin the right euclidean division bymodulus.INPUT:
exp– integermodulus– a skew polynomial in the same ring asself
OUTPUT:
Remainder of
self**expin the right euclidean division bymodulus.REMARK:
The quotient of the underlying skew polynomial ring by the principal ideal generated by
modulusis in general not a ring.As a consequence, Sage first computes exactly
self**expand then reduce it modulomodulus.EXAMPLES:
sage: # needs sage.rings.finite_rings sage: k.<t> = GF(5^3) sage: Frob = k.frobenius_endomorphism() sage: S.<x> = k['x',Frob] sage: a = x + t sage: b = a^5 # indirect doctest sage: b x^5 + (2*t^2 + 4)*x^4 + (t^2 + 2)*x^3 + 2*x^2 + (4*t^2 + 2)*x + 2*t^2 + 4*t + 4 sage: b == a * a * a * a * a True sage: modulus = x^3 + t*x^2 + (t+3)*x - 2 sage: br = a.right_power_mod(5, modulus); br (t + 1)*x^2 + (2*t^2 + t + 1)*x + 2*t^2 + 4*t + 2 sage: br == b % modulus True sage: a.right_power_mod(100, modulus) (2*t^2 + 3)*x^2 + (t^2 + 4*t + 2)*x + t^2 + 2*t + 1
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> k = GF(Integer(5)**Integer(3), names=('t',)); (t,) = k._first_ngens(1) >>> Frob = k.frobenius_endomorphism() >>> S = k['x',Frob]; (x,) = S._first_ngens(1) >>> a = x + t >>> b = a**Integer(5) # indirect doctest >>> b x^5 + (2*t^2 + 4)*x^4 + (t^2 + 2)*x^3 + 2*x^2 + (4*t^2 + 2)*x + 2*t^2 + 4*t + 4 >>> b == a * a * a * a * a True >>> modulus = x**Integer(3) + t*x**Integer(2) + (t+Integer(3))*x - Integer(2) >>> br = a.right_power_mod(Integer(5), modulus); br (t + 1)*x^2 + (2*t^2 + t + 1)*x + 2*t^2 + 4*t + 2 >>> br == b % modulus True >>> a.right_power_mod(Integer(100), modulus) (2*t^2 + 3)*x^2 + (t^2 + 4*t + 2)*x + t^2 + 2*t + 1
Negative exponents are supported:
sage: # needs sage.rings.finite_rings sage: a^(-5) (x^5 + (2*t^2 + 4)*x^4 + (t^2 + 2)*x^3 + 2*x^2 + (4*t^2 + 2)*x + 2*t^2 + 4*t + 4)^(-1) sage: b * a^(-5) 1
However, they cannot be combined with modulus:
sage: a.right_power_mod(-10, modulus) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: modulus cannot be combined with negative exponent
>>> from sage.all import * >>> a.right_power_mod(-Integer(10), modulus) # needs sage.rings.finite_rings Traceback (most recent call last): ... ValueError: modulus cannot be combined with negative exponent