Non-simple branch point


The general method is exposed in Golubitsky, Martin, David G Schaeffer, and Ian Stewart. Singularities and Groups in Bifurcation Theory. New York: Springer-Verlag, 1985, VI.1.d page 295


An example of use of the methods presented here is provided in 2d generalized Bratu–Gelfand problem.

We expose our method to study non-simple branch points. Such branch point $(x_0,p_0)$ for the problem $F(x,p)=0$ satisfies $d=\dim \ker dF(x_0,p_0) > 1$ and the eigenvalues have zero imaginary part. At such point, we can apply Lyapunov-Schmidt reduction to transform the initial problem in large dimensions to a $d$-dimensional polynomial equation, called the reduced equation.

More precisely, it is possible to write $x = u + v$ where $u\in \ker dF(x_0,p_0)$ and $v\approx 0$ belongs to a vector space complement of $\ker dF(x_0,p_0)$. It can be shown that $u$ solves $\Phi(u,\delta p)=0$ with $\Phi(u,\delta p) = (I-\Pi)F(u+\psi(u,\delta p),p_0+\delta p)$ where $\psi$ is known implicitly and $\Pi$ is the spectral projector on $\ker dF(x_0,p_0)$. Fortunately, one can compute the Taylor expansion of $\Phi$ up to order 3. Computing the bifurcation diagram of this $d$-dimensional multivariate polynomials can be done using brute force methods.

Once the zeros of $\Phi$ have been located, we can use them as initial guess for continuation but for the original $F$ !!

Reduced equation computation

The reduced equation (E) can be automatically computed as follows

get_normal_form(br::ContResult, ind_bif::Int ; verbose = false, ζs = nothing, lens = getlens(br))

where prob is a bifurcation problem. br is a branch computed after a call to continuation with detection of bifurcation points enabled and ind_bif is the index of the bifurcation point on the branch br. The above call returns a point with information needed to compute the bifurcated branch. For more information about the optional parameters, we refer to get_normal_form. It returns a point with all requested information:

mutable struct NdBranchPoint{Tv, T, Tevl, Tevr, Tnf} <: BranchPoint
	"bifurcation point"

	"Parameter value at the bifurcation point"

	"Right eigenvectors"

	"Left eigenvectors"

	"Normal form coefficients"

	"Type of bifurcation point"

Using the reduced equation

Once a branch point has been computed bp = get_normal_form(...), you can do all sort of things.

  • For example, quoted from the file test/testNF.jl, you can print the 2d reduced equation as follows:
2-element Array{String,1}:
 " + (3.23 + 0.0im) * x1 * p + (-0.123 + 0.0im) * x1^3 + (-0.234 + 0.0im) * x1 * x2^2"
 " + (-0.456 + 0.0im) * x1^2 * x2 + (3.23 + 0.0im) * x2 * p + (-0.123 + 0.0im) * x2^3"
  • You can evaluate the reduced equation as bp2d(Val(:reducedForm), rand(2), 0.2). This can be used to find all the zeros of the reduced equation by sampling on a grid or using a general solver like Roots.jl.

  • Finally, given a $d$-dimensional vector $x$ and a parameter $\delta p$, you can have access to an initial guess $u$ (see above) by calling bp2d(rand(2), 0.1)

Branching from bifurcation point

It may happen that the general procedure fails. We thus expose the procedure multicontinuation in order to let the user tune it to its need.

The first step is to compute the reduced equation, say of the first bifurcation point in br.

bp = get_normal_form(br, 1)

Next, we want to find the zeros of the reduced equation. This is usually achieved by calling the predictor

pred = predictor(bp, δp)

which returns zeros of bp before and after the bifurcation point. You could also use your prefered procedure from Roots.jl (or other) to find the zeros of the polynomials bp(Val(:reducedForm), z, p).

We can use these zeros to form guesses to apply Newton for the full functional:

pts = BifurcationKit.getFirstPointsOnBranch(br, bp, pred, opts; δp =  δp)

We can then use this to continue the different branches

brbp = BifurcationKit.multicontinuation(br, bp, pts.before, pts.after, opts)