# 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.

`HomotopyContinuation.CoreTracker`

— Type.`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 1e`max_lost_digits`

.

The easiest way to construct a `CoreTracker`

:

`HomotopyContinuation.coretracker_startsolutions`

— Function.`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.

`HomotopyContinuation.coretracker`

— Function.`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.

**Examples**

**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)
end
```

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)
end
```

## Other types

` CoreTrackerResult{V<:AbstractVector}`

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`

.

`CoreTrackerStatus.states`

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`

`CoreTrackerOptions`

The set of options set for a `CoreTracker`

. See the description of `CoreTracker`

for all possible options.

## Methods

To track from a start to an endpoint with the `CoreTracker`

we provide the following routines.

`HomotopyContinuation.track`

— Function.`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.

`HomotopyContinuation.track!`

— Function.` 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.

`HomotopyContinuation.setup!`

— Function.`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`

.

`HomotopyContinuation.iterator`

— Function.`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).

**Example**

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:")
println(x)
end
```

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.

`HomotopyContinuation.current_x`

— Function.`current_x(tracker::CoreTracker)`

Return the current value of `x`

.

`HomotopyContinuation.current_t`

— Function.` current_t(tracker::CoreTracker)`

Current `t`

.

`HomotopyContinuation.current_Δt`

— Function.` current_Δt(tracker::CoreTracker)`

Current step_size `Δt`

.

`HomotopyContinuation.iters`

— Function.` iters(tracker::CoreTracker)`

Current number of iterations.

`HomotopyContinuation.status`

— Function.` status(tracker::CoreTracker)`

Current status.

`LinearAlgebra.cond`

— Method.`LinearAlgebra.cond(tracker::CoreTracker)`

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

`HomotopyContinuation.digits_lost`

— Function.`digits_lost(tracker::CoreTracker)`

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

`HomotopyContinuation.options`

— Function.`options(tracker::CoreTracker)`

Returns the options used in the tracker.

## Changing options

To change settings

`HomotopyContinuation.accuracy`

— Method.` accuracy(tracker::CoreTracker)`

Current accuracy.

`HomotopyContinuation.set_accuracy!`

— Function.` 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.

`HomotopyContinuation.max_corrector_iters`

— Function.` max_corrector_iters(tracker::CoreTracker)`

Current correction max_steps.

`HomotopyContinuation.set_max_corrector_iters!`

— Function.` set_max_corrector_iters!(tracker::CoreTracker, n)`

Set the correction max_steps to `n`

.

`HomotopyContinuation.max_step_size`

— Function.` max_step_size (tracker::CoreTracker)`

Current maximal step size.

`HomotopyContinuation.set_max_step_size!`

— Function.` set_max_corrector_iters!(tracker::CoreTracker, Δs)`

Set the maximal step size to `Δs`

.

`HomotopyContinuation.max_refinement_iters`

— Function.` max_refinement_iters(tracker::CoreTracker)`

Current refinement max_steps.

`HomotopyContinuation.set_max_refinement_iters!`

— Function.` set_max_refinement_iters!(tracker::CoreTracker, n)`

Set the current refinement max_steps to `n`

.

`HomotopyContinuation.refinement_accuracy`

— Function.` refinement_accuracy(tracker::CoreTracker)`

Current refinement accuracy.

`HomotopyContinuation.set_refinement_accuracy!`

— Function.` set_max_refinement_iters!(tracker::CoreTracker, accuracy)`

Set the current refinement accuracy to `accuracy`

.