AbstractAlgebra.jl icon indicating copy to clipboard operation
AbstractAlgebra.jl copied to clipboard

Mapping universal polynomials to multivariate polynomials and back

Open SoongNoonien opened this issue 11 months ago • 3 comments

Hi! Sometimes it seems to be necessary to work with the underlying multivariate polynomials of universal polynomials for performance reasons. Is there a way to switch back and forth between multivariate and universal polynomials? Currently, I think my only option is to directly access the p field of the universal polynomial struct directly. But there seems to be no option to map this back to the universal polynomial ring.

SoongNoonien avatar Jan 23 '25 11:01 SoongNoonien

Ok, apparently data(f) works as well for an universal polynomial f.

SoongNoonien avatar Jan 26 '25 11:01 SoongNoonien

Currently this works:

julia> S = universal_polynomial_ring(QQ)
Universal Polynomial Ring over Rational field

julia> x = gen(S, :x)
x

julia> y, z = gens(S, [:y, :z])
(y, z)

julia> f = y^3 + z^2
y^3 + z^2

julia> mf = data(f)
y^3 + z^2

julia> typeof(mf)
QQMPolyRingElem

julia> f2 = Nemo.AbstractAlgebra.Generic.UnivPoly(mf, S)
y^3 + z^2

julia> typeof(f2)
AbstractAlgebra.Generic.UnivPoly{QQFieldElem}

julia> f2 == f
true

We could consider allowing S(mf) as a shorthand -- not for arbitrary multivariate polynomials of course, but at least for the case that mf has as parent S.mpoly_ring, i.e., the "current" multivariate ring. That means in the example above, S(x) would not work, as it still has the old initial mpolyring as parent, but such is life. But I would reject all other mpolys because this is not meant to be a universal "coercion" of mpolys into univpolys (one could offer that, but then it should map based on variable names, which the current code does not).

But maybe for now you can just work with the code snippets above...

fingolfin avatar Jan 31 '25 09:01 fingolfin

Hm, S(mf) does not feel right, since this might become illegal if S is changed, so does not really fit in our under-specified notion of "coercion". (For example, hom(parent(data(f)), Sf) will work for a few minutes and then suddenly start crashing.)

What about an unsafe_convert(S, mf) (or something like that)? I would not make it part of the user-facing API, but this should not be a problem, since data is also not part of that API.

thofma avatar Mar 01 '25 11:03 thofma