Error with Catalyst.jl bifurcation diagram tutorial

Hello everyone! I’m still fairly new to Julia and programming in general. I’ve been following the tutorial in the Catalyst.jl documentation for bifurcation diagrams, and I’ve run into an issue. My code (which is copied from the documentation) is as follows:

using Catalyst
rn = @reaction_network begin
    (v0+v*(S*X)^n/((S*X)^n+(D*A)^n+K^n),d), ∅ ↔ X
    (τ*X,τ), ∅ ↔ A
end S D τ v0 v K n d
odefun = ODEFunction(convert(ODESystem,rn),jac=true)
F = (u,p) -> odefun(u,p,0)      
J = (u,p) -> odefun.jac(u,p,0)
params = [1.,9.,0.001,0.01,2.,20.,3,0.05]
p_idx = 1            # The index of the bifurcation parameter.
p_span = (0.1,20.)   # The parameter range for the bifurcation diagram.
plot_var_idx = 1     # The index of the variable we plot in the bifurcation diagram.
using BifurcationKit, Plots, LinearAlgebra, Setfield
opts = ContinuationPar( dsmax = 0.05,        # Maximum arclength value of the pseudo-arc length continuation method.
                        dsmin = 1e-4,        # Minimum arclength value of the pseudo-arc length continuation method.
                        ds=0.001,            # Initial arclength value of the pseudo-arc length continuation method (should be positive).
                        maxSteps = 100000,   # The maximum number of steps.
                        pMin = p_span[1],    # Minimum p-vale (if hit, the method stops).
                        pMax = p_span[2],    # Maximum p-vale (if hit, the method stops).
                        detectBifurcation=3, # Value in {0,1,2,3} determening to what extent bofurcation points are detected (0 means nothing is done, 3 both them and there localisation are detected).
                        newtonOptions = NewtonPar(tol = 1e-9, verbose = false, maxIter = 15)) #Parameters to the newton solver (when finding fixed points) see BifurcationKit documentation.
                        
DO = DeflationOperator( 2,      # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        dot,    # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        1,     # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        [fill(0.,length(rn.states))]); # Guess(es) of the fixed point for the initial parameter set. Do not need to be exact.
params_input = setindex!(copy(params),p_span[1],p_idx)                                # The input parameter values have to start at the first index of our parameter span.
branches, = continuation(F, J, params_input, (@lens _[p_idx]) ,opts , DO,             # Gives our input.
    verbosity = 0, showplot=false,                                                    # We do not want to display, or plot, intermediary results.
    recordFromSolution = (x, p) -> x[plot_var_idx],                                   # How we wish to print the output in the diagram. Here we simply want the value of the target varriable.
    perturbSolution = (x,p,id) -> (x  .+ 0.8 .* rand(length(x))),                     # Parameter for the continuation method, see BifurcationKit documentation.
    callbackN = (x, f, J, res, iteration, itlinear, options; kwargs...) -> res <1e7)  # Parameter for the continuation method, see BifurcationKit documentation.

The last snippet is throwing this error, and I’m unsure as to why:

MethodError: no method matching continuation(::var"#1#2", ::var"#3#4", ::Vector{Float64}, ::Setfield.IndexLens{Tuple{Int64}}, ::ContinuationPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, ::DeflationOperator{Int64, typeof(dot), Vector{Float64}}; verbosity=0, showplot=false, recordFromSolution=var"#5#9"(), perturbSolution=var"#6#10"(), callbackN=var"#7#11"())
Closest candidates are:
  continuation(::Any, ::Any, ::Any, ::Lens, ::ContinuationPar, ::DeflationOperator; verbosity, maxBranches, seekEveryStep, maxIterDefOp, showplot, tangentAlgo, linearAlgo, dotPALC, 452, printSolution, plotSolution, 455, perturbSolution, callbackN, acceptSolution, updateDeflationOp, normN) at C:\Users\Nikith Kurella\.julia\packages\BifurcationKit\Yvq7p\src\DeflatedContinuation.jl:103 got unsupported keyword argument "recordFromSolution"
  continuation(::Any, ::Any, ::Any, ::Lens, ::ContinuationPar; kwargs...) at C:\Users\Nikith Kurella\.julia\packages\BifurcationKit\Yvq7p\src\Continuation.jl:594
  continuation(::Any, ::Any, ::Any, ::Any, ::Lens, ::ContinuationPar; linearAlgo, kwargs...) at C:\Users\Nikith Kurella\.julia\packages\BifurcationKit\Yvq7p\src\Continuation.jl:577
  ...

Stacktrace:
 [1] kwerr(::NamedTuple{(:verbosity, :showplot, :recordFromSolution, :perturbSolution, :callbackN), Tuple{Int64, Bool, var"#5#9", var"#6#10", var"#7#11"}}, ::Function, ::Function, ::Function, ::Vector{Float64}, ::Setfield.IndexLens{Tuple{Int64}}, ::ContinuationPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, ::DeflationOperator{Int64, typeof(dot), Vector{Float64}})
   @ Base .\error.jl:163
 [2] top-level scope
   @ In[8]:2
 [3] eval
   @ .\boot.jl:373 [inlined]
 [4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base .\loading.jl:1196

Any help would be much appreciated!

Hi,

can you give the link from which you copied this?

It is from here: Bifurcation Diagrams · Catalyst.jl
@rveltz I will have a look at it and try to fix it, will drop a note here if I run into trouble.

Ok, the first issue is the option showplot is used instead of plot. However, after changing that, there’s still an error:

MethodError: no method matching (::var"#7#11")(::NamedTuple{(:x, :f, :nothing, :res, :it, :options, :x0, :resHist), Tuple{Vector{Float64}, Vector{Float64}, Nothing, Float64, Int64, NewtonPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, Vector{Float64}, Vector{Float64}}}; fromNewton=true, iterationC=0, p=0.1)
Closest candidates are:
  (::var"#7#11")(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any; kwargs...) at In[7]:6

Stacktrace:
 [1] newton(Fhandle::var"#1#2", Jhandle::var"#3#4", x0::Vector{Float64}, p0::Vector{Float64}, options::NewtonPar{Float64, DefaultLS, DefaultEig{typeof(real)}}; normN::typeof(norm), callback::Function, kwargs::Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol}, NamedTuple{(:iterationC, :p), Tuple{Int64, Float64}}})
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/Newton.jl:117
 [2] iterate(it::ContIterable{var"#1#2", var"#3#4", Vector{Float64}, Vector{Float64}, Setfield.IndexLens{Tuple{Int64}}, Float64, DefaultLS, DefaultEig{typeof(real)}, SecantPred, BorderingBLS{DefaultLS, Float64}, BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, var"#5#9", typeof(norm), BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, typeof(BifurcationKit.finaliseDefault), var"#7#11", Nothing, Nothing}; _verbosity::Int64)
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/Continuation.jl:276
 [3] iterate
   @ ~/.julia/packages/BifurcationKit/eoTLY/src/Continuation.jl:259 [inlined]
 [4] getStatesContResults(iter::BifurcationKit.DefContIterable{ContIterable{var"#1#2", var"#3#4", Vector{Float64}, Vector{Float64}, Setfield.IndexLens{Tuple{Int64}}, Float64, DefaultLS, DefaultEig{typeof(real)}, SecantPred, BorderingBLS{DefaultLS, Float64}, BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, var"#5#9", typeof(norm), BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, typeof(BifurcationKit.finaliseDefault), var"#7#11", Nothing, Nothing}, var"#6#10", BifurcationKit.var"#592#608", BifurcationKit.var"#593#609"}, roots::Vector{Vector{Float64}})
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/DeflatedContinuation.jl:73
 [5] deflatedContinuation(iter::BifurcationKit.DefContIterable{ContIterable{var"#1#2", var"#3#4", Vector{Float64}, Vector{Float64}, Setfield.IndexLens{Tuple{Int64}}, Float64, DefaultLS, DefaultEig{typeof(real)}, SecantPred, BorderingBLS{DefaultLS, Float64}, BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, var"#5#9", typeof(norm), BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, typeof(BifurcationKit.finaliseDefault), var"#7#11", Nothing, Nothing}, var"#6#10", BifurcationKit.var"#592#608", BifurcationKit.var"#593#609"}, deflationOp::DeflationOperator{Int64, typeof(dot), Float64, Vector{Float64}}, contParams::ContinuationPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, verbosity::Int64, plot::Bool)
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/DeflatedContinuation.jl:170
 [6] continuation(F::var"#1#2", J::var"#3#4", par::Vector{Float64}, lens::Setfield.IndexLens{Tuple{Int64}}, contParams::ContinuationPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, defOp::DeflationOperator{Int64, typeof(dot), Float64, Vector{Float64}}; verbosity::Int64, maxBranches::Int64, seekEveryStep::Int64, maxIterDefOp::Int64, plot::Bool, tangentAlgo::SecantPred, linearAlgo::BorderingBLS{DefaultLS, Float64}, dotPALC::BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, recordFromSolution::var"#5#9", plotSolution::BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, perturbSolution::var"#6#10", callbackN::var"#7#11", acceptSolution::BifurcationKit.var"#592#608", updateDeflationOp::BifurcationKit.var"#593#609", normN::typeof(norm))
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/DeflatedContinuation.jl:165
 [7] top-level scope
   @ In[7]:2
 [8] eval
   @ ./boot.jl:373 [inlined]
 [9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1196

I think there’s some problem with the callbackN = (x, f, J, res, iteration, itlinear, options; kwargs...) -> res <1e7 function. Remvoing it an the error disappears (but we get a lot of ┌ Error: Same solution found for identical parameter value!!, which might be expected acroding to Deflated Continuation · Bifurcation Analysis in Julia)

@rveltz Is it that something have changed internally to how the input or output of the callbackN function is expected to be? I also try the example form Deflated Continuation · Bifurcation Analysis in Julia

using BifurcationKit, LinearAlgebra, Setfield, SparseArrays, Plots
const BK = BifurcationKit

k = 2
N = 1
F = (x, p) -> p .* x .+ x.^(k+1)/(k+1) .+ 0.01
Jac_m = (x, p) -> diagm(0 => p .+ x.^k)

opts = BK.ContinuationPar(dsmax = 0.051, dsmin = 1e-3, ds=0.001, maxSteps = 140, pMin = -3., saveSolEveryStep = 0, newtonOptions = NewtonPar(tol = 1e-8, verbose = false), saveEigenvectors = false);

brdc, = continuation(F,Jac_m, 0.5, (@lens _),
	ContinuationPar(opts, ds = -0.001, maxSteps = 800, newtonOptions = NewtonPar(verbose = false, maxIter = 6), plotEveryStep = 40),
	DeflationOperator(2.0, dot, .001, [[0.]]); plot=true, verbosity = 0,
	perturbSolution = (x,p,id) -> (x  .+ 0.1 .* rand(length(x))),
	callbackN = (x, f, J, res, iteration, itlinear, options; kwargs...) -> res <1e3)

and get the identical error:

MethodError: no method matching (::var"#17#20")(::NamedTuple{(:x, :f, :nothing, :res, :it, :options, :x0, :resHist), Tuple{Vector{Float64}, Vector{Float64}, Nothing, Float64, Int64, NewtonPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, Vector{Float64}, Vector{Float64}}}; fromNewton=true, iterationC=0, p=0.5)
Closest candidates are:
  (::var"#17#20")(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any; kwargs...) at In[10]:5

Stacktrace:
 [1] newton(Fhandle::var"#12#13", Jhandle::var"#14#15", x0::Vector{Float64}, p0::Float64, options::NewtonPar{Float64, DefaultLS, DefaultEig{typeof(real)}}; normN::typeof(norm), callback::Function, kwargs::Base.Pairs{Symbol, Real, Tuple{Symbol, Symbol}, NamedTuple{(:iterationC, :p), Tuple{Int64, Float64}}})
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/Newton.jl:117
 [2] iterate(it::ContIterable{var"#12#13", var"#14#15", Vector{Float64}, Float64, Setfield.IdentityLens, Float64, DefaultLS, DefaultEig{typeof(real)}, SecantPred, BorderingBLS{DefaultLS, Float64}, BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, BifurcationKit.var"#586#602", typeof(norm), BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, typeof(BifurcationKit.finaliseDefault), var"#17#20", Nothing, Nothing}; _verbosity::Int64)
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/Continuation.jl:276
 [3] iterate
   @ ~/.julia/packages/BifurcationKit/eoTLY/src/Continuation.jl:259 [inlined]
 [4] getStatesContResults(iter::BifurcationKit.DefContIterable{ContIterable{var"#12#13", var"#14#15", Vector{Float64}, Float64, Setfield.IdentityLens, Float64, DefaultLS, DefaultEig{typeof(real)}, SecantPred, BorderingBLS{DefaultLS, Float64}, BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, BifurcationKit.var"#586#602", typeof(norm), BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, typeof(BifurcationKit.finaliseDefault), var"#17#20", Nothing, Nothing}, var"#16#19", BifurcationKit.var"#592#608", BifurcationKit.var"#593#609"}, roots::Vector{Vector{Float64}})
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/DeflatedContinuation.jl:73
 [5] deflatedContinuation(iter::BifurcationKit.DefContIterable{ContIterable{var"#12#13", var"#14#15", Vector{Float64}, Float64, Setfield.IdentityLens, Float64, DefaultLS, DefaultEig{typeof(real)}, SecantPred, BorderingBLS{DefaultLS, Float64}, BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, BifurcationKit.var"#586#602", typeof(norm), BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, typeof(BifurcationKit.finaliseDefault), var"#17#20", Nothing, Nothing}, var"#16#19", BifurcationKit.var"#592#608", BifurcationKit.var"#593#609"}, deflationOp::DeflationOperator{Float64, typeof(dot), Float64, Vector{Float64}}, contParams::ContinuationPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, verbosity::Int64, plot::Bool)
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/DeflatedContinuation.jl:170
 [6] continuation(F::var"#12#13", J::var"#14#15", par::Float64, lens::Setfield.IdentityLens, contParams::ContinuationPar{Float64, DefaultLS, DefaultEig{typeof(real)}}, defOp::DeflationOperator{Float64, typeof(dot), Float64, Vector{Float64}}; verbosity::Int64, maxBranches::Int64, seekEveryStep::Int64, maxIterDefOp::Int64, plot::Bool, tangentAlgo::SecantPred, linearAlgo::BorderingBLS{DefaultLS, Float64}, dotPALC::BifurcationKit.DotTheta{BifurcationKit.var"#169#171", BifurcationKit.var"#170#172"}, recordFromSolution::BifurcationKit.var"#586#602", plotSolution::BifurcationKit.var"#587#603"{BifurcationKit.var"#587#588#604"}, perturbSolution::var"#16#19", callbackN::var"#17#20", acceptSolution::BifurcationKit.var"#592#608", updateDeflationOp::BifurcationKit.var"#593#609", normN::typeof(norm))
   @ BifurcationKit ~/.julia/packages/BifurcationKit/eoTLY/src/DeflatedContinuation.jl:165
 [7] top-level scope
   @ In[10]:1
 [8] eval
   @ ./boot.jl:373 [inlined]
 [9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1196

There are several issues. The best is to use the following limiter:

callbackN = BifurcationKit.cbMaxNorm(1e7)

so you dont have to worry about the signature. The next one is here:

DO = DeflationOperator( 2,     
                        dot,    
                        1.,    # note the Float here
                        [fill(0.,length(rn.states))]); 

You used integer valued DeflationOperator. Maybe I should be less strict in the function signature.

1 Like

All in all:

DO = DeflationOperator( 2,      # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        dot,    # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        1.,     # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        [fill(0.,length(rn.states))]); # Guess(es) of the fixed point for the initial parameter set. Do not need to be exact.

params_input = setindex!(copy(params),p_span[1],p_idx)                                # The input parameter values have to start at the first index of our parameter span.
branches, = continuation(F, J, params_input, (@lens _[p_idx]), opts , DO,             # Gives our input.
    verbosity = 0, plot=false,                                                    # We do not want to display, or plot, intermediary results.
    recordFromSolution = (x, p) -> x[plot_var_idx],                                   # How we wish to print the output in the diagram. Here we simply want the value of the target varriable.
    perturbSolution = (x,p,id) -> (x  .+ 0.8 .* rand(length(x))),                     # Parameter for the continuation method, see BifurcationKit documentation.
    callbackN = BifurcationKit.cbMaxNorm(1e7),  # Parameter for the continuation method, see BifurcationKit documentation.
)

plot(branches...)
1 Like

Yes, that works well, thanks a lot for helping. Also, thanks @Dragolonth for reporting the issue. I will update the docs after lunch.

Yes, the function signature has changed here so it is less cumbersome. I have not tagged a version yet so maybe you can add the BK version bound 1.10.0 on Catalyst’s website.

Apologies for this…

Amazing! Thank you @rveltz and @Gaussia

I was getting this error message when I was using a float value:

MethodError: no method matching DeflationOperator(::Int64, ::typeof(dot), ::Float64, ::Vector{Vector{Float64}})
Closest candidates are:
  DeflationOperator(::T, ::Tdot, ::T, ::Vector{vectype}) where {T<:Real, Tdot, vectype} at C:\Users\Nikith Kurella\.julia\packages\BifurcationKit\Yvq7p\src\DeflationOperator.jl:14

Stacktrace:
 [1] top-level scope
   @ In[10]:10
 [2] eval
   @ .\boot.jl:373 [inlined]
 [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base .\loading.jl:1196

Using an integer value seemed to resolve this error

I seem to have run into another issue. After copying your code, I get this error:

UndefVarError: cbMaxNorm not defined

Stacktrace:
 [1] getproperty(x::Module, f::Symbol)
   @ Base .\Base.jl:35
 [2] top-level scope
   @ In[11]:16
 [3] eval
   @ .\boot.jl:373 [inlined]
 [4] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base .\loading.jl:1196

I believe I have initialized the BifurcationKit package correctly, so I’m unsure as to why cbMaxNorm is not defined.

it is not exported, so BifurcationKit.cbMaxNorm

Thank you for bearing with me @rveltz. Forgive me if this is a basic question, but I seem to still be getting the error after using BifurcationKit.cbMaxNorm

Here is my code:

using BifurcationKit, Plots, LinearAlgebra, Setfield
opts = ContinuationPar( dsmax = 0.05,        # Maximum arclength value of the pseudo-arc length continuation method.
                        dsmin = 1e-4,        # Minimum arclength value of the pseudo-arc length continuation method.
                        ds=0.001,            # Initial arclength value of the pseudo-arc length continuation method (should be positive).
                        maxSteps = 100000,   # The maximum number of steps.
                        pMin = p_span[1],    # Minimum p-vale (if hit, the method stops).
                        pMax = p_span[2],    # Maximum p-vale (if hit, the method stops).
                        detectBifurcation=3, # Value in {0,1,2,3} determening to what extent bofurcation points are detected (0 means nothing is done, 3 both them and there localisation are detected).
                        newtonOptions = NewtonPar(tol = 1e-9, verbose = false, maxIter = 15)) #Parameters to the newton solver (when finding fixed points) see BifurcationKit documentation.
DO = DeflationOperator( 2,      # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        dot,    # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        1,     # Algorithm parameter required when using deflated continuation, see BifurcationKit documentation.
                        [fill(0.,length(rn.states))]); # Guess(es) of the fixed point for the initial parameter set. Do not need to be exact.

params_input = setindex!(copy(params),p_span[1],p_idx)                                # The input parameter values have to start at the first index of our parameter span.
branches, = continuation(F, J, params_input, (@lens _[p_idx]), opts , DO,             # Gives our input.
    verbosity = 0, plot=false,                                                    # We do not want to display, or plot, intermediary results.
    recordFromSolution = (x, p) -> x[plot_var_idx],                                   # How we wish to print the output in the diagram. Here we simply want the value of the target varriable.
    perturbSolution = (x,p,id) -> (x  .+ 0.8 .* rand(length(x))),                     # Parameter for the continuation method, see BifurcationKit documentation.
    callbackN = BifurcationKit.cbMaxNorm(1e7),  # Parameter for the continuation method, see BifurcationKit documentation.
)

plot(branches...)

please compare my code to yours, see DO