-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Root finding with interval parameters #158
Comments
In principle yes they are allowed, but the problem is that the zeros are then no longer isolated, so the standard interval Newton method (which Using bisection instead should work: rts = roots(f, IntervalBox(0..8000, 0..100), Bisection) I believe that this could be solved by using the parametric interval Newton method, which should be able to prove uniqueness for each parameter value in your input interval, but that is not yet implemented. Help here is welcome! |
It seems to run infinitely because the default tolerance is absolute and small (1e-7). If you put in a tolerance more adapted to your range it terminates julia> roots(f, IntervalBox(0..1000, 0..100), Newton, 10.0)
111-element Array{Root{IntervalBox{2,Float64}},1}:
Root([792.702, 800.575] × [28.9393, 33.6693], :unknown)
Root([299.76, 307.633] × [28.9393, 33.6693], :unknown)
Root([338.634, 346.385] × [28.9393, 33.6693], :unknown)
Root([330.762, 338.635] × [28.9393, 33.6693], :unknown)
Root([511.235, 518.866] × [28.9393, 33.6693], :unknown)
Root([879.797, 887.67] × [28.9393, 33.6693], :unknown)
Root([855.929, 863.926] × [28.9393, 33.6693], :unknown)
Root([959.388, 967.511] × [28.9393, 33.6693], :unknown)
Root([927.401, 935.524] × [28.9393, 33.6693], :unknown)
Root([416.749, 424.622] × [28.9393, 33.6693], :unknown)
Root([385.504, 393.255] × [28.9393, 33.6693], :unknown)
Root([651.111, 658.862] × [28.9393, 33.6693], :unknown)
⋮
Root([534.245, 541.996] × [28.9393, 33.6693], :unknown)
Root([729.96, 737.957] × [28.9393, 33.6693], :unknown)
Root([307.632, 315.263] × [28.9393, 33.6693], :unknown)
Root([323.012, 330.763] × [28.9393, 33.6693], :unknown)
Root([951.392, 959.389] × [28.9393, 33.6693], :unknown)
Root([214.618, 222.369] × [28.9393, 33.6693], :unknown)
Root([635.489, 643.24] × [28.9393, 33.6693], :unknown)
Root([175.744, 183.617] × [28.9393, 33.6693], :unknown)
Root([238.112, 246.11] × [28.9393, 33.6693], :unknown)
Root([253.62, 261.251] × [28.9393, 33.6693], :unknown)
Root([604.241, 612.114] × [28.9393, 33.6693], :unknown)
Root([919.405, 927.402] × [28.9393, 33.6693], :unknown) |
Thanks! Yes I have been experimenting with the tolerance. In this case, it seems strange to return all of these roots. I know that there will be a big range with one root, so I just defined: Base.union(a::Root, b::Root) = union(a.interval,b.interval)
Base.union(a::IntervalBox, b::Root) = union(a,b.interval) to get:
edit: I suppose mapreduce(r->r.interval, union, roots(f, IntervalBox(0..8000, 0..100), Newton, 1.0)) |
I am fairly confident that all the roots returned here overlap, so should the answer there be just a single root? E.g. with a bigger tol so that the list is more manageable:
Why are these intervals even being subdivided in the first place? |
Interval bodes are being subdivised until one of the following is true:
The core idea is that proving existence or absence of solution is easier with smaller box. Reassambling boxes is interesting, but it is not clear how it should be done in general. Taking the union results in a bigger box than necessary in many case. Finally another issue here is that we only allow the same tolerance for each dimension, which in your case doesn't quite make sense. |
Thanks for the detailed answer.
This makes sense!
I suppose that as long as the intervals are overlapping, as they are for the above, it is natural to merge them, no? There could be an additional pass at the end of the root finding algorithm to do that. (I assume that when splitting a box, the resulting subboxes are created overlapping on purpose?). I could look into doing that, is there already functionality to check if boxes are overlapping?
Yes, that could be solved by allowing to pass a tuple for the tolerance in each dimension. |
It totally is, I am just cautious before saying it will be straightforward :). Consider the following image where gray boxes have status How should the gray boxes be merged? Taking the union would give big box covering everything, thus losing resolution, which is not acceptable (by default at least). Still you can merge 1-3 and 4-6, but you could also merge 3-4-6. The most reasonable think to do may be to walk the internal tree in reverse and merge leaves with common ancestors. But really before someone try to seriously tackle that it is impossible to tell. If you want to be the one tackling it you are of course welcome :) |
The boxes produced by the algorithm don't really overlap, they abut: they share only edges (no interior points). They have to share edges in order to cover all possible inputs (since we deal only with closed intervals, not open intervals). I wrote some code to unify boxes using connected components from LightGraphs.jl, which I can dig up, but as @Kolaru points out, the result is a single box that is the interval hull of the subboxes. |
Ah in fact a version of |
I couldn't find an example for this in the docs, but are Interval values (not unknowns) allowed in the root function?
I tried the following (note the interval
g1
parameter), but it doesn't appear to finish. Any advice on if this is doable?Note that the code works great if I plug in a number for
g2
, but I would like the result interval to reflect the uncertainty ing2
.The text was updated successfully, but these errors were encountered: