diff --git a/docs/src/mpolynomial.md b/docs/src/mpolynomial.md index d1b44e3286..064ed06dd2 100644 --- a/docs/src/mpolynomial.md +++ b/docs/src/mpolynomial.md @@ -63,6 +63,13 @@ provided when the number of generators is greater than `1`: given a base ring R[:x, :y, ...] ``` +In addition to that, it is also possible to construct univariate polynomial rings +over other univariate polynomial rings in a similar fashion: + +```julia +R[:x][:y]... +``` + Here are some examples of creating multivariate polynomial rings and making use of the resulting parent objects to coerce various elements into the polynomial ring. @@ -101,6 +108,9 @@ julia> R, x = polynomial_ring(ZZ, 10); R Multivariate polynomial ring in 10 variables x1, x2, x3, x4, ..., x10 over integers +julia> T, (z, t) = QQ[:z][:t] +(Univariate polynomial ring in t over univariate polynomial ring, AbstractAlgebra.Generic.Poly{AbstractAlgebra.Generic.Poly{Rational{BigInt}}}[z, t]) + ``` ## Polynomial constructors diff --git a/src/Poly.jl b/src/Poly.jl index d7e62e8cf1..f8279b3b5b 100644 --- a/src/Poly.jl +++ b/src/Poly.jl @@ -3578,14 +3578,36 @@ end ############################################################################### # -# Polynomial Ring S, x = R[:x] syntax +# Syntactic sugar for Polynomial ring constructors # ############################################################################### +# syntax: S, x = R[:x] getindex(R::NCRing, s::VarName) = polynomial_ring(R, s) -# `R[:x, :y]` returns `S, [x, y]` instead of `S, x, y` -getindex(R::NCRing, s::VarName, ss::VarName...) = - polynomial_ring(R, [Symbol(x) for x in (s, ss...)]) -# syntax: Rxy, y = R[:x][:y] -getindex(R::Union{Tuple{PolyRing, PolyRingElem}, Tuple{NCPolyRing, NCPolyRingElem}}, s::VarName) = polynomial_ring(R[1], s) +# syntax: S, (x,y) = R[:x,:y] +getindex(R::Ring, s::VarName, t::VarName, ss::VarName...) = polynomial_ring(R, [Symbol(x) for x in (s, t, ss...)]) + +# syntax: S, (x,y) = R[:x][:y] +function getindex((R,x)::Union{Tuple{PolyRing, PolyRingElem}, Tuple{NCPolyRing, NCPolyRingElem}}, s::VarName) + S, y = polynomial_ring(R, s) + return S, elem_type(S)[S(x),y] +end + +# syntax: S, (x,y,z) = R[:x][:y][:z] and S, (x,y,z) = R[:x,:y][:z] +function getindex((R,xs)::Union{Tuple{PolyRing, Vector{<:PolyRingElem}}, Tuple{NCPolyRing, Vector{<:NCPolyRingElem}}, Tuple{MPolyRing, Vector{<:MPolyRingElem}}}, s::VarName) + S, y = polynomial_ring(R, s) + return S, elem_type(S)[S.(xs)...,y] +end + +# syntax: S, (x,y,z) = R[:x][:y,:z] +function getindex((R,x)::Tuple{PolyRing, PolyRingElem}, s::VarName, t::VarName, ss::VarName...) + S, ys = polynomial_ring(R, [Symbol(y) for y in (s, t, ss...)]) + return S, elem_type(S)[S(x),ys...] +end + +# syntax: S, (x,y,z,w) = R[:x][:y][:z,:w] and S, (x,y,z,w) = R[:x,:y][:z,:w] +function getindex((R,xs)::Union{Tuple{PolyRing, Vector{<:PolyRingElem}}, Tuple{MPolyRing, Vector{<:MPolyRingElem}}}, s::VarName, t::VarName, ss::VarName...) + S, ys = polynomial_ring(R, [Symbol(y) for y in (s, t, ss...)]) + return S, elem_type(S)[S.(xs)...,ys...] +end diff --git a/test/generic/MPoly-test.jl b/test/generic/MPoly-test.jl index 8e7d36cd91..baff75987d 100644 --- a/test/generic/MPoly-test.jl +++ b/test/generic/MPoly-test.jl @@ -93,7 +93,7 @@ @test !(y in keys(Dict(x => 1))) end - R1, (x, y) = QQ["x", "y"] + R1, (x, y) = polynomial_ring(QQ, ["x", "y"]) B = MPolyBuildCtx(R1) @@ -187,6 +187,40 @@ ) @test_throws UndefVarError let local_name = 3 @macroexpand @polynomial_ring(QQ, :x => 1:local_name) end + + @testset "Generic.MPoly.constructors.getindex" begin + S, vs = ZZ[:x][:y,:z] + @test S isa Generic.MPolyRing{Generic.Poly{BigInt}} + @test length(vs) == 3 + for v in vs + @test v isa Generic.MPoly{Generic.Poly{BigInt}} + @test parent(v) == S + end + + S, vs = ZZ[:x,:y][:z] + @test S isa Generic.PolyRing{Generic.MPoly{BigInt}} + @test length(vs) == 3 + for v in vs + @test v isa Generic.Poly{Generic.MPoly{BigInt}} + @test parent(v) == S + end + + S, vs = ZZ[:x,:y][:z,:w] + @test S isa Generic.MPolyRing{Generic.MPoly{BigInt}} + @test length(vs) == 4 + for v in vs + @test v isa Generic.MPoly{Generic.MPoly{BigInt}} + @test parent(v) == S + end + + S, vs = ZZ[:x][:y][:z,:w] + @test length(vs) == 4 + @test S isa Generic.MPolyRing{Generic.Poly{Generic.Poly{BigInt}}} + for v in vs + @test v isa Generic.MPoly{Generic.Poly{Generic.Poly{BigInt}}} + @test parent(v) == S + end + end end # these variables need to be in global scope diff --git a/test/generic/NCPoly-test.jl b/test/generic/NCPoly-test.jl index ce75ad069b..b6a46fb8b0 100644 --- a/test/generic/NCPoly-test.jl +++ b/test/generic/NCPoly-test.jl @@ -23,6 +23,10 @@ @test elem_type(S3) == Generic.NCPoly{Generic.NCPoly{Generic.MatRingElem{BigInt}}} @test typeof(S3) == Generic.NCPolyRing{Generic.NCPoly{Generic.MatRingElem{BigInt}}} + S4, _ = R["x"]["y"]["z"] + @test elem_type(S4) == Generic.NCPoly{Generic.NCPoly{Generic.NCPoly{Generic.MatRingElem{BigInt}}}} + @test typeof(S4) == Generic.NCPolyRing{Generic.NCPoly{Generic.NCPoly{Generic.MatRingElem{BigInt}}}} + S, y = S1 T, z = polynomial_ring(S, "z") diff --git a/test/generic/Poly-test.jl b/test/generic/Poly-test.jl index 774b791252..3bfc0deeae 100644 --- a/test/generic/Poly-test.jl +++ b/test/generic/Poly-test.jl @@ -29,13 +29,15 @@ end @test isa(S1, Generic.PolyRing) R, x = ZZ["x"] - S1 = R["y"] - S2 = ZZ["x"]["y"] + S1, y = R["y"] + @test isa(y, PolyRingElem) + S2, (x,y) = ZZ["x"]["y"] + @test isa(y, PolyRingElem) @test polynomial_ring(R, "y", cached = true)[1] === polynomial_ring(R, "y", cached = true)[1] @test polynomial_ring(R, "y", cached = true)[1] !== polynomial_ring(R, "y", cached = false)[1] - for (S, y) in (S1, S2) + for S in (S1, S2) @test base_ring(S) === R @test coefficient_ring(S) === R @test coefficient_ring_type(S) === typeof(R) @@ -46,8 +48,6 @@ end @test R isa AbstractAlgebra.Ring @test S isa Generic.PolyRing - - @test isa(y, PolyRingElem) end R, x = polynomial_ring(ZZ, "x") @@ -121,6 +121,24 @@ end @test Rx1 == Rx6 @test Rx1 == (Rx7, x) end + + @testset "Generic.Poly.constructors.getindex" begin + S, vs = ZZ[:x][:y] + @test S isa Generic.PolyRing{Generic.Poly{BigInt}} + @test length(vs) == 2 + for v in vs + @test v isa Generic.Poly{Generic.Poly{BigInt}} + @test parent(v) == S + end + + S, vs = ZZ[:x][:y][:z] + @test S isa Generic.PolyRing{Generic.Poly{Generic.Poly{BigInt}}} + @test length(vs) == 3 + for v in vs + @test v isa Generic.Poly{Generic.Poly{Generic.Poly{BigInt}}} + @test parent(v) == S + end + end end @testset "Generic.Poly.iterators" begin