diff --git a/.travis.yml b/.travis.yml index 722b9be..50cd624 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,8 @@ language: julia os: - linux - -arch: - - amd64 + - osx + - windows julia: - nightly @@ -15,11 +14,6 @@ julia: notifications: email: false -before_install: - - sudo apt-add-repository -y ppa:leo.robol/mpsolve - - sudo apt-get update -qq - - sudo apt-get install -y libmps3 libmps3-dev - script: - julia --color=yes -e 'using Pkg; Pkg.test(; coverage=true)'; diff --git a/Project.toml b/Project.toml index 962afcd..5d867a7 100644 --- a/Project.toml +++ b/Project.toml @@ -1,9 +1,10 @@ name = "MPSolve" uuid = "9b0ab244-28a7-517c-931e-75c4e3199a6c" authors = ["Leonardo Robol ", "Mikhail Kagalenko Pkg.clone("git://github.com/robol/MPSolve.jl.git") -``` -Notice that, in order to use the package, you will need to have -libmps available on the system. See the official [MPSolve website](http://numpi.dm.unipi.it/mpsolve/) -for instructions on getting MPSolve up and running. - +This repository contains the Julia interface to the [MPSolve](https://github.com/robol/MPSolve) polynomial rootfinder. diff --git a/README.md b/README.md index 5719db8..ab13d21 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,4 @@ [![Coverage Status](https://coveralls.io/repos/github/kagalenko-m-b/MPSolve.jl/badge.svg?branch=master)](https://coveralls.io/github/kagalenko-m-b/MPSolve.jl?branch=master) # MPSolve.jl -This repository contains the Julia interface to the MPSolve -polynomial rootfinder. It requires Julia version no less than 1.3. You can -install the package in your Julia environment by typing -``` - julia> Pkg.add("https://github.com/robol/MPSolve.jl.git") -``` -Notice that in order to use the package, you will need to have -libmps available on the system. See the official [MPSolve website](http://numpi.dm.unipi.it/mpsolve/) -for instructions on getting MPSolve up and running. - - +This repository contains the Julia interface to the [MPSolve](https://github.com/robol/MPSolve) polynomial rootfinder. diff --git a/src/MPSolve.jl b/src/MPSolve.jl index 32d0c1e..00a7729 100644 --- a/src/MPSolve.jl +++ b/src/MPSolve.jl @@ -3,6 +3,7 @@ module MPSolve include("MpsNumberTypes.jl") using .MpsNumberTypes +using MPSolve_jll export mps_roots,mps_barycentric_coeffs @@ -18,7 +19,7 @@ struct MContext{PolyType} degree = length(coeffs) - 1 cntxt_ptr = new_cntxt_ptr() monomial_poly = ccall( - (:mps_monomial_poly_new, :libmps), + (:mps_monomial_poly_new, libmps), Ptr{Cvoid}, (Ptr{Cvoid}, Int), cntxt_ptr, degree ) @@ -34,7 +35,7 @@ struct MContext{PolyType} throw(ArgumentError("input arrays must have equal length")) end cntxt_ptr = new_cntxt_ptr() - sec_eqn = ccall((:mps_secular_equation_new_raw, :libmps), Ptr{Cvoid}, + sec_eqn = ccall((:mps_secular_equation_new_raw, libmps), Ptr{Cvoid}, (Ptr{Cvoid}, Culong), cntxt_ptr, degree ) @@ -47,26 +48,24 @@ end function new_cntxt_ptr() - cntxt_ptr = ccall((:mps_context_new, :libmps), Ptr{Cvoid}, ()) + cntxt_ptr = ccall((:mps_context_new, libmps), Ptr{Cvoid}, ()) end function set_coefficient!(context::MContext{Monomial}, cf::Complex{Float64}, index) ccall( - (:mps_monomial_poly_set_coefficient_d, :libmps), + (:mps_monomial_poly_set_coefficient_d, libmps), Cvoid, (Ref{Cvoid}, Ref{Cvoid}, Clong, Cdouble, Cdouble), context.cntxt_ptr, context.poly, index, cf.re, cf.im ) end -function set_coefficient!(context::MContext{Monomial}, cf, index) - c_re = Mpq(real(cf)) - c_im = Mpq(imag(cf)) +function set_coefficient!(context::MContext{Monomial}, cf::Complex, index) + c_re,c_im = Mpq(cf) ccall( - (:mps_monomial_poly_set_coefficient_q, :libmps), + (:mps_monomial_poly_set_coefficient_q, libmps), Cvoid, (Ref{Cvoid}, Ref{Cvoid}, Clong, Ref{Mpq}, Ref{Mpq}), context.cntxt_ptr, context.poly, index, c_re, c_im ) - mps_clear!([c_re, c_im]) end function set_coefficient!( @@ -75,7 +74,7 @@ function set_coefficient!( c_re = Clonglong(real(cf)) c_im = Clonglong(real(cf)) ccall( - (:mps_monomial_poly_set_coefficient_int, :libmps), + (:mps_monomial_poly_set_coefficient_int, libmps), Cvoid, (Ref{Cvoid}, Ref{Cvoid}, Clong, Clonglong, Clonglong), context.cntxt_ptr, context.poly, index, c_re, c_im ) @@ -92,22 +91,19 @@ function set_coefficients!( context::MContext{Secular}, a_coeffs::AbstractVector, b_coeffs::AbstractVector ) for (k, (a,b)) in enumerate(zip(a_coeffs, b_coeffs)) - a_re = Mpq(real(a)) - a_im = Mpq(imag(a)) - b_re = Mpq(real(b)) - b_im = Mpq(imag(b)) + a_re,a_im = Mpq(complex(a)) + b_re,b_im = Mpq(complex(b)) ccall( - (:mps_secular_equation_set_coefficient_q, :libmps), + (:mps_secular_equation_set_coefficient_q, libmps), Cvoid, (Ref{Cvoid}, Ref{Cvoid}, Clong, Ref{Mpq}, Ref{Mpq}, Ref{Mpq}, Ref{Mpq}), context.cntxt_ptr, context.poly, k - 1, a_re, a_im, b_re, b_im ) - mps_clear!([a_re, a_im, b_re, b_im]) end return nothing end function set_input_poly(context::MContext) - ccall((:mps_context_set_input_poly, :libmps), Cvoid, + ccall((:mps_context_set_input_poly, libmps), Cvoid, (Ref{Cvoid}, Ref{Cvoid}), context.cntxt_ptr, context.poly) end @@ -118,7 +114,7 @@ end function select_algorithm(context::MContext, alg::mps_algorithm) ccall( - (:mps_context_select_algorithm, :libmps), Cvoid, + (:mps_context_select_algorithm, libmps), Cvoid, (Ref{Cvoid}, Cint), context.cntxt_ptr, alg ) end @@ -131,7 +127,7 @@ end function set_output_goal(context::MContext, goal:: mps_output_goal) ccall( - (:mps_context_set_output_goal, :libmps), + (:mps_context_set_output_goal, libmps), Cvoid, (Ref{Cvoid}, Cint), context.cntxt_ptr, goal ) @@ -139,14 +135,14 @@ end function set_output_precision(context::MContext, output_precision::Integer) ccall( - (:mps_context_set_output_prec, :libmps), Cvoid, + (:mps_context_set_output_prec, libmps), Cvoid, (Ref{Cvoid}, Clong), context.cntxt_ptr, output_precision ) end function mpsolve(context::MContext) - ccall((:mps_mpsolve, :libmps), Cvoid, (Ptr{Cvoid},), context.cntxt_ptr) + ccall((:mps_mpsolve, libmps), Cvoid, (Ptr{Cvoid},), context.cntxt_ptr) end function solve_poly(context::MContext, output_precision::Integer) @@ -158,7 +154,7 @@ end function get_degree(context::MContext) - ccall((:mps_context_get_degree, :libmps), Cint, (Ref{Cvoid},), context.cntxt_ptr) + ccall((:mps_context_get_degree, libmps), Cint, (Ref{Cvoid},), context.cntxt_ptr) end function get_roots(context::MContext, output_precision::Int) @@ -181,7 +177,7 @@ function get_roots_big(context::MContext) roots_ptr = pointer(roots_m) rds_ptr = pointer(rds) ccall( - (:mps_context_get_roots_m, :libmps), Cint, + (:mps_context_get_roots_m, libmps), Cint, (Ref{Cvoid}, Ref{Ptr{Mpsc}}, Ref{Ptr{Rdpe}}), context.cntxt_ptr, roots_ptr, rds_ptr ) @@ -200,7 +196,7 @@ function get_roots_f64(context::MContext) roots_ptr = pointer(roots_c) radii_ptr = pointer(radii) ccall( - (:mps_context_get_roots_d, :libmps), Cint, + (:mps_context_get_roots_d, libmps), Cint, (Ref{Cvoid}, Ref{Ptr{Cplx}}, Ref{Ptr{Cdouble}}), context.cntxt_ptr, roots_ptr, radii_ptr ) @@ -313,7 +309,7 @@ end function free_poly(context::MContext{Monomial}) ccall( - (:mps_monomial_poly_free, :libmps), Cvoid, + (:mps_monomial_poly_free, libmps), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), context.cntxt_ptr, context.poly ) @@ -321,7 +317,7 @@ end function free_poly(context::MContext{Secular}) ccall( - (:mps_secular_equation_free, :libmps), Cvoid, + (:mps_secular_equation_free, libmps), Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}), context.cntxt_ptr, context.poly ) @@ -329,6 +325,6 @@ end function free_context(context::MContext) free_poly(context) - ccall((:mps_context_free, :libmps), Cvoid, (Ptr{Cvoid},), context.cntxt_ptr) + ccall((:mps_context_free, libmps), Cvoid, (Ptr{Cvoid},), context.cntxt_ptr) end end diff --git a/src/MpsNumberTypes.jl b/src/MpsNumberTypes.jl index 5a7bcc1..97eb615 100644 --- a/src/MpsNumberTypes.jl +++ b/src/MpsNumberTypes.jl @@ -2,7 +2,9 @@ module MpsNumberTypes using Base.GMP: Limb using Base.MPFR: MPFRRoundingMode,MPFRRoundNearest -import Base: convert, big, complex +using MPSolve_jll +import Base: big, convert, complex, finalizer + export Mpz,Mpq,Mpf,Mpsc,Rdpe,Cplx,mpsf_precision,mpsf_setprecision,mps_clear! function __init__() @@ -39,7 +41,7 @@ end big(::Type{Mpz}) = BigInt big(v::Mpz) = BigInt(v) -struct Mpq +mutable struct Mpq num::Mpz den::Mpz @@ -48,23 +50,30 @@ struct Mpq Mpq(q::Rational{T}) where T<:Signed = Mpq(q.num, q.den) Mpq(num::T, den::S) where {T, S<:Signed} = Mpq(BigInt(num), BigInt(den)) function Mpq(num::BigInt, den::BigInt) - q = Ref{Mpq}() + #q = Ref{Mpq}() + q = new() ccall((:__gmpq_init, :libgmp), Cvoid, (Ref{Mpq},), q) ccall((:__gmpq_set_num, :libgmp), Cvoid, (Ref{Mpq},Ref{BigInt}), q, num) ccall((:__gmpq_set_den, :libgmp), Cvoid, (Ref{Mpq},Ref{BigInt}), q, den) - return q[] + finalizer(cglobal((:__gmpq_clear, :libgmp)), q) + return q end function Mpq(f::BigFloat) - q = Ref{Mpq}() + #q = Ref{Mpq}() + q = new() ccall((:__gmpq_init, :libgmp), Cvoid, (Ref{Mpq},), q) ccall((:mpfr_get_q, :libmpfr), Cvoid, (Ref{Mpq}, Ref{BigFloat}), q, f) - return q[] + finalizer(cglobal((:__gmpq_clear, :libgmp)), q) + return q end + end + mps_clear!(m::Mpz) = ccall((:__gmpz_clear, :libgmp), Cvoid, (Ref{Mpz},), m) -mps_clear!(m::Mpq) = ccall((:__gmpq_clear, :libgmp), Cvoid, (Ref{Mpq},), m) +# mps_clear!(m::Mpq) = ccall((:__gmpq_clear, :libgmp), Cvoid, (Ref{Mpq},), m) Mpq(f::AbstractFloat) = Mpq(big(f)) +Mpq(c::Complex) = Mpq.(reim(c)) Base.convert(::Type{Mpq}, x::T) where T<:Union{Signed,Rational} = Mpq(x) Base.Rational(q::Mpq) = Rational(BigInt(q.num), BigInt(q.den)) (::Type{T})(q::Mpq) where T<: AbstractFloat = T(Rational(q)) @@ -162,7 +171,7 @@ struct Rdpe e::Clong end -Float64(d::Rdpe) = ccall((:rdpe_get_d, :libmps), Cdouble, (Ref{Rdpe},) ,d) +Float64(d::Rdpe) = ccall((:rdpe_get_d, libmps), Cdouble, (Ref{Rdpe},) ,d) struct Cplx r::Cdouble diff --git a/test/runtests.jl b/test/runtests.jl index b87641e..22bc364 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -114,7 +114,7 @@ end v = Mpq.(Any[big(pi), rationalize(Float64(pi), tol=eps(BigFloat))]) @test eltype(v) == Mpq && eltype(big.(v)) == BigFloat @test big.(v) == [big(pi), Float64(pi)] - mps_clear!(v) + #mps_clear!(v) # v = Mpf.(Any[Float64(pi), Int32(1234567890)]) @test eltype(v) == Mpf && eltype(big.(v)) == BigFloat