# Path tracking

We also export a path tracking primitive to make the core path tracking routine available for other applications. At the heart is a `PathTracker`

object which holds all the state. The easiest way to construct a `PathTracker`

is to use the `pathtracker_startsolutions`

routine.

`HomotopyContinuation.pathtracker_startsolutions`

— Function.`pathtracker_startsolutions(args...; kwargs...)`

Construct a `PathTracker`

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.pathtracker`

— Function.`pathtracker(args...; kwargs...)`

Construct a `PathTracker`

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 = pathtracker(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 = pathtracker(f, parameters=p, p₁=a, p₀=b)
for (x, t) in iterator(tracker, x₁)
@show (x,t)
end
```

## Types

`HomotopyContinuation.PathTracker`

— Type.` PathTracker(H::AbstractHomotopy, x₁, t₁, t₀; options...)::PathTracker`

Create a `PathTracker`

to track `x₁`

from `t₁`

to `t₀`

. The homotopy `H`

needs to be homogenous. Note that a `PathTracker`

is also a (mutable) iterator.

**PathTrackerOptions**

`corrector::AbstractCorrector`

: The corrector used during in the predictor-corrector scheme. The default is`Newton`

.`corrector_maxiters=3`

: The maximal number of correction steps in a single step.`initial_steplength=0.1`

: The step length of the first step.`maxiters=10_000`

: The maximal number of iterations the path tracker has available.`minimal_steplength=1e-14`

: The minimal step length.`predictor::AbstractPredictor`

: The predictor used during in the predictor-corrector scheme. The default is`[RK4`

](@ref)()`.`refinement_maxiters=corrector_maxiters`

: The maximal number of correction steps used to refine the final value.`refinement_tol=1e-8`

: The precision used to refine the final value.`tol=1e-7`

: The precision used to track a value.

` PathTrackerResult(tracker)`

Containing the result of a tracked path. The fields are

`successfull::Bool`

Indicating whether tracking was successfull.`returncode::PathTrackerStatus.states`

If the tracking was successfull then it is`PathTrackerStatus.success`

.`x::V`

The result.`t::Float64`

The`t`

when the path tracker stopped.

`PathTrackerStatus.states`

The possible states the pathtracker can achieve are

`PathTrackerStatus.success`

`PathTrackerStatus.tracking`

`PathTrackerStatus.terminated_maximal_iterations`

`PathTrackerStatus.terminated_invalid_startvalue`

`PathTrackerStatus.terminated_steplength_too_small`

`PathTrackerStatus.terminated_singularity`

## Methods

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

we provide the following routines.

`HomotopyContinuation.track`

— Function.`track(tracker, x₁, t₁=1.0, t₀=0.0; options...)::PathTrackerResult`

Track a value `x₁`

from `t₁`

to `t₀`

using the given `PathTracker`

`tracker`

. This returns a `PathTrackerResult`

. This modifies `tracker`

. See `track!`

for the possible options.

`track(tracker, x::AbstractVector, edge::Edge, loop::Loop, stats::MonodromyStatistics)`

Track `x`

along the edge `edge`

in the loop `loop`

using `tracker`

. Record statistics in `stats`

.

`HomotopyContinuation.track!`

— Function.` track!(tracker, x₁, t₁=1.0, t₀=0.0; setup_patch=true, checkstartvalue=true, compute_ẋ=true)`

Track a value `x₁`

from `t₁`

to `t₀`

using the given `PathTracker`

`tracker`

. Returns one of the enum values of `PathTrackerStatus.states`

indicating the status. If the tracking was successfull it is `PathTrackerStatus.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...)`

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, fac)`

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!(pathtracker, x₁, t₁=1.0, t₀=0.0, setup_patch=pathtracker.options.update_patch, checkstartvalue=true, compute_ẋ=true)`

Setup `pathtracker`

to track `x₁`

from `t₁`

to `t₀`

. Use this if you want to use the pathtracker as an iterator.

It is also possible to use a `PathTracker`

as an iterator. This can either be done by the high level `iterator`

method or by directly using a `PathTracker`

as an iterator. The recommend approach is simply using `iterator`

.

`HomotopyContinuation.iterator`

— Function.`iterator(tracker::PathTracker, 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 `PathTracker`

`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: ", currstatus(tracker) == PathTrackerStatus.success)`

## Introspecting the current state

To introspect the current state we provide the following routines.

`HomotopyContinuation.currx`

— Function.`currx(tracker::PathTracker)`

Return the current value of `x`

.

`HomotopyContinuation.currt`

— Function.` currt(tracker::PathTracker)`

Current `t`

.

`HomotopyContinuation.currΔt`

— Function.` currΔt(tracker::PathTracker)`

Current steplength `Δt`

.

`HomotopyContinuation.curriters`

— Function.` curriters(tracker::PathTracker)`

Current number of iterations.

`HomotopyContinuation.currstatus`

— Function.` currstatus(tracker::PathTracker)`

Current status.

## Changing options

To change settings

`HomotopyContinuation.tol`

— Function.` tol(tracker::PathTracker)`

Current tolerance.

`HomotopyContinuation.corrector_maxiters`

— Function.` corrector_maxiters(tracker::PathTracker)`

Current correction maxiters.

`HomotopyContinuation.refinement_tol`

— Function.` refinement_tol(tracker::PathTracker)`

Current refinement tolerance.

`HomotopyContinuation.refinement_maxiters`

— Function.` refinement_maxiters(tracker::PathTracker)`

Current refinement maxiters.

`HomotopyContinuation.set_tol!`

— Function.` set_tol!(tracker::PathTracker, tol)`

Set the current tolerance to `tol`

.

`HomotopyContinuation.set_corrector_maxiters!`

— Function.` set_corrector_maxiters!(tracker::PathTracker, n)`

Set the current correction maxiters to `n`

.

`HomotopyContinuation.set_refinement_tol!`

— Function.` set_refinement_maxiters!(tracker::PathTracker, tol)`

Set the current refinement tolerance to `tol`

.

`HomotopyContinuation.set_refinement_maxiters!`

— Function.` set_refinement_maxiters!(tracker::PathTracker, n)`

Set the current refinement maxiters to `n`

.