Core Tracker

We also export the path tracking primitive to make the core path tracking routine available for other applications. At the heart is a CoreTracker object which holds all the state.

CoreTracker(problem::AbstractProblem, x₁; kwargs...)

Construct a CoreTracker from the given problem to track elements of type x₁. The path is tracked using a predictor-corrector scheme. The recommended methods to construct a CoreTracker are coretracker and coretracker_startsolutions. Note that a CoreTracker is also a (mutable) iterator.

Keyword arguments

  • accuracy=1e-7: The accuracy required during the path tracking.
  • corrector::AbstractCorrector: The corrector used during in the predictor-corrector scheme. The default is NewtonCorrector.
  • initial_step_size=0.1: The size of the first step.
  • max_corrector_iters=2: The maximal number of correction steps in a single step.
  • max_lost_digits::Real: The tracking is terminated if we estimate that we loose more than max_lost_digits in the linear algebra steps. This threshold depends on the precision argument.
  • max_refinement_iters=5: The maximal number of correction steps used to refine the final value.
  • max_steps=1_000: The maximal number of iterations the path tracker has available. Note that this changes to 10_000 for parameter homotopies.
  • max_step_size=Inf: The maximal step size.
  • min_step_size=1e-14: The minimal step size.
  • precision::PrecisionOption=PRECISION_FIXED_64: The precision used for evaluating the residual in Newton's method.
  • predictor::AbstractPredictor: The predictor used during in the predictor-corrector scheme. The default is Heun()`.
  • refinement_accuracy=1e-8: The precision required for the final value.
  • simple_step_size_alg=false: Use a more simple step size algorithm.
  • steps_jacobian_info_update::Int=1: Every n-th step a linear system will be solved using a QR factorization to obtain an estimate for the condition number of the Jacobian.
  • terminate_ill_conditioned::Bool=true: Indicates whether the path tracking should be terminated for ill-conditioned paths. A path is considerd ill-conditioned if the condition number of the Jacobian is larger than ≈1e14 or if it is larger than 1emax_lost_digits.

The easiest way to construct a CoreTracker:

coretracker_startsolutions(args...; kwargs...)

Construct a CoreTracker and startsolutions in the same way solve does it. This also takes the same input arguments as solve. This is convenient if you want to investigate single paths.

coretracker(args...; kwargs...)

Construct a CoreTracker in the same way solve does it. This also takes the same input arguments as solve with the exception that you do not need to specify startsolutions. This is convenient if you want to investigate single paths.


Obtain single solution

We want to construct a path tracker to track a parameterized system f with parameters p from the parameters a to b.

tracker = coretracker(f, parameters=p, p₁=a, p₀=b)

You then can obtain a single solution at b by using

x_b = track(tracker, x_a).x

Trace a path

To trace a path you can use the iterator method.

tracker = coretracker(f, parameters=p, p₁=a, p₀=b, max_step_size =0.01)
for (x, t) in iterator(tracker, x₁)
    @show (x,t)

If we want to guarantee smooth traces we can limit the maximal step size.

tracker = coretracker(f, parameters=p, p₁=a, p₀=b, max_step_size =0.01)
for (x, t) in iterator(tracker, x₁)
    @show (x,t)

Other types


Containing the result of a tracked path. The fields are

  • returncode::CoreTrackerStatus.states If the tracking was successfull then it is CoreTrackerStatus.success.
  • x::V The result.
  • t::ComplexF64 The t when the path tracker stopped.
  • accuracy::Float64: The estimated accuracy of x.

The possible states the coretracker can achieve are

  • CoreTrackerStatus.success
  • CoreTrackerStatus.tracking
  • CoreTrackerStatus.terminated_maximal_iterations
  • CoreTrackerStatus.terminated_invalid_startvalue
  • CoreTrackerStatus.terminated_step_size_too_small
  • CoreTrackerStatus.terminated_singularity
  • CoreTrackerStatus.terminated_ill_conditioned

The set of options set for a CoreTracker. See the description of CoreTracker for all possible options.


To track from a start to an endpoint with the CoreTracker we provide the following routines.

track(tracker, x₁, t₁=1.0, t₀=0.0; options...)::CoreTrackerResult

Track a value x₁ from t₁ to t₀ using the given CoreTracker tracker. This returns a CoreTrackerResult. This modifies tracker. See track! for the possible options.

 track!(tracker, x₁, t₁=1.0, t₀=0.0; setup_patch=true, checkstartvalue=true, loop::Bool=false)::CoreTrackerResult

Track a value x₁ from t₁ to t₀ using the given CoreTracker tracker. Returns one of the enum values of CoreTrackerStatus.states indicating the status. If the tracking was successfull it is CoreTrackerStatus.success. If setup_patch is true then setup! is called at the beginning of the tracking.

track!(x₀, tracker, x₁, t₁=1.0, t₀=0.0; options...)::CoreTrackerStatus.states

Additionally also stores the result in x₀ if the tracking was successfull.

setup!(::AbstractAffinePatchState, x::AbstractVector)

Setup the affine patch depending on x and modify x if necessary. This is only called once at the beginning of a tracked path.

setup!(cache::AbstractStatefulPredictorCache, H, x, ẋ, t, Jac)

Setup the cache. x is the new path value at t and is the derivative at t. fac is a factorization of the Jacobian at (x,t). This falls back to calling update.

setup!(coretracker, x₁, t₁=1.0, t₀=0.0, setup_patch=coretracker.options.update_patch, checkstartvalue=true, compute_ẋ=true)

Setup coretracker to track x₁ from t₁ to t₀. Use this if you want to use the coretracker as an iterator.

It is also possible to use a CoreTracker as an iterator. This can either be done by the high level iterator method or by directly using a CoreTracker as an iterator. The recommend approach is simply using iterator.

iterator(tracker::CoreTracker, x₁, t₁=1.0, t₀=0.0; affine=true)

Prepare a tracker to make it usable as a (stateful) iterator. Use this if you want to inspect a specific path. In each iteration the tuple (x,t) is returned. If affine == true then x is the affine solution (internally we compute in projective space).


Assume you have CoreTracker tracker and you wan to track x₁ from 1.0 to 0.25:

for (x,t) in iterator(tracker, x₁, 1.0, 0.25)
    println("x at t=$t:")

Note that this is a stateful iterator. You can still introspect the state of the tracker. For example to check whether the tracker was successfull (and did not terminate early due to some problem) you can do

println("Success: ", status(tracker) == CoreTrackerStatus.success)

Introspecting the current state

To introspect the current state we provide the following routines.


Return the current value of x.


Current t.


Current step_size Δt.


Current number of iterations.


Current status.


Returns the currently computed approximation of the condition number of the Jacobian.


Returns the currently computed approximation of the number of digits lost during the linear system solving in Newton's method.


Returns the options used in the tracker.

Changing options

To change settings


Current accuracy.

 set_accuracy!(tracker::CoreTracker, accuracy, update_max_lost_digits=true)

Set the current accuracy to accuracy. If update_max_lost_digits is true then the setting max_lost_digits will be updated to the default setting.


Current correction max_steps.

 set_max_corrector_iters!(tracker::CoreTracker, n)

Set the correction max_steps to n.

 max_step_size (tracker::CoreTracker)

Current maximal step size.

 set_max_corrector_iters!(tracker::CoreTracker, Δs)

Set the maximal step size to Δs.


Current refinement max_steps.

 set_max_refinement_iters!(tracker::CoreTracker, n)

Set the current refinement max_steps to n.


Current refinement accuracy.

 set_max_refinement_iters!(tracker::CoreTracker, accuracy)

Set the current refinement accuracy to accuracy.