I have accumulated, over the last years, some methods for performing pseudo-arclength continuation of solutions of PDE or large scale problems. I decided to package these methods and release it publicly in case others find it useful. I tried my best to write something customizable where one can easily specify a custom linear solver (GMRES, , \ on GPU…) and eigen solver to adapt the method to the specificity of the problem under study. It works reasonably well although I was not very careful about allocations (premature optimization is...)

So the package can perform continuation of solutions, detection of codim 1 bifurcation (Branch point, Fold point, Hopf point) and continue them as function of another parameter. In the context of matrix free methods, there aren’t so many codes which does this (pde2path, trilinos, ?)

I did not implement branch switching because I could not be bothered implementing the different normal forms (PR suggested ) BUT I implemented a very powerful method described by P Farrell which largely makes up for this and allows you to discover many more solutions than with branch switching.

Finally, I also provide some methods for computing periodic orbits and continuation of them. There are Matrix Free methods and one suitable for Sparse problems.

I did my best not to rely on AbstractVector so one can use Matrices as a state space, or use ApproxFun or ArrayFire…

Please have a look at PseudoArcLengthContinuation.jl and at the examples. Feel free to suggest improvements, design choices and submit PR

This looks amazing! Can we get this setup so it can handle ODEProblem/SteadyStateProblem inputs? We can link over to this in the DiffEq docs for bifurcation analysis.

Sure! You only need to provide the vector field and the jacobian (compute with AD in your package) to my package. It should be relatively easy. You can even pass “your” linearsolvers to the continuation function.

Looks fantastic! You beat me to producing a package on this (looking at my current work rate, probably by a few years…). I look forward playing around with it!

I’ve only had a brief look at your code (looks pretty clean ) but it looks like each problem (regular continuation versus fold continuation, etc) is implemented quite discretely, that is, it’s not possible to easily compose different problems. For example, to track a periodic orbit and an equilibrium state at the same time (e.g., a homoclinic problem). Is that the case?

I’ve been looking at developing something that is composable, along the lines of COCO (Matlab-based), since Julia seems ideal for such things but, again, time has got the better of me.

You are right, there is design tension for now and I hope it will be solved later. For now, I focused on something that works but is less elegant than what you suggest.

For example, I should call newton on [F, N] where N is the arclength constraint to perform continuation but I call a specific solver newtonPsArcLength for now which does not rely on newton.

It is on my todo list to provide a way to combine functionals. I thought about providing a way of appending functionals (and Jacobian ) like when you want to specify a phase condition. I have a newtonBordered function which does this but it is not pushed.

This said, in Julia it is very simple to do what you suggest. For example, I would “loosely” give to newton a function like (uper,u) -> BorderedVector(poPb(uper) , F(u)) where the problem for Periodic orbit is encoded here.

I suggest using Setfield.Lens for specifying the bifurcation parameters. It’s a very handy way to make virtually any Julia object “differentiable” using ForwardDiff. Or maybe I can just pull out that part from my code.

As for the heteroclinic orbits, I still have to improve the case of periodic orbits first. Right now, it works but it is not the best way to do this in large dimensions. Although there are some more urgent to do on my README…

Thank you for the suggestion about Lens

As for Bifurcations.jl, I am sorry but I did not noticed this before. It looks GREAT. You should make an announcement on discourse to make it known. Also, you should add a link to your docs on your README. I thought in Julia, we ``only’’ had PyDSTool.jl but we now have a serious work for ODE written in Julia.

I do think there is room for multiple packages doing the same thing. My goal is to do PDE where the problem is (partly) to perform linear solves efficiently. In ODE, you can do all sort of things that are impossible for PDEs. So we can have a specialized package for this. It would be possible to do it with my package by specialising the linear solves for example but we have Bifurcations.jl…

But we should definitely get these two packages setup to take a problem type in, and flesh them out as the options in the bifurcations page. PyDSTool isn’t that great so there’s no reason it should stay front and center in our docs

Thanks! Well, it’s my fault not advertising it I was kind of hiding it since there are tons of things I wanted to fix. (And then I caught up in something else…) Anyway, I added a link to the docs in Github.

Yeah, my main usecase is for (low dimensional) ODE. I’d imagine continuation in PDE is a much harder beast.

The first concerns the computation of periodic orbits for systems where the Jacobian can be expressed with a sparse matrix. The issue in the code was a slow conversion from BlockArray to a sparse matrix. This has been fixed by the function blockToSparsehere, see issue and quick answer by @dlfivefifty . This allows to study much larger PDE problems and compute associated periodic orbits. The third example in the docs shows an application.

The second improvement allows the computation of branches entirely on the GPU using Matrix-Free methods thanks to KrylovKit.jl !!
I have to thank @juthohaegeman for his help on this issue. Hence, I propose another example described in the docs where I show how to do this for a nontrivial problem.

I hope you will find it useful,

If you think you can improve my code, advice me… do not hesitate!