Multivariate Puiseux polynomials
A Puiseux polynomial over a field $K$ is a finite sum of terms $c x_1^{e_1} \cdots x_n^{e_n}$ with $c \in K$ and rational exponents $e_i$, which may be negative. Puiseux polynomials form a ring containing the Laurent polynomial ring $K[x_1^{\pm 1}, \dots, x_n^{\pm 1}]$.
Generic Puiseux polynomial types
AbstractAlgebra.jl provides a generic implementation of multivariate Puiseux polynomials in the file src/generic/PuiseuxMPoly.jl, built on top of the generic multivariate Laurent polynomials.
The element type is PuiseuxMPolyRingElem{T} <: RingElem and the parent type is PuiseuxMPolyRing{T} <: Ring, parameterized on the coefficient type T.
A Puiseux polynomial $f$ is stored as a pair $(g, d)$ of a Laurent polynomial $g$ and a positive integer $d$, its scale, with
\[f(x_1, \dots, x_n) = g(x_1^{1/d}, \dots, x_n^{1/d}).\]
The representation is normalized: $d$ is coprime to the greatest common divisor of all exponents of $g$, so $d$ is the least common denominator of the exponents of $f$. Every Puiseux polynomial has a unique normalized representation, which makes comparing elements cheap. Arithmetic rescales both operands to a common scale, operates on the underlying Laurent polynomials and normalizes the result.
Constructor
AbstractAlgebra.puiseux_polynomial_ring — Method
puiseux_polynomial_ring(K::Field, variableName::Vector{String})Return a tuple (R, x) consisting of the ring R of Puiseux polynomials over K in the given variables and the vector x of its generators.
The elements of R are finite sums of terms $c x_1^{e_1} \cdots x_n^{e_n}$ with $c \in K$ and rational, possibly negative, exponents $e_i$.
Examples
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> R
Puiseux polynomial ring in 2 variables x, y
over rationals
julia> f = x^(1//2) + 2*y^(-1//3)
x^(1//2) + 2*y^(-1//3)
julia> f^2
x + 4*x^(1//2)*y^(-1//3) + 4*y^(-2//3)Elements can be created from the generators by the usual arithmetic operations, and constants can be coerced into the ring by calling it:
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> R(3)
3
julia> 3*x^(1//2)*y^(-2//3) - 1
3*x^(1//2)*y^(-2//3) - 1Basic functionality
Puiseux polynomial rings implement the Ring interface. In addition, the following functions are available.
base_ring(R::PuiseuxMPolyRing)
coefficient_ring(R::PuiseuxMPolyRing)
symbols(R::PuiseuxMPolyRing)
number_of_variables(R::PuiseuxMPolyRing)
gens(R::PuiseuxMPolyRing)
is_univariate(R::PuiseuxMPolyRing)Here base_ring returns the underlying Laurent polynomial ring, and coefficient_ring returns the field $K$.
length(f::PuiseuxMPolyRingElem)
coefficients(f::PuiseuxMPolyRingElem)
monomials(f::PuiseuxMPolyRingElem)
exponent_vectors(f::PuiseuxMPolyRingElem)
leading_coefficient(f::PuiseuxMPolyRingElem)
is_gen(f::PuiseuxMPolyRingElem)
is_monomial(f::PuiseuxMPolyRingElem)
is_term(f::PuiseuxMPolyRingElem)
is_unit(f::PuiseuxMPolyRingElem)
canonical_unit(f::PuiseuxMPolyRingElem)The exponent vectors have entries of type Rational{Int}. The units are the nonzero terms, i.e. the nonzero constant multiples of monomials. As for Laurent polynomials, the canonical unit of f is the canonical unit of its leading coefficient times $x_1^{m_1} \cdots x_n^{m_n}$, where $m_i$ is the smallest exponent of $x_i$ in f.
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> f = x^(1//2) + 2*y^(1//3);
julia> collect(coefficients(f))
2-element Vector{Rational{BigInt}}:
1
2
julia> exponent_vectors(f)
2-element Vector{Vector{Rational{Int64}}}:
[1//2, 0]
[0, 1//3]
julia> is_unit(f), is_unit(2*x^(1//2))
(false, true)
julia> canonical_unit(3*x*y + 2*x^(1//2))
3*x^(1//2)The normalized representation can be inspected with the following functions.
AbstractAlgebra.Generic.poly — Method
poly(f::PuiseuxMPolyRingElem)Return the Laurent polynomial $g$ in base_ring(parent(f)) with $f(x_1, \dots, x_n) = g(x_1^{1/d}, \dots, x_n^{1/d})$, where $d$ is scale(f).
Examples
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> poly(x^(1//2) + 2*y^(1//3))
x^3 + 2*y^2AbstractAlgebra.Generic.scale — Method
scale(f::PuiseuxMPolyRingElem)Return the least common denominator $d > 0$ of the exponents of f, so that f is the Laurent polynomial poly(f) evaluated at $x_1^{1/d}, \dots, x_n^{1/d}$.
Examples
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> scale(x^(1//2) + 2*y^(1//3))
6Powering
^(f::PuiseuxMPolyRingElem, n::Integer)
^(f::PuiseuxMPolyRingElem, q::Rational)Any Puiseux polynomial can be raised to a nonnegative integer power. A negative integer power requires f to be a monomial times a constant, and a non-integer rational power requires f to be a monomial with coefficient one.
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> (x^(1//2) + y)^2
x + 2*x^(1//2)*y + y^2
julia> (x*y^2)^(1//3)
x^(1//3)*y^(2//3)
julia> (x + y)^(1//2)
ERROR: ArgumentError: only monomials can be exponentiated to non-integer powers
[...]Divisibility
divexact(f::PuiseuxMPolyRingElem, g::PuiseuxMPolyRingElem; check::Bool = true)
divexact(f::PuiseuxMPolyRingElem, a::RingElement; check::Bool = true)
divides(f::PuiseuxMPolyRingElem, g::PuiseuxMPolyRingElem)divexact returns the quotient of f by a nonzero Puiseux polynomial or constant g, provided the division is exact. divides(f, g) returns a tuple (flag, q) where flag is true if $f = qg$ for some Puiseux polynomial $q$; otherwise q is zero.
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> f = x^(1//2) + 2*y^(1//3);
julia> divexact(f^2, f)
x^(1//2) + 2*y^(1//3)
julia> divexact(f, x^(1//6))
x^(1//3) + 2*x^(-1//6)*y^(1//3)
julia> divides(f^2, f)
(true, x^(1//2) + 2*y^(1//3))
julia> divides(x, f)
(false, 0)Changing the coefficient ring
change_base_ring(K::Ring, f::PuiseuxMPolyRingElem; cached::Bool = true, parent::PuiseuxMPolyRing)
map_coefficients(g, f::PuiseuxMPolyRingElem; cached::Bool = true, parent::PuiseuxMPolyRing)Return the Puiseux polynomial obtained from f by coercing each coefficient into K, respectively by applying g to each coefficient. Unless parent is given, the result lies in the Puiseux polynomial ring over K, respectively over the parent of the images of g, in the same variables as parent(f).
julia> R, (x, y) = puiseux_polynomial_ring(QQ, ["x", "y"]);
julia> map_coefficients(c -> 2*c, x^(1//2) + 3*y^(1//3))
2*x^(1//2) + 6*y^(1//3)Valuation
AbstractAlgebra.valuation — Method
valuation(f::PuiseuxMPolyRingElem)Return the smallest exponent occurring in the univariate Puiseux polynomial f, or PosInf() if f is zero.
Examples
julia> R, (t,) = puiseux_polynomial_ring(QQ, ["t"]);
julia> valuation(t^(-2//3) + t^(1//2))
-2//3