Difference polynomial rings
A difference polynomial ring over the commutative ring $R$ is an action polynomial ring $A$ whose action maps are (injective) endomorphisms of $A$. We also call them shift operators.
Construction
We provide the following methods to construct shift operators on the coefficient ring R. Using these is necessary, if one wants to use difference polynomial rings with nontrivial shift operators.
action_shift — Method
action_shift(R::Ring)Construct the trivial shift, i.e. the identity map on the ring R.
This function is part of the experimental code in Oscar. Please read here for more details.
action_shift — Method
action_shift(m::Map{D, D}) where {D <: Ring}Wrap the map m into an ActionShift. This does not check whether m is actually a shift operator.
This function is part of the experimental code in Oscar. Please read here for more details.
We provide the following methods to create difference polynomial rings where all shift operators are trivial, i.e. the identity map on the coefficient ring.
difference_polynomial_ring — Method
difference_polynomial_ring(R::Ring, action_indeterminates::Union{Vector{Symbol}, Int}, n_action_maps::Int) -> Tuple{DifferencePolyRing, Vector{DifferencePolyRingElem}}Construct the difference polynomial ring over the coefficient ring R with the given action indeterminates that is equipped with n_action_maps-many trivial shift operators, i.e. they are the identity map on R.
- If
action_indeterminatesis a vector of symbols, those names are used. - If it is an integer
m, the symbolsu1, …, umare generated automatically.
In both cases, the jet variables that are initially available are those with jet [0,…,0], one for each action indeterminate.
This method returns a tuple (dpr, gens) where dpr is the resulting difference polynomial ring and gens is the vector of initial jet variables.
This constructor also accepts all keyword arguments of set_ranking! to control the ranking.
Examples
julia> R, variablesR = difference_polynomial_ring(QQ, 3, 4)
(Difference polynomial ring in 3 action indeterminates over QQ, DifferencePolyRingElem{QQFieldElem}[u1[0,0,0,0], u2[0,0,0,0], u3[0,0,0,0]])
julia> R
Difference polynomial ring in 3 action indeterminates u1, u2, u3
with 4 commuting endomorphisms
over rational field
julia> variablesR
3-element Vector{DifferencePolyRingElem{QQFieldElem}}:
u1[0,0,0,0]
u2[0,0,0,0]
u3[0,0,0,0]
julia> S, variablesS = difference_polynomial_ring(QQ, [:a, :b, :c], 4)
(Difference polynomial ring in 3 action indeterminates over QQ, DifferencePolyRingElem{QQFieldElem}[a[0,0,0,0], b[0,0,0,0], c[0,0,0,0]])
julia> S
Difference polynomial ring in 3 action indeterminates a, b, c
with 4 commuting endomorphisms
over rational field
julia> variablesS
3-element Vector{DifferencePolyRingElem{QQFieldElem}}:
a[0,0,0,0]
b[0,0,0,0]
c[0,0,0,0]This function is part of the experimental code in Oscar. Please read here for more details.
difference_polynomial_ring — Method
difference_polynomial_ring(R::Ring, x::Symbol, n_action_maps::Int) -> Tuple{DifferencePolyRing, DifferencePolyRingElem}This constructor behaves exactly like difference_polynomial_ring but only allows for one action indeterminate x instead of a vector of these. Consequently, this method returns the tuple (dpr, x[0,…,0]) where dpr is the resulting difference polynomial ring.
Examples
This constructor is preferred when one only wants to have one action indeterminate:
julia> R, x = difference_polynomial_ring(ZZ, :x, 2)
(Difference polynomial ring in 1 action indeterminates over ZZ, x[0,0])
julia> x
x[0,0]If we instead construct this ring by passing the single action indeterminate as a vector, the variable x does not behave as intended:
julia> R, x = difference_polynomial_ring(ZZ, [:x], 2)
(Difference polynomial ring in 1 action indeterminates over ZZ, DifferencePolyRingElem{ZZRingElem}[x[0,0]])
julia> x
1-element Vector{DifferencePolyRingElem{ZZRingElem}}:
x[0,0]This function is part of the experimental code in Oscar. Please read here for more details.
We provide the following constructors to create difference polynomial rings with arbitrary commuting shift operators. Note that commutativity is not actually checked and that ensuring it is left to the user.
difference_polynomial_ring — Method
difference_polynomial_ring(R::Ring, action_indeterminates::Union{Vector{Symbol}, Int}, action_maps::Vector{<:ActionShift}; kwargs...) -> Tuple{DifferencePolyRing, Vector{DifferencePolyRingElem}}This constructor behaves exactly like and comes with the same features as difference_polynomial_ring but additionally allows the user to pass a custom vector of shift operators action_maps. In particular, this constructor allows for nontrivial shift operators.
Examples
julia> S, x = polynomial_ring(QQ, :x);
julia> nontrivial_shifts = action_shift.([hom(S, S, x + 1), hom(S, S, x + 2)])
2-element Vector{Oscar.NontrivialActionShift{QQPolyRing}}:
Shift operator on S
Shift operator on S
julia> dpr, (u, v) = difference_polynomial_ring(S, [:u, :v], nontrivial_shifts)
(Difference polynomial ring in 2 action indeterminates over S, DifferencePolyRingElem{QQPolyRingElem}[u[0,0], v[0,0]])This function is part of the experimental code in Oscar. Please read here for more details.
difference_polynomial_ring — Method
difference_polynomial_ring(R::Ring, action_indeterminate::Symbol, action_maps::Vector{<:ActionShift}; kwargs...) -> Tuple{DifferencePolyRing, DifferencePolyRingElem}This constructor behaves exactly like difference_polynomial_ring in that only a single action indeterminate is passed as a symbol but additionally allows the user to pass a custom vector of shift operators action_maps. In particular, this constructor allows for nontrivial shift operators.
This function is part of the experimental code in Oscar. Please read here for more details.
Applying shift operators
You can use the following methods to apply the shift operators of a difference polynomial ring to its elements:
apply_action — Method
apply_action(p::DifferencePolyRingElem, i::Int)Apply the i-th shift operator to the difference polynomial p.
Examples
julia> dpr, (a,b,c) = difference_polynomial_ring(ZZ, [:a, :b, :c], 2); f = -2*a*b + 3*a*b^2;
julia> apply_action(3*a, 1)
3*a[1,0]
julia> apply_action(3*a, 2)
3*a[0,1]
julia> apply_action(f, 1)
(3*b[1,0]^2 - 2*b[1,0])*a[1,0]
julia> apply_action(f, 2)
(3*b[0,1]^2 - 2*b[0,1])*a[0,1]This function is part of the experimental code in Oscar. Please read here for more details.
apply_action — Method
apply_action(p::DifferencePolyRingElem, d::Vector{Int})Successively apply the i-th shift operator d[i]-times to the difference polynomial p, where $i = 1, \ldots, \mathrm{length}(d)$.
This function is part of the experimental code in Oscar. Please read here for more details.