The iterator interface gives the possibility of stepping through the numerical steps of the continuation procedure. It thus allows to inject custom monitoring function (saving, plotting, bifurcation detection, ...) at will and during the continuation run. In short, it allows to completely re-write the continuation algorithm as one sees fit and this, in a straightforward manner.
The general method
continuation is built upon this iterator interface and we refer to the source code for a complete example of use.
The iterator provided below does not compute eigenvalues nor perform bifurcations detection.
The interface is set by defining an iterator, pretty much in the same way one calls
iter = ContIterable(prob, alg, opts; kwargs...)
Once an iterator
iter has been defined, one can step through the numerical continuation using a for loop:
for state in iter println("Continuation step = ", state.step) end
state::ContState has the following description. It is a mutable object which holds the current state of the continuation procedure from which one can step to the next state.
The for loop stops when
done(iter, state) returns
false. The condition which is implemented is basically that the number of iterations should be smaller than
maxIter, that the parameters should be in
state = ContState(ds = 1e-4,...)
Returns a variable containing the state of the continuation procedure. The fields are meant to change during the continuation procedure.
z_predcurrent solution on the branch
convergedBoolean for newton correction
itnewtonNumber of newton iteration (in corrector)
stepcurrent continuation step
stopcontinuationBoolean to stop continuation
copy(state)returns a copy of
copyto!(dest, state)returns a copy of
getsolution(state)returns the current solution (x, p)
getx(state)returns the x component of the current solution
getp(state)returns the p component of the current solution
getpreviousp(state)returns the p component of the previous solution
is_stable(state)whether the current state is stable
You can also call
continuation(iter) to have access to the regular continuation method used throughout the tutorials.
We show a quick and simple example of use. Note that it is not very optimized because of the use of global variables.
using BifurcationKit, Plots const BK = BifurcationKit k = 2 # functional we want to study F(x, p) = (@. p + x - x^(k+1)/(k+1)) # bifurcation problem prob = BifurcationProblem(F, [0.8], 1., (@lens _)) # parameters for the continuation opts = ContinuationPar(dsmax = 0.1, dsmin = 1e-3, ds = -0.001, max_steps = 130, p_min = -3., p_max = 3., newton_options = NewtonPar(tol = 1e-8)) # we define an iterator to hold the continuation routine iter = BK.ContIterable(prob, PALC(), opts; verbosity = 2) resp = Float64 resx = Float64 # this is the PALC algorithm for state in iter # we save the current solution on the branch push!(resx, getx(state)) push!(resp, getp(state)) end # plot the result plot(resp, resx; label = "", xlabel = "p")
If you want to customize the iterator to your needs, perhaps the best source of inspiration is the code of the function
continuation!(it::ContIterable, state::ContState, contRes::ContResult) where the iterator is used at its fullest. You will see how the eigen-elements and the stability are computed, how bifurcations are detected and how results are saved.