JuliaIntervals / IntervalRootFinding.jl

Library for finding the roots of a function using interval arithmetic
https://juliaintervals.github.io/IntervalRootFinding.jl/
Other
127 stars 26 forks source link

Cannot use complex functions #40

Open dpsanders opened 6 years ago

dpsanders commented 6 years ago
julia> roots(sin, Complex(-5..5, -5..5))
ERROR: MethodError: no method matching sin(::IntervalRootFinding.Compl{IntervalArithmetic.Interval{Float64}})
Closest candidates are:
  sin(::Float64) at math.jl:419
  sin(::Float32) at math.jl:420
  sin(::Float16) at math.jl:950

There was an issue that meant that standard Julia complex numbers could not be used, hence the reimplementation in complex.jl as Compl that is cited here.

dpsanders commented 6 years ago

(Though I don't see how that is being used.)

dpsanders commented 6 years ago

After simply removing the definitions of Compl in complex.jl, this seems to work:

julia> roots(sin, Complex(-5..6, -5..6))
3-element Array{IntervalRootFinding.Root{Complex{IntervalArithmetic.Interval{Float64}}},1}:
 Root([3.14159, 3.1416] + [0, 0]*im, :unique)
 Root([-4.44287e-27, 3.23118e-27] + [-1.61559e-27, 1.2117e-27]*im, :unique)
 Root([-3.1416, -3.14159] + [-0, -0]*im, :unique)
dpsanders commented 6 years ago

(Note that there is some weirdness with the zeros in the first and last root.)

bernardrhall commented 5 years ago

Hi, I seem to have run into a similar problem, and I was wondering if this has been fixed? Using the test function:

x=-5..5
xx = Complex(x,x)

function tst(x)
    return sin(x)
end

rts = roots(tst, xx)

I get the error:

MethodError: no method matching sin(::IntervalRootFinding.Compl{Interval{Float64}}) Closest candidates are: sin(!Matched::Float16) at math.jl:1018 sin(!Matched::Complex{Float16}) at math.jl:1019 sin(!Matched::Missing) at math.jl:1070 ...

Stacktrace:

[2] (::getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)})(::IntervalBox{2,Float64}) at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\complex.jl:34 [3] newtonlike_contract(::typeof(IntervalRootFinding.𝒩), ::Newton{getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)},getfield(IntervalRootFinding, Symbol("##44#46")){getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)}}}, ::IntervalBox{2,Float64}, ::Float64) at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\contractors.jl:41 [4] (::Newton{getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)},getfield(IntervalRootFinding, Symbol("##44#46")){getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)}}})(::IntervalBox{2,Float64}, ::Float64) at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\contractors.jl:75 [5] step!(::IntervalRootFinding.RootSearchState{IntervalBox{2,Float64}}, ::Newton{getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)},getfield(IntervalRootFinding, Symbol("##44#46")){getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)}}}, ::Float64) at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\roots.jl:60 [6] iterate at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\roots.jl:83 [inlined] [7] branch_and_prune(::IntervalBox{2,Float64}, ::Newton{getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)},getfield(IntervalRootFinding, Symbol("##44#46")){getfield(IntervalRootFinding, Symbol("#g#34")){typeof(tst)}}}, ::Float64) at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\roots.jl:108 [8] roots(::Function, ::Function, ::IntervalBox{2,Float64}, ::Type{Newton}, ::Float64) at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\roots.jl:170 [9] roots(::Function, ::Complex{Interval{Float64}}, ::Type{Newton}, ::Float64) at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\roots.jl:208 [10] roots at C:\Users\mrg.julia\packages\IntervalRootFinding\H2vL9\src\roots.jl:227 [inlined] (repeats 2 times)

dpsanders commented 5 years ago

This has not yet been fixed. If you change Compl to Complex in complex.jl then it works with sin, but no longer with polynomials...

One solution is to just implement sin etc. directly on the Compl type.