API Reference

Shooting layers

ShootingLayer returns (trajectory, state). Parameter switches and scheduled initial conditions split the solve into segments. Only active, non-fixed initial conditions at interior segment starts contribute matching residuals. Tunable global initial values are free; final-time assignments create no segment. See the shooting formulation, Parallel shooting for independent block execution and Automatic differentiation backends for tested gradient configurations. Segment boundaries are cached in st.timestops during setup and retained in the returned state. After changing a schedule, refresh the cache with st = merge(st, (; timestops = Corleone.get_timestops(layer, nothing, st))).

Corleone.ShootingLayer — Type
struct ShootingLayer{__T_name, __T_problem, __T_alg, __T_ensemblealg, __T_initialcondition, __T_parameter, __T_sys} <: LuxCore.AbstractLuxContainerLayer{(:initialcondition, :parameter)}

A Lux layer that solves a differential equation in segments separated by parameter switches and initial-condition resets. Calling with (input, ps, st) returns (trajectory, next_st), with reset residuals stored in trajectory.residuals. A tunable assignment at the global problem start is a free initial value and produces no matching residual. Active tunable interior assignments produce matching residuals; fixed resets do not. Assignments at the final time create no outgoing segment. A differential equation problem can be supplied as input; other inputs use the stored problem. A (problem, tstops) tuple supplies an explicit segment grid.

Segment boundaries are computed once during setup and stored in st.timestops. Forward calls reuse that vector and preserve it in the returned state. After changing a schedule, explicitly refresh the cached grid before solving; see get_timestops. For a replacement problem with a different time span, supply its matching grid through the (problem, tstops) call.

EnsembleSerial() solves sequentially. For ODE problems, EnsembleThreads() and EnsembleDistributed() solve independent blocks starting at interior full-state resets. Partial resets remain sequential within a block. Reverse-mode rules record block solves serially; ordinary forward execution uses the ensemble map.

Fields

  • name: The optional name of the shooting layer.

  • problem: The differential equation problem used when no replacement problem is supplied.

  • alg: The differential equation solver algorithm for each segment.

  • ensemblealg: The ensemble algorithm selecting serial, threaded, or distributed block execution.

  • initialcondition: Per-variable initial-condition layers and their reset schedules.

  • parameter: Per-parameter layers supplying parameter values for each segment.

  • sys: The ControlSymbolCache shared with trajectories for symbolic bookkeeping.

Corleone.ShootingLayer — Method
ShootingLayer(
    problem,
    alg,
    definitions;
    name,
    fixed_parameters,
    ensemblealg,
    controls,
    quadratures,
    bounds
)

Construct a shooting layer from a problem, solver, and annotation => timegrid definitions. Variable annotations define initial-condition resets; remaining definitions configure parameters. fixed_parameters selects parameters held in Lux state.

controls and quadratures select parameter and state subsets by symbol or original index. bounds maps symbols to bound pairs used as annotation defaults. Omitted metadata inherits from the problem cache; explicit annotation bounds take precedence. Metadata does not alter numerical state or parameter layouts.

Corleone.InitialConditions — Type
struct InitialConditions{__T_name, __T_repack, __T_initialconditions, __T_indices} <: LuxCore.AbstractLuxContainerLayer{(:initialconditions,)}

A collection of shared-grid InitialCondition layers, analogous to Parameter. Definitions are annotation => timegrid pairs; plain indices and symbols are also accepted as tunable annotations. Variables with no grid pass through their incoming values. Constant annotations store scheduled values in Lux state via FixedLayer.

Calling with (incoming_state, t) returns ((state, residuals), next_st). Residuals are assigned values minus the corresponding incoming values, in state index order. Only active, non-fixed layers contribute residuals. Set matching = false to apply assignments without producing matching residuals, as used for free initial values at the global problem start. The Boolean vector st.active is allocated during setup and reused on each call. Updating this scheduling metadata is non-differentiable; residual arithmetic is not.

Fields

  • name: The optional name of the initial-condition collection.

  • repack: Reconstructs the problem state from its canonical tunable values.

  • initialconditions: Shared-grid reset layers and pass-through layers, keyed by their first variable symbol.

  • indices: Original state indices represented by each reset or pass-through layer.

Corleone.InitialConditions — Method
InitialConditions(problem, definitions; name, sys)

Construct per-variable initial conditions from annotation => timegrid definitions. Annotations of kind Val(:variable) select state entries. Unspecified variables pass through their incoming values; Constant definitions store reset values in Lux state. sys supplies symbols, defaults, and annotation bounds.

Corleone.Parameter — Type
struct Parameter{__T_name, __T_repack, __T_parameters, __T_indices} <: LuxCore.AbstractLuxContainerLayer{(:parameters,)}

A collection of per-parameter piecewise-constant layers. Calling with (t, ps, st) returns the reconstructed problem parameters and updated Lux state. Fixed values are held in Lux state through FixedLayer.

Fields

  • name: The optional name of the parameter collection.

  • repack: Reconstructs the problem parameters from their canonical tunable values.

  • parameters: Shared-grid parameter layers, keyed by the first member's symbol.

  • indices: Original parameter indices represented by each shared-grid layer.

Corleone.Parameter — Method
Parameter(prob, raw_definitions; name, fixed, sys)

Construct parameter layers from annotation => timegrid definitions. Unspecified parameters receive one tunable value initialized from the problem. Constant annotations and entries selected by fixed store values in Lux state. sys supplies symbols, defaults, and annotation bounds.

Corleone.Tunable — Function
Tunable(
;
    index,
    sym,
    kind,
    default,
    lowerbound,
    upperbound,
    integer
)

Construct an annotation whose values are stored in Lux parameters. Supply an index or symbol, a vector of indices or symbols, a positional selector => default pair, or the index/sym keywords. Optional keywords are kind, default, lowerbound, upperbound, and integer. Missing metadata is resolved from the symbolic container.

Use kind = Val(:variable) for initial-condition resets and Val(:parameter) for parameter definitions. Pair the annotation with its time grid to define a layer.

default accepts a scalar, a vector, or a callback (rng, n::Int) -> values or (rng, times::AbstractVector) -> values. Untyped callbacks retain the count-based interpretation; the count signature wins if both are applicable. State defaults have one value per reset time, in supplied grid order. Parameter defaults have one value per interval; time-based callbacks receive [tspan[1]; switching_times]. A parameter without switching times has one value at tspan[1].

For vector selectors, supply one default per selector: a vector of scalars gives constant guesses, and a vector of vectors gives per-variable time series. Omitted defaults inherit metadata separately. Bounds may be shared scalars or per-selector vectors. Grouped annotations expand into scalar definitions before layer construction.

Scalar and vector bounds are checked when resolving annotations. Callback output length and bounds are checked during Lux setup. Vectors and callback results are retained by reference; use a callback that allocates when independent setup arrays are needed.

Corleone.Constant — Function
Constant(
;
    index,
    sym,
    kind,
    default,
    lowerbound,
    upperbound,
    integer
)

Construct a fixed-value annotation with the same selectors and metadata keywords as Tunable. Values are stored in Lux state through FixedLayer, and active fixed initial conditions do not contribute shooting residuals.

Corleone.Annotations — Function
Annotations(sys; kwargs...)

Read state and parameter metadata from a symbolic system. The ModelingToolkit extension returns (; variables, parameters), containing Tunable or Constant annotations with explicit indices, defaults, bounds and kinds. Load ModelingToolkit to use this constructor.

See Initializing shooting variables for scalar, vector, and count/timepoint callback defaults and helpers for existing parameter buffers.

Corleone.forward_initialization — Function
forward_initialization(rng, layer, ps, st; variables)

Omit ps and st to run LuxCore.setup(rng, layer) and return initialized (ps, st).

Initialize selected interior shooting values by a sequential solve using the current parameter schedule. Preserve assignments at the global start, fixed resets, and unselected tunable resets. At each selected reset, use the incoming solution value, including resets at the final time. Selected matching residuals then vanish up to solver accuracy.

Pass existing ps and st. variables selects original state indices. Work on private copies while solving, then validate bounds and update the existing ps buffers. Return ps; the supplied state and fixed values remain unchanged. This helper currently supports ODE problems and uses the layer's solver serially, regardless of its ensemble algorithm.

Corleone.linear_initialization — Function
linear_initialization(
    rng,
    layer,
    ps,
    st;
    u_infinity,
    u0,
    variables
)

Omit ps and st to run LuxCore.setup(rng, layer) and return initialized (ps, st).

Interpolate from u0 (default: the problem initial state) to the required u_infinity over the problem time span. Sample each variable's current reset grid from st. Endpoints are vectors, dictionaries, or collections of index => value pairs indexed by original variable. Update tunable ps buffers and return ps. variables selects state indices; fixed values are unchanged. Bounds are validated before writing.

Corleone.random_initialization — Function
random_initialization(rng, layer, ps, st; variables)

Omit ps and st to run LuxCore.setup(rng, layer) and return initialized (ps, st).

Sample each selected tunable shooting value uniformly within its variable bounds using rng. All selected bounds must be finite. variables selects original state indices. Update existing buffers and return ps; fixed values and st are unchanged. Use a seeded RNG for reproducible guesses.

Corleone.constant_initialization — Function
constant_initialization(rng, layer, ps, st; u0, variables)

Omit ps and st to run LuxCore.setup(rng, layer) and return initialized (ps, st).

Fill tunable shooting values in ps from u0, indexed by problem variable. u0 is a vector, dictionary, or collection of index => value pairs. Pass existing Lux parameters and state explicitly. variables selects original state indices; fixed and pass-through initial conditions are skipped. Return the same ps, with its existing buffers updated in place. Bounds are validated before writing.

Corleone.custom_initialization — Function
custom_initialization(rng, layer, ps, st; u0s, variables)

Omit ps and st to run LuxCore.setup(rng, layer) and return initialized (ps, st).

Set tunable shooting values from u0s, a dictionary, collection of index => values pairs, or another indexable collection. Values are vectors in each variable's reset-grid index order. variables defaults to dictionary keys, or all variables for other collections. Update existing ps buffers and return ps; fixed values and st are unchanged. All selected vectors must match their current schedules.

Corleone.hybrid_initialization — Function
hybrid_initialization(
    rng,
    layer,
    ps,
    st,
    methods;
    kwargs...
)

Omit ps and st to run LuxCore.setup(rng, layer) and return initialized (ps, st).

Apply variables => helper pairs sequentially to existing shooting parameters. Selectors are original state indices or collections of indices. Each helper is called as helper(rng, layer, ps, st; variables, kwargs...). Use closures to supply strategy-specific keywords when mixing methods. Later pairs override earlier assignments. Return the same ps. Fixed values are never selected by the built-in helpers. Failure of a later helper does not undo earlier successful updates.

Trajectories

Saved states and times are available as trajectory.u and trajectory.t, and initial-condition matching residuals as trajectory.residuals. Continuous segment handoffs are stored once; reset boundaries retain both sides, with trajectory.reset_indices pointing to the outgoing states. See the trajectory guide for an executable reset example and the distinction between state and parameter grids.

The trajectory retains the supplied layer, parameters, and Lux state by reference. Parameter queries evaluate layer.parameter using those objects. In-place changes to them affect subsequent parameter queries. Use SymbolicIndexingInterface.parameter_values_at_time(trajectory, trajectory, t) for values at a time, or getp(trajectory, symbol)(trajectory) for a parameter's history on its parameter-change grid.

Corleone.Trajectory — Type
struct Trajectory{__T_sys, __T_u, __T_t, __T_residuals, __T_reset_indices, __T_layer, __T_ps, __T_st}

Assemble saved segment solutions into a trajectory. Continuous handoffs occur once; initial-condition boundaries retain both the incoming endpoint and outgoing start, even when their states are equal. reset_indices indexes the outgoing samples.

Fields u and t contain the state samples and their times. residuals retains one initial-condition residual vector per segment start. The trajectory stores layer and its supplied Lux parameters ps and state st; parameter histories are evaluated on demand through layer.parameter, rather than stored separately. State samples are shared with the input solutions. Mutating ps or st changes subsequent parameter queries without recomputing the saved states. Run the layer again after changing parameters when both histories must describe the same prediction. Gradients through state values, residuals, and parameter values are supported on a fixed time grid; layout and symbolic metadata are not differentiated. The symbolic cache is shared with layer.sys and exposed through SymbolicIndexingInterface.symbolic_container. Query controls, quadrature states, and bounds on that ControlSymbolCache wrapper. No interpolation or integration is performed.

Fields

  • sys: The symbolic bookkeeping cache shared with the shooting layer.

  • u: Saved state samples, sharing their numerical arrays with the segment solutions.

  • t: The actual saved solution times, including both sides of reset boundaries.

  • residuals: State matching residual vectors per segment start; excludes on-demand parameter equalities.

  • reset_indices: Indices in u and t of outgoing samples at initial-condition reset boundaries.

  • layer: The shooting layer used to evaluate parameter values on demand.

  • ps: The supplied Lux parameters, retained by reference for parameter queries and AD.

  • st: The Lux state used for parameter queries, retained by reference for AD.

Corleone.Trajectory — Method
Trajectory(layer, ps, st, solutions, residuals)

Assemble saved segment solutions and residuals into a Trajectory. Remove duplicate samples at continuous handoffs while retaining both sides of initial-condition resets. Saved state arrays, parameters, and Lux state are shared.

Corleone.trajectoryplot — Function
trajectoryplot(trajectory; figure = (;), kwargs...)

Create a Makie figure displaying trajectory states, controls, and quadratures. Load Makie to activate this method. figure configures the figure; remaining keywords are passed to trajectoryplot!.

Corleone.trajectoryplot! — Function
trajectoryplot!(container, trajectory; skips = [], show_legend = true, kwargs...)

Add trajectory axes and optional legends to a Makie figure or layout position. skips excludes selected symbols. State, control, and quadrature axes share the time axis. Load Makie to activate this method; remaining keywords configure lines.

Symbolic bookkeeping

Retrieve the wrapper with SymbolicIndexingInterface.symbolic_container(trajectory) or SymbolicIndexingInterface.symbolic_container(layer). Control and quadrature queries are defined only on ControlSymbolCache; original state and parameter indices are preserved. See Symbolic bookkeeping.

Corleone.ControlSymbolCache — Type
struct ControlSymbolCache{__T_sys, __T_controls, __T_quadratures, __T_bounds}

Wrap a SymbolicIndexingInterface symbolic container with bookkeeping metadata. controls selects parameters; quadratures selects states that integrate running costs. Selections accept symbols or original indices. All symbols retain their original kind, index and ordering. Controls remain parameters.

bounds maps state or parameter symbols to (lower, upper) pairs. The parent container and supplied bounds dictionary are retained by reference, just as the parent's defaults are. Index-provider queries delegate through symbolic_container. A differential equation problem can also be supplied in place of sys.

Fields

  • sys: The original symbolic index provider, retained by reference.

  • controls: The subset of parameter symbols designated as controls.

  • quadratures: The subset of state symbols designated as running-cost integrals.

  • bounds: State and parameter symbols mapped to (lower, upper) bounds, retained by reference.

Corleone.ControlSymbolCache — Method
ControlSymbolCache(sys; controls, quadratures, bounds)

Construct a bookkeeping wrapper from a symbolic index provider. controls and quadratures accept symbols or original indices; bounds must be keyed by symbols. The parent and bounds dictionary are retained by reference. Passing an existing cache without overrides returns that same cache.

Corleone.default_bounds — Function
default_bounds(_)

Return the dictionary of default (lower, upper) bounds keyed by symbols. The fallback returns an empty dictionary; ControlSymbolCache returns its stored bounds dictionary by reference.

Corleone.get_bounds — Function
get_bounds(layer, ps)
get_bounds(layer, ps, st)

Return (get_lower_bound(layer, ps, st), get_upper_bound(layer, ps, st)). The returned trees follow the supplied parameter ordering and shapes; fixed data in Lux state is excluded. The two directional functions recursively traverse Lux containers, wrappers, and layer collections. Only ShootingLayer has a concrete layer specialization in Corleone, using its symbolic bounds metadata.

Pass initialized parameters explicitly. Native NamedTuple parameters and structured arrays such as ComponentArrays are supported; flatten all three trees with the same vectorization outside this API. st is optional. Flat optimizer vectors must be reconstructed before requesting bounds for a container layer.

get_bounds(cache, sym)

Return the stored (lower, upper) bound pair for sym, or (-Inf, Inf) when no bounds are stored for that symbol.

Internal layers and scheduling

These layers compose the public shooting layer. Their grids and activity masks live in Lux state and can be reused between evaluations.

Corleone.PassThrough — Type
struct PassThrough{__T_name} <: LuxCore.AbstractLuxLayer

A single-variable layer that returns the incoming value and Lux state unchanged. It has no trainable values or scheduled reset times.

Fields

  • name: The optional name of the state variable.
Corleone.InitialCondition — Type
struct InitialCondition{__T_name, __T_lookup, __T_parameter} <: LuxCore.AbstractLuxContainerLayer{(:lookup, :parameter)}

Reset values for one state variable or a group sharing the same exact-time lookup. Each scalar collection stores one value per entry in timegrid, initialized from a scalar, vector, or callback accepting (rng, n::Int) or (rng, times::AbstractVector). Count callbacks take precedence; time-based callbacks receive the grid in its supplied order. Calling with (incoming, t) returns (value, next_st): a stored value at an exact grid match, otherwise the incoming value promoted to the parameter scalar type. Single-variable layers accept a scalar; shared-grid groups accept a vector in group order. A nothing grid has no reset entries and allocates no trainable values.

Fields

  • name: The optional name of the state variable.

  • lookup: Exact-time lookup mapping each scheduled reset time to its value index.

  • parameter: A scalar parameter collection or NamedTuple of scalar collections sharing this reset grid.

Corleone.InitialCondition — Method
InitialCondition(timegrid, default; name, cache, bounds)

Construct reset values for one state variable on timegrid. default is a scalar, vector, or count/timepoint initializer as described by Tunable. Times must be unique; nothing selects an empty reset grid. cache is an optional lookup cache. Output length and bounds are checked during Lux setup.

Corleone.PiecewiseConstant — Type
struct PiecewiseConstant{__T_name, __T_lookup, __T_parameter} <: LuxCore.AbstractLuxContainerLayer{(:lookup, :parameter)}

One or more piecewise-constant parameters sharing a lookup. Lookup times separate intervals, so a grid of n switching times stores n + 1 values. A nothing grid stores one constant value. Calling with (t, ps, st) returns (value, next_st).

Fields

  • name: The optional name of the parameter.

  • lookup: The time lookup selecting a piecewise-constant interval.

  • parameter: A scalar parameter collection or NamedTuple of scalar collections sharing this grid.

Corleone.PiecewiseConstant — Method
PiecewiseConstant(
    timegrid,
    default;
    name,
    cache,
    initialization_times,
    bounds,
    kwargs...
)

Construct interval values on timegrid from a scalar, vector, or count/timepoint initializer as described by Tunable. Each switching time belongs to the following interval. Supply switching times in sorted order. A nothing grid creates one value. Time-based callbacks require initialization_times, one per interval; Parameter supplies the problem start followed by the switching times. cache optionally caches time lookups. Output length and bounds are checked during Lux setup.

Corleone.ParameterCollection — Type
struct ParameterCollection{__T_init_parameters, __T_out_dims} <: LuxCore.AbstractLuxLayer

A layer storing tunable values initialized during Lux setup.

Fields

  • init_parameters: The initializer called as init_parameters(rng, out_dims) during Lux setup.

  • out_dims: The number of stored parameter values.

Calling with (index, ps, st) returns (ps.ps[index], st).

Corleone.FixedLayer — Type
struct FixedLayer{__T_layer} <: LuxCore.AbstractLuxWrapperLayer{:layer}

A wrapper that stores the inner layer's parameters and state in Lux state. The wrapper has no trainable parameters. Calling it forwards its stored values to the inner layer and retains that layer's updated state.

Fields

  • layer: The inner layer whose parameters are held fixed in Lux state.
Corleone.LookUp — Type
struct LookUp{__T_collection, __T_cache} <: LuxCore.AbstractLuxLayer

A time-based lookup layer using lookup!. Its collection, optional cache, and inserted-index buffer are stored in Lux state during setup.

Fields

  • collection: The initial switching-time vector, exact-time dictionary, or nothing.

  • cache: The optional dictionary used to cache time lookups, or nothing.

Corleone.lookup! — Function
lookup!(cache, collection, key)

Look up the interval or entry for key, optionally caching the result.

  • cache is a cache for storing already looked up keys. In case of nothing the caching is skipped.
  • collection either an AbstractVector or AbstractDict used for the lookup
  • key the key.

If used with an AbstractVector and Number, lookup defaults to piecewise constant interpolation using searchsortedfirst(collection, key; lt = <=): a switching time belongs to the following interval. Dictionary lookup requires an exact key and returns typemax of its value type when absent. A nothing collection returns index 1.

Corleone.get_timestops — Function
get_timestops(layer, ps, st)
get_timestops(layer, ps, st, T)

Return sorted, unique segment boundaries from the problem time span and the initial-condition and parameter schedules in Lux state. Layer boundaries outside the problem time span are excluded. The result has element type T. Schedules are read exclusively from Lux state, so ps may be nothing. To refresh a layer's cached grid after changing schedules, use merge(st, (; timestops = get_timestops(layer, nothing, st))). Forward evaluation uses st.timestops directly rather than invoking this function.

Corleone.update_active_ics! — Function
update_active_ics!(active, initial_conditions, new_st)
update_active_ics!(
    active,
    initial_conditions,
    new_st,
    permutation
)

Update the preallocated residual activity mask from per-variable layers and their new Lux states. Only active, non-fixed initial conditions contribute residuals. This scheduling update is non-differentiable; an all-PassThrough tuple clears the mask without checking individual layers.

Corleone.terminal_state — Function
terminal_state(sol)

Return the final state from a time-series solution, a sequence of saved states, or a matrix whose columns are saved states. Supports solver and AD return formats.

Corleone.AbstractAnnotation — Type
abstract type AbstractAnnotation

Metadata for a state or parameter definition, including its selector, default, bounds, kind, and integrality. Concrete annotations are resolved against a symbolic index provider before numerical layers are constructed.

Corleone.DynamicVariable — Type
struct DynamicVariable{T, __T_index, __T_sym, __T_kind, __T_default, __T_lowerbound, __T_upperbound, __T_integer} <: Corleone.AbstractAnnotation

A state or parameter annotation. The type parameter T selects tunable (true) or fixed (false) values. Missing metadata is represented by nothing, except for the unknown kind Val(:unknown). Use Tunable or Constant to construct annotations.

Fields

  • index: The original state or parameter index, or nothing before resolution.

  • sym: The state or parameter symbol, or nothing before resolution.

  • kind: The annotation kind: Val(:variable), Val(:parameter), or Val(:unknown).

  • default: A scalar, vector, count/timepoint initializer, or nothing to inherit the symbolic default.

  • lowerbound: The lower bound, or nothing to inherit the symbolic bound.

  • upperbound: The upper bound, or nothing to inherit the symbolic bound.

  • integer: Whether the value is integer-valued, or nothing to inherit symbol metadata.

Corleone.update_annotation — Function
update_annotation(x, indep)

Resolve an annotation against symbolic index provider indep. Fill missing index, symbol, default, bounds, and integrality metadata. Reject unknown selectors, inconsistent symbol/index pairs, reversed bounds, and defaults outside bounds.

Deprecated constructor functions

These functions return native definitions and layers. See Deprecated constructors for the translation rules and unsupported legacy options.

Corleone.ControlParameter — Function
ControlParameter(t; name, controls, bounds)

Deprecated constructor for a piecewise-constant control. Return a Tunable(name; kind = Val(:parameter), ...) => switching_times definition. Legacy t contains the start of each control interval, so the first entry is removed from the returned switching grid. controls may be a vector, scalar, or legacy callback (rng, times, bounds) -> values. Callbacks run during Lux setup.

Scalar bounds and uniform bound vectors are supported. Nonuniform per-time bounds cannot be represented by the current annotation bounds and are rejected. Pass the returned definition directly to ShootingLayer, or use index => definition in a deprecated shooting constructor to select a parameter independently of name.

Corleone.SingleShootingLayer — Function
SingleShootingLayer(prob, alg; kwargs...)

Deprecated single-shooting constructor returning a ShootingLayer. Translate controls = [index => ControlParameter(...), ...], tunable_ic, bounds_ic, bounds_p, and quadrature_indices into native annotations and symbolic bookkeeping. Initial conditions in tunable_ic are tunable at the problem start; other initial conditions pass through problem.u0. Non-control parameters remain tunable. Extra keywords remake the differential equation problem.

The return value uses the new Lux parameter/state layout, with residuals in trajectory.residuals. Legacy whole-vector initialization callbacks are not supported; set annotation defaults using count or timepoint callbacks instead.

Corleone.MultipleShootingLayer — Function
MultipleShootingLayer(
    prob,
    alg,
    times;
    ensemble_alg,
    initialization,
    kwargs...
)

Deprecated multiple-shooting constructor returning a ShootingLayer. Accept a problem and algorithm, or an existing ShootingLayer, followed by shooting points as a vector or positional arguments. Every state, including quadratures, is lifted at interior shooting points. ensemble_alg selects block execution.

The returned layer uses the native per-variable parameter layout, free tunable initial values, and interior matching residuals. Parameters and controls remain shared across shooting blocks. Legacy stage-parameter/control lifting and whole-layer initialization callbacks are not restored; express initial guesses through annotation defaults instead.

Optimization-facing contracts

See Optimization-facing contracts for structured variable bounds, constraint ordering, and optimizer buffer requirements. The get_bounds methods are documented above with symbolic bookkeeping.

Corleone.get_lower_bound — Function

Return lower optimization bounds with the parameter layout and array shapes of ps. Containers and wrappers recurse using Lux's declared child fields; NamedTuple, Tuple and array collections recurse over their layers. Generic leaves have unbounded parameters (-Inf). Empty parameter subtrees remain empty.

ShootingLayer specializes this operation using its ControlSymbolCache, repeating each symbol's lower bound across its scheduled values. Other layers may specialize this function to supply their own bounds. Initialized parameters are supplied explicitly; no setup, RNG draws, initializers, or solves are performed. st is optional and is forwarded to child layers when supplied.

Corleone.get_upper_bound — Function

Return upper optimization bounds, following the same recursive layer and parameter structure as get_lower_bound. Generic leaves use Inf; ShootingLayer uses the upper bounds in its symbolic cache. No parameter initialization or solve is performed.

Corleone.get_number_of_shooting_constraints — Function
get_number_of_shooting_constraints(layer, ps, st)

Count scalar state and parameter matching residuals for the cached segment grid in st.timestops, without running the model. Each tunable initial condition contributes one residual at each matching segment start strictly after the global problem start. Assignments at the global start are free initial values. Each inserted interval of a tunable parameter adds one matching residual, counted once regardless of other segment boundaries within that interval. Original parameter switches, fixed assignments, and resets at the final endpoint contribute none.

The count uses scheduling metadata in Lux state; ps may be nothing. Refresh st.timestops after changing schedules, then recompute this count before allocating optimizer constraint buffers. This discrete metadata calculation is not differentiated.

Corleone.add_parameter_segments! — Function
add_parameter_segments!(layer, ps, st)

Split tunable parameter intervals at interior full-state resets and return updated (ps, st) for the same layer. New interval values duplicate the previously active value. Their right-hand interval indices are recorded in st's per-parameter lookup.inserted vectors, for subsequent parameter matching constraints.

Existing parameter switches remain unconstrained, and fixed parameters are unchanged. Repeated calls do not insert additional entries. The input arrays and layer are retained unchanged; changed parameter arrays and lookup grids are newly allocated, and affected lookup caches are cleared. Segment boundaries are read from the current initial-condition schedules and the stored problem span; the returned state's cached timestops are refreshed. No solve, initialization, or constraint construction occurs.

The layer's setup dimensions remain unchanged. Use the returned parameters to size optimizer storage and query bounds; calling setup again restores the original layout.

Corleone.shooting_constraints — Function
shooting_constraints(trajectory)

Return scalar state matching residuals followed by parameter matching residuals. State residuals use chronological segment order, with variables in canonical state index order within each segment. The values are assigned states minus incoming states, as stored in trajectory.residuals. Parameter residuals are computed on demand from the stored layer, parameters, and state. Each inserted right-hand interval index i contributes values[i] - values[i - 1], in canonical parameter order and then increasing index. Original parameter switches and fixed assignments do not contribute residuals.

These are equality-constraint values; matching constraint bounds are zero. Numerical derivatives flow through the residual values. Use shooting_constraints! to write directly into an existing optimizer buffer.

Corleone.shooting_constraints! — Function
shooting_constraints!(res, trajectory)

Write shooting_constraints into res in the same order and return res. The buffer length must equal the total number of scalar residuals; otherwise throw DimensionMismatch before writing. This avoids allocating an intermediate flattened vector. The buffer's element type must support the residual values, including AD number types. Backends that do not support array mutation should use the allocating shooting_constraints form instead.

Prepared optimization facade

The core model evaluates trajectory callbacks and symbolic selectors without an optimizer dependency. SciMLBase constructs OptimizationFunction/OptimizationProblem; ComponentArrays supplies the default packing implementation. See Prepared optimization models.

Corleone.CorleoneDynamicOptProblem — Type
struct CorleoneDynamicOptProblem{L, O, C, P, S, T, G, B, V, LB, UB}

Prepare CorleoneDynamicOptProblem(layer, objective, constraints...; lcons, ucons, ps, st, rng, eval_module). The objective is a scalar trajectory callback f(prediction) or f(prediction, st), a Julia Expr, or a terminal state/parameter selector. Omitting it sums terminal quadratures.

Callback-based Lux layers may return a collection of trajectories. Timed expressions and terminal selectors require a ShootingLayer.

Each constraint is a scalar/vector callback f(traj), an in-place callback f!(res, traj) whose return is ignored, or a numerical Julia expression. Supply lcons and ucons with matching structure and one top-level entry per constraint: [0.0, [0.0, 0.0], 0.0] declares output sizes (1, 2, 1). With a single constraint, a flat bound vector is also accepted. Bounds are flattened in declaration order; state and parameter shooting equalities are appended automatically with zero bounds.

Timed signal calls such as :(u₁(10.0) + p₁(5.0)) collect their timepoints during setup. Prediction uses the union of these points and st.timestops. Expressions are compiled against the actual saved grid, including internal saveat samples. A timed reset query selects the post-reset state; parameters are right-continuous. Bare signal names within expressions denote their full series on that saved grid. Constraint comparisons are not parsed: use numerical expressions and lcons/ucons.

eval_module resolves ordinary expression functions and constants (default: Corleone, including Base functions). Pass your own module for custom helpers. Signal times must be real literals within the time span; interpolate computed times. SymbolicUtils parsing is deferred. evaluator = default_evaluator() selects the loaded RuntimeGeneratedFunctions extension, with eval as the built-in fallback.

Supply ps/st together to retain them by reference, including expanded parameter intervals. Otherwise setup runs once. One initial prediction validates outputs and prepares indices; its numerical solution is not retained. Reprepare after changing schedules, saved layout, or output dimensions. Load ComponentArrays for the default SciMLBase optimization bridge, or supply another packing implementation.

Fields

  • layer: The Lux layer shared with forward predictions.

  • objective: The scalar objective callback or prepared expression/terminal selector.

  • constraints: Prepared constraint evaluators in declaration order.

  • ps: Initialized numerical parameters, retained by reference.

  • st: Initialized Lux state, retained by reference.

  • timepoints: Signal names mapped to requested expression times; discrete setup metadata.

  • evaluation_grid: The evaluation grid, or nothing when prediction uses the layer's own grids.

  • source_timestops: The original cached shooting-stop tree used to detect schedule changes.

  • times: The actual saved prediction grid or grid tree, retained for layout checks.

  • lcons: Flattened user lower bounds followed by shooting equality bounds.

  • ucons: Flattened user upper bounds followed by shooting equality bounds.

  • nshooting: The prepared number of state and parameter shooting equalities.

Corleone.optimization_objective — Function
optimization_objective(prob)
optimization_objective(prob, ps)
optimization_objective(prob, ps, st)

Solve once on the prepared evaluation grid and evaluate the scalar objective. Parameters/state default to those retained by the model. No numerical solution cache is shared between calls or AD contexts.

Corleone.optimization_constraints — Function
optimization_constraints(prob)
optimization_constraints(prob, ps)
optimization_constraints(prob, ps, st)

Solve once and concatenate constraint outputs, followed by shooting equalities. Out-of-place callbacks and compiled expressions support mutation-free reverse AD. An in-place callback is evaluated into a fresh, appropriately typed buffer; its AD support depends on the callback and backend's support for mutation.

Corleone.optimization_constraints! — Function
optimization_constraints!(res, prob)
optimization_constraints!(res, prob, ps)
optimization_constraints!(res, prob, ps, st)

Write constraints into res in declaration order, followed by shooting equalities. Check total length before solving/writing. In-place user callbacks receive their own output slice directly; their return values are ignored. The buffer must support the current numerical scalar type, including AD values.

Corleone.constraint_jacobian_sparsity — Function
constraint_jacobian_sparsity(prob; vectorize, ps, st)

Return a conservative sparse Boolean constraint Jacobian pattern for a prepared ODE shooting problem. Columns follow pack(vectorize, ps); rows follow optimization_constraints. Parsed Expr constraints (including lowered MTK constraints) use their referenced state/time and parameter/time dependencies. Literal vectors retain separate dependencies per component; other vector-valued expressions use their combined dependencies. Arbitrary callback rows are dense. Shooting rows propagate all state dependencies within each integration segment, replace them at scheduled resets, and include active tunable parameters. Fixed resets erase state dependencies; partial resets retain dependencies of the other states. Inserted parameter equalities have two entries each.

The pattern describes a fixed schedule and parameter layout. Rebuild it after changing either. This computes structural metadata without solving or tracing through the ODE solver. Dependencies of fixed numerical values in st are excluded because the Jacobian differentiates only ps.

Corleone.lagrangian_hessian_sparsity — Function
lagrangian_hessian_sparsity(prob; vectorize, ps, st)

Return a conservative symmetric Boolean sparsity pattern for the Lagrangian Hessian σ * ∇²objective + sum(λ[i] * ∇²constraint[i]), including the objective when there are no constraints. Columns and rows follow pack(vectorize, ps). The pattern is independent of the current objective factor and multipliers.

Parsed expressions (including lowered MTK expressions) conservatively couple all parameter columns on which each output depends. This covers general nonlinear operations and curvature introduced by the ODE solution without differentiating expression syntax. Unknown callbacks conservatively couple all columns. This is a structural superset, not symbolic second differentiation. State matching rows use their incoming solution dependencies; the assigned lifted value is affine. Parameter matching equalities are affine and add no entries.

Supports prepared ODE ShootingLayer models. Rebuild after schedule or layout changes. Load OptimizationBase to obtain its canonical upper-triangle coordinates with OptimizationBase.lag_hess_structure(prob; vectorize, ps, st). This helper supplies structure only. Use sparse_hessian=true when constructing OptimizationFunction/OptimizationProblem to prepare numerical Hessian callbacks.

Corleone.pack — Function
pack(extension::Val, ps) -> q0, reconstruct

Prepare flat real optimizer storage and a callable restoring named parameter access. reconstruct(q) must use the current vector's numerical values and scalar type; its result may be a ComponentArray, NamedTuple, or another parameter container. Each implementation must pack parameters and their bounds in the same order.

Load ComponentArrays for Val(:ComponentArrays). It returns the ComponentVector's backing array and a callable retaining only its axes. Calling that object wraps any compatible vector in a ComponentArray without copying numeric values. Packing a NamedTuple allocates flat storage once; packing an existing ComponentVector reuses its backing storage.

Corleone.default_vectorizer — Function
default_vectorizer()

Select a loaded parameter vectorization extension. Currently returns Val(:ComponentArrays) when the ComponentArrays extension is loaded. If no supported extension is loaded, throw UndefKeywordError(:vectorize).

Load ComponentArrays to enable the default, or supply vectorize explicitly to OptimizationFunction/OptimizationProblem using an implementation of pack.

Corleone.default_evaluator — Function
default_evaluator()

Select Val(:RuntimeGeneratedFunctions) when its extension is loaded, otherwise return Val(:Eval). An explicit evaluator keyword overrides this selection.

Corleone.compile_evaluator — Function
compile_evaluator(strategy::Val, expression::Expr, eval_module::Module)

Compile a one-argument lambda expression into a numerical callable. Val(:Eval) uses Core.eval in eval_module and calls the resulting function in its latest world. The RuntimeGeneratedFunctions extension implements Val(:RuntimeGeneratedFunctions). Parsing and index substitution are shared by both implementations.

SciMLBase.OptimizationFunction — Method
OptimizationFunction(
    prob,
    ad;
    vectorize,
    ps,
    st,
    inplace,
    sparse_constraints,
    sparse_hessian,
    kwargs...
)

Build typed optimizer callbacks using the reconstruction callable returned by pack. inplace = true uses the buffer-writing constraint callback; false uses the allocating form and out-of-place derivative convention. Additional keywords configure function/derivative options. sparse_constraints = true prepares a colored sparse constraint Jacobian when DifferentiationInterface and SparseMatrixColorings are loaded. sparse_hessian = true prepares colored objective and Lagrangian Hessian callbacks. Both require inplace = true; the Hessian option additionally requires second-order support from ad. Initialization and layout preparation are not repeated. The vectorize keyword selects the packing implementation. Its default is default_vectorizer, which requires a loaded supported extension. Other implementations may be supplied explicitly through vectorize.

SciMLBase.OptimizationProblem — Method
OptimizationProblem(
    prob,
    ad;
    vectorize,
    ps,
    st,
    inplace,
    sparse_constraints,
    sparse_hessian,
    function_kwargs,
    kwargs...
)

Build a SciMLBase OptimizationProblem with vectorize = default_vectorizer(), flattened Lux parameters, matching symbolic bounds, and prepared user/shooting constraints. Use supplied ps/st or the model's retained values. The packing implementation controls storage and reconstruction; the default ComponentArrays implementation uses flat numerical storage and restores ComponentArray axes around the current optimizer input without copying values. function_kwargs configures OptimizationFunction. sparse_constraints = true prepares only the constraint Jacobian sparsely; objective differentiation retains ad. Load DifferentiationInterface and SparseMatrixColorings to enable it. sparse_hessian = true additionally prepares exact objective and Lagrangian Hessians with structural coloring; ad must support second differentiation. Remaining keywords are forwarded to OptimizationProblem.

SciMLBase.OptimizationProblem — Method
OptimizationProblem(
    layer,
    ad;
    vectorize,
    loss,
    constraints,
    ps,
    st,
    lcons,
    ucons,
    eval_module,
    evaluator,
    rng,
    kwargs...
)

Prepare a CorleoneDynamicOptProblem and construct its SciMLBase OptimizationProblem in one call. Setup runs only when neither ps nor st is supplied. loss, constraints, and initialization options follow the core model constructor.