Skip to content

Conversation

@TorkelE
Copy link
Member

@TorkelE TorkelE commented Aug 1, 2022

This updates the bifurcation diagram tutorial to work with the latest BifurcationKit version. It also uses a slightly less powerful (and thus simpler) approach.

@TorkelE
Copy link
Member Author

TorkelE commented Aug 1, 2022

(Need to add an updated figure before we can merge)

@isaacsas
Copy link
Member

isaacsas commented Aug 1, 2022

Could you convert this to be a dynamic tutorial that uses @example blocks? (See some of the others.)

That would cause it to run when docs are built, and let us see immediately if it breaks.

(Also, maybe switch to using the preferred u0 / p style with mappings?)

@TorkelE
Copy link
Member Author

TorkelE commented Aug 1, 2022

Could you convert this to be a dynamic tutorial that uses @example blocks? (See some of the others.

Sounds good, will do.

I could use the mapping notation, however, I would then have to do e.g. first.() to extract a vector which made it all feel a bit silly. Ideally, at some point, it would be good if we could make the two packages more compatible, including permitting BifurcationKit use mapping input.

Bit unsure how it will look though, might need some tutorial redesign.
@isaacsas
Copy link
Member

isaacsas commented Aug 1, 2022

Right, but the point is even using first.(pmap) is implicitly then assuming you've defined the parameters with the correct ordering, and we no longer provide any guarantees about that. Calling varmap_to_vars on a symbolic mapping will give you the correct order. Alternatively you could just create an ODEProblem and extract p, u0 and the ODEFunction from that (instead of creating an ODEFunction directly).

@TorkelE
Copy link
Member Author

TorkelE commented Aug 1, 2022

Going via an ODEProblem seems like a good way to do it, agreed.

@isaacsas
Copy link
Member

isaacsas commented Aug 1, 2022

Yeah, that should probably be the way we suggest people get all the "stuff" out they need to interface with non-MT packages.

@isaacsas
Copy link
Member

isaacsas commented Aug 1, 2022

Looks like there are some issues in running the examples -- the output doesn't look all there:

https://catalyst.sciml.ai/previews/PR539/tutorials/bifurcation_diagram/

Have you tried building the docs locally to double check them?

@TorkelE
Copy link
Member Author

TorkelE commented Aug 1, 2022

I was unsure how to build them locally (I just ran the code), so I just used the preview function https://catalyst.sciml.ai/previews/PR539/tutorials/bifurcation_diagram/.

To me it seems that it is just the display of the actual diagram that fails:
image

The 3 before that doesn't display anything, but given that it would just be an incomprehensible mess, that is probably very much desired...

@isaacsas
Copy link
Member

isaacsas commented Aug 1, 2022

The final four example boxes have no output, so I think this is an issue.

You can build them locally by going into the docs folder, activating the environment there, resolving it, and then including the make.jl file.

@TorkelE
Copy link
Member Author

TorkelE commented Aug 2, 2022

Right, BifurcationKit wasn't available for the doc to build. I added it to the docs/Project.toml file.

@TorkelE
Copy link
Member Author

TorkelE commented Aug 2, 2022

Ok, some minor thing still needs fixing, will do that when I get home tonight.

@isaacsas
Copy link
Member

isaacsas commented Aug 2, 2022

Thanks for taking the time to make this dynamic. It will make it much easier to see when package updates, or Catalyst updates, break things going forward!

@TorkelE
Copy link
Member Author

TorkelE commented Aug 2, 2022

Think this is done now, unless something happens I'll merge by tomorrow.

J = (u,p) -> odefun.jac(u,p,0)
Next, we specify the system parameters for which we wish to plot the bifurcation diagram. We also set the parameter we wish to vary in our bifurcation diagram, as well as over which interval. Finally, we set which variable we wish to plot the steady state values of in the diagram.
```@example ex1
p = [:S=>1., :D=>9., :τ=>1000., :v0=>0.01, :v=>2., :K=>20., :n=>3, :d=>0.05]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you make this a Dict then won't your p_bstart calculation become trivial? ModelingToolkit should support Dicts for the mappings too.

@isaacsas
Copy link
Member

isaacsas commented Aug 3, 2022

Just the one comment, maybe make the parameter mapping a dictionary. I think it would simplify the tutorial since it would avoid having to use setindex! or findfirst (if I've understood what you are doing).

@TorkelE
Copy link
Member Author

TorkelE commented Aug 3, 2022

Generally I think that would make sense, however, when I do:

bprob = BifurcationProblem(F, oprob.u0, oprob.p, (@lens _[findfirst(first.(p).==bif_par)]); recordFromSolution = (x, p) -> x[findfirst(first.(u0).==plot_var)], J=J)

I must supply the index of the bifurcation parameter and plotting variable in the resulting array, and I am not sure how to do this robustly, nor if it is even possible.

@isaacsas
Copy link
Member

isaacsas commented Aug 3, 2022

You can use https://mtk.sciml.ai/dev/basics/FAQ/#Getting-the-index-for-a-symbol to see the recommended way to get a symbolic variable's index. For the species replace parameters(sys) with states(sys).

@TorkelE
Copy link
Member Author

TorkelE commented Aug 3, 2022

How to I access this function? I got the latest version of MTK, but trying indexof, ModelingToolkit.indexof, or similar all fails. (I also tried importing Symbolics and Catalyst and using these).

@isaacsas
Copy link
Member

isaacsas commented Aug 3, 2022

You have to define that function as in the FAQ. It isn't pre-defined by ModelingToolkit unfortunately.

@TorkelE
Copy link
Member Author

TorkelE commented Aug 3, 2022

Ahh, I understand.

@TorkelE
Copy link
Member Author

TorkelE commented Aug 3, 2022

Those seems to only work well if you actually have declared the vars/pars as symbolic. After some tinkering the best I got was:

indexof(sym,syms) = findfirst(isequal(sym),syms)
par_idx = indexof(:S,Symbol.(ModelingToolkit.parameters(rn)))
var_idx = indexof(:X,Symbol.(getfield.(ModelingToolkit.states(rn),:f)))

but I think this will just make things messier than what we already have.

@isaacsas
Copy link
Member

isaacsas commented Aug 3, 2022

Just @unpack the symbols from the system to load them as symbolic variables.

@isaacsas
Copy link
Member

isaacsas commented Aug 3, 2022

If you want I can update it to handle this part tonight?

@TorkelE
Copy link
Member Author

TorkelE commented Aug 3, 2022

That might be better, yeah, I am still unsure exactly how we want this. Loads of thanks!

@isaacsas isaacsas merged commit 33a988d into master Aug 4, 2022
@isaacsas isaacsas deleted the fix_bifurcation_tutorial branch August 4, 2022 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants