JuliaHomotopyContinuation / HomotopyContinuation.jl

A Julia package for solving systems of polynomials via homotopy continuation.
https://www.JuliaHomotopyContinuation.org
MIT License
178 stars 30 forks source link

Converting from Nemo.fmpq_mpoly to HomotopyContinuation.Expression #520

Open iliailmer opened 1 year ago

iliailmer commented 1 year ago

I have an array of polynomials which are obtained through Nemo CAS. Is there a way to convert them into a HomotopyContinuation.Expression type so that I can find roots of the polynomial system? I've tried a few different things but no luck so far.

Thanks.

PBrdng commented 1 year ago

I don't think there is a direct way so far. Sorry!

saschatimme commented 1 year ago

There seems to be a way to extract the exponent vectors and coefficient of the polynomial (see https://nemocas.github.io/AbstractAlgebra.jl/stable/mpolynomial/#Basic-manipulation).

If you have the exponents and the coefficients in Matrix and vector form you can rebuild the polynomial. Here is an example.

julia> @var x y z
(x, y, z)

julia> E = [1 2 3; 0 2 1; 3 5 6; 1 0 2]
4×3 Matrix{Int64}:
 1  2  3
 0  2  1
 3  5  6
 1  0  2

julia> c = [5, -3, 2, 3]
4-element Vector{Int64}:
  5
 -3
  2
  3

julia> sum(coeff * prod([x,y,z] .^ row) for (row, coeff) in zip(eachrow(E), c))
3*x*z^2 - 3*y^2*z + 5*x*y^2*z^3 + 2*x^3*y^5*z^6

A little bit clumsy but should get the job done

iliailmer commented 1 year ago

Thank you, @saschatimme @PBrdng! I also found another way using Meta:


function nemo2hc(expr_tree::Union{Expr,Symbol})
    #traverse expr_tree
    if typeof(expr_tree) == Symbol
        return HomotopyContinuation.variables(expr_tree)[1]
    end
    if typeof(expr_tree) == Expr
        if expr_tree.head == :call
            if expr_tree.args[1] in [:+, :-, :*, :/, :^]
                return reduce(eval(expr_tree.args[1]), map(nemo2hc, expr_tree.args[2:end]))
            end
        end
    end
end

called as

nemo2hc(Meta.parse(string(poly)))

I wonder which way will be faster.