I only find that it can print out such information by the kwargs verbose=true
. But how can I obtain this just like the Optim.jl
which store all information in the returned value? I want to count the number of evaluations of my function called by each root finding algorithm.
Just increment a counter in your function. (You can use a local variable for the counter via a closure.)
Thanks! But what if I don’t want to modify my funciton (or the function is an external call to the C/C++ funciton?). Do you know any other root finding packages that keeps track of its iteration trace? Besides the number of evaluations, I’d also like to know the x
and f(x)
during each iteration.
“You can use a local variable for the counter via a closure.” means to do the following. You can use any function including a function which is an external call to the C function.
using Roots
function withcounter(f, n = 0)
c = Ref(n)
F(x...; y...) = (c[] += 1; f(x...; y...))
getcounter() = c[]
setcounter!(n) = c[] = n
F, getcounter, setcounter!
end
f(x::Float64)::Float64 = @ccall sin(x::Float64)::Float64
@show f(1.0);
f(1.0) = 0.8414709848078965
F, getcounter, setcounter! = withcounter(x -> f(x) - 0.8414709848078965)
@show find_zero(F, 0.9)
@show getcounter();
find_zero(F, 0.9) = 1.0
getcounter() = 11
setcounter!(0)
@show find_zeros(F, 0, 2π)
@show getcounter();
find_zeros(F, 0, 2π) = [1.0, 2.141592653589793]
getcounter() = 1270
In addition to the suggested ways, the state object keeps track of this. It can be accessed different ways, here is one:
using Roots
Z = ZeroProblem(sin, (3,4))
prob = init(Z, Roots.Secant()); solve!(prob)
prob.state.fnevals # 7
This solution leads me to explore the source code of Roots.jl
package. And what I find is the kwargs tracks
which is exactly what I want! Thanks all!
To track the number of evaluations and all xs
and fs
, we just provide a Tracks
instance to the kwargs, such as
using Roots
tracks = Roots.Tracks(Float64[], Float64[])
find_zero(sin, (3,4), Roots.FalsePosition(), tracks=tracks, verbose=true)
Then we can show the tracks
Roots.show_tracks(tracks, Roots.FalsePosition())