API reference

The entries below document OED-owned APIs and OED-specific methods of shared functions. Re-exported Corleone and Symbolics APIs retain their own documentation. See the design guide for links to the shared Corleone manual. The shared optimization helpers include constraint_jacobian_sparsity and lagrangian_hessian_sparsity for supported shooting problems.

Measurements and layers

CorleoneOED.AbstractMeasurement — Type
abstract type AbstractMeasurement

A measurement specification with an identifier, schedule, and observation map observed(u, p, t). A map may return a scalar or a vector. All outputs of one measurement share its weight. Measurement weights are tunable parameters in [0, 1].

CorleoneOED.ContinuousMeasurement — Type
struct ContinuousMeasurement{T, F} <: CorleoneOED.AbstractMeasurement

Integrate information with a piecewise-constant measurement density. tpoints contains switching times; optional problem endpoints are removed when constructing intervals. There is one value per resulting interval, not per supplied point. An empty grid gives one density over the whole time span. Times must be finite, sorted, unique, and inside the problem span; validation occurs in OEDLayer.

At a switch, the density is right-continuous. All output rows of observed(u, p, t) share this density, and information is weighted linearly. Budgets integrate density by interval duration. Identifiers must be unique and distinct from model symbols; observation maps must accept symbolic inputs with a fixed scalar/vector output size.

Fields

  • id: The unique parameter symbol for this measurement's densities.

  • tpoints: Sorted density-switch times; optional problem endpoints are only interval boundaries.

  • observed: The symbolic-compatible map (u, p, t) -> y, with fixed scalar/vector output size.

CorleoneOED.DiscreteMeasurement — Type
struct DiscreteMeasurement{T, F} <: CorleoneOED.AbstractMeasurement

Observe at the exact, sorted tpoints. There is one weight per point, including any points at the initial and final time. tpoints must be nonempty, finite, unique, and within the problem span; validation occurs in OEDLayer. Information is linear in the weights: w * J'J, with one shared weight for every output row of observed(u, p, t). Identifiers must be unique and distinct from model symbols. Observation maps must accept symbolic inputs with a fixed output size.

Events are added to the saved grid. At a shooting reset, discrete information uses the last saved sample at that time, the outgoing/post-reset state. Discrete budgets sum event weights; weights between events do not create extra observations.

Fields

  • id: The unique parameter symbol for this measurement's weights.

  • tpoints: Sorted actual observation events; includes initial/final times only when supplied.

  • observed: The symbolic-compatible map (u, p, t) -> y, with fixed scalar/vector output size.

CorleoneOED.OEDLayer — Type
struct OEDLayer{L, P, M, I, B} <: LuxCore.AbstractLuxWrapperLayer{:shooting}

A shooting layer for local optimal experimental design. The augmented state holds physical states, parameter sensitivities, and the upper triangle of the continuous Fisher information matrix. Discrete observations are accumulated on demand.

Call OEDLayer(problem, algorithm, definitions...; params, measurements, kwargs...) or wrap an existing ShootingLayer. params defaults to every original physical parameter index and accepts a nonempty, unique sequence of indices or symbols. measurements is a tuple/collection of ContinuousMeasurement and/or DiscreteMeasurement specifications. Physical states and parameters must be vectors; the RHS and observations must accept symbolic inputs.

With the default fixed_parameters=nothing policy, unannotated physical parameters are fixed at their nominal values; explicit annotations select design variables. All measurement weights are tunable in [0, 1]. params selects the physical parameters whose sensitivities define the information matrix, independently of their tunability.

Lux parameters retain the shooting layer's layout. State additionally stores F_init, a prior information matrix, included once by fisher_information. Evaluation returns (trajectory, next_st) and preserves derivatives through current parameters and numerical state. Full physical-state shooting resets also lift the sensitivity and continuous-information states at interior full-state resets, with ordinary continuity constraints. Prescribed physical resets after the initial time are rejected because sensitivity jump maps are not provided.

svd=false uses the identity on params. With svd=true, ns selects the number of nominal singular-vector directions; otherwise threshold_singular_values=0.95 selects by cumulative squared singular values. threshold_singular_vectors=0.1 zeros rows whose retained entries are all at or below that magnitude. Both thresholds lie in [0,1); the resulting basis need not be orthonormal. See SVD reduction for the reference surrogate and approximation limits.

controls, quadratures, and bounds retain the root symbolic-metadata contracts; measurement weights are marked as controls automatically. ensemblealg selects the underlying shooting execution algorithm. fixed_parameters explicitly overrides the default fixed-index selection. Wrapping a ShootingLayer preserves its annotation schedules, initializers, bounds, and execution algorithm.

Trajectories reference the underlying shooting layer and the supplied parameter and state containers. Parameter histories are queried on demand: mutating those containers changes later parameter queries without recomputing saved states. Re-evaluate after a numerical change when both must describe the same experiment.

Fields

  • shooting: The augmented shooting layer used for execution and retained by trajectories.

  • augmented_prob: The augmented differential equation problem, shared with shooting.problem.

  • measurements: Discrete/continuous measurement specifications and numerical observation getters.

  • params: Original estimated physical parameter indices, in the requested coordinate order.

  • basis: The fixed length(params) × n_s direction basis; identity without SVD reduction.

CorleoneOED.MultiExperimentLayer — Type
struct MultiExperimentLayer{E, P, B} <: LuxCore.AbstractLuxContainerLayer{(:experiments,)}

Joint experimental design with independent Lux parameter/state trees per experiment. Local information matrices are embedded in common physical-parameter index order before summation. A global st.F_init is included once. SVD-reduced experiments contribute their information projected back through their fixed direction bases.

Construct from a tuple/NamedTuple of OED layers, or MultiExperimentLayer(oed, n). Different experiments must use the same meaning for each physical parameter index. Tuple inputs get names experiment_1, experiment_2, …; NamedTuples retain their names. n must be positive and the experiment collection must be nonempty.

Evaluation returns (named_trajectories, next_st). Parameters and state have named experiments subtrees; access them by getproperty. Iterating ComponentArrays instead yields numerical entries. Setup initializes independent numerical trees for repeated experiments, while the layer descriptions may be shared. Parameter buffers remain vector-based even though information is matrix-valued.

The global prior has size length(params) × length(params), in sorted union index order. Child priors are excluded from joint information. SVD embeddings project local reduced information into physical coordinates as an approximation; they do not recover discarded directions. See multiple experiments.

Fields

  • experiments: The OED layers, keyed by experiment name.

  • params: The union of physical parameter indices in information-matrix order.

  • embeddings: Fixed embeddings of local sensitivity directions into the common parameter axes.

Information and sampling

CorleoneOED.fisher_information — Function
fisher_information(oed, traj; add_initial)

Return an n_s × n_s information matrix from fisher_information(oed, trajectory) without another solve. Combine the terminal continuous contribution and discrete w * J'J event contributions. For a vector measurement, all rows share its weight. Discrete events use the last saved sample at their exact time (post-reset when both sides are saved). Missing saved event times raise ArgumentError.

Include the trajectory's current st.F_init once unless add_initial=false. Saved states and queried parameters must describe the same prediction: numerical parameter/state mutations after solving are visible to on-demand parameter queries. This function does not mutate the prior or trajectory.

fisher_information(layer, x, ps, st; add_initial=true) solves once and returns (F, next_st). For a MultiExperimentLayer, F uses the sorted union of estimated physical coordinates; local priors are excluded and the supplied global st.F_init is added once. Its size is length(layer.params) in each dimension. A single SVD-reduced experiment instead returns information in its n_s directions.

CorleoneOED.sensitivities — Function
sensitivities(oed, traj)

Return one n_x × n_s physical-state sensitivity matrix per saved augmented state, including both saved sides of shooting resets. Columns use oed.basis; without reduction they follow oed.params. These are sensitivities to estimated physical parameter directions, not AD derivatives with respect to design variables.

The trajectory form uses saved augmented states without solving. The four-argument form solves once and returns (matrices, next_st). Initial parameter sensitivities are zero; estimated initial-condition sensitivities are not included.

CorleoneOED.observed_equations — Function
observed_equations(oed, traj)

Return one flat observation vector per saved state, continuous measurements first and discrete measurements second, retaining declaration order within each kind. A vector-valued measurement contributes consecutive rows in its output order. Both saved sides of a reset are returned; this function does not select only the discrete events. Discrete information extraction selects their post-reset samples.

Evaluate observation maps with saved states and current, on-demand physical parameters. Keep the trajectory's parameter/state containers consistent with its saved states. The four-argument form solves once and returns (outputs, next_st).

CorleoneOED.sampling_sums — Function
sampling_sums(oed, traj)

Return sampling budgets, continuous measurements first and discrete measurements second. Continuous budgets are time integrals; discrete budgets are sums at measurement events. The four-argument form reads ps and st without solving the differential equation; its x argument is unused. The trajectory form reads its retained parameter/state containers. Multi-experiment budgets concatenate experiment order. Return one scalar per measurement, not per observation row.

CorleoneOED.sampling_sums! — Function
sampling_sums!(res, oed, args)

Write sampling_sums(layer, args...) into the prefix of res and return res. The buffer must have at least one entry per measurement; its remaining entries are unchanged. Throw DimensionMismatch for a shorter buffer. The buffer element type must accommodate the current numerical/AD values; the function does not solve when using the direct parameter/state form.

CorleoneOED.continuous_sampling_sums — Function
continuous_sampling_sums(oed, lookup, times)

Integrate each continuous measurement's piecewise-constant weight over the full problem time span. Pass a trajectory, or lookup(id, time) and the sorted interval boundaries covering the problem span. Return a vector in continuous declaration order; an empty continuous tuple returns an empty vector. Each interval uses its left endpoint's right-continuous weight. The trajectory form obtains boundaries from the current parameter schedule; neither form performs an ODE solve.

CorleoneOED.discrete_sampling_sums — Function
discrete_sampling_sums(oed, lookup)

Return the sum of the event weights for each discrete measurement. Pass a trajectory, or a callable lookup(id, time). Return a vector in discrete declaration order; an empty discrete measurement tuple returns an empty vector. Initial/final measurements contribute normally. The trajectory form queries current weights without another solve; values between the declared events do not contribute.

CorleoneOED.local_information_gain — Function
local_information_gain(oed, x, ps, st)

Solve once and return (gains, next_st). Each saved time contains the unweighted outer products J[i:i, :]' * J[i:i, :] of individual observation-sensitivity rows, continuous observations first, then discrete observations. These are per output row, even when several rows share one measurement weight. gains[k][i] is an n_s × n_s matrix for output row i at saved sample k. All saved times and both reset sides are included, not just discrete event times. Sum rows belonging to a vector measurement when interpreting its shared weight.

CorleoneOED.global_information_gain — Function
global_information_gain(oed, x, ps, st)

Solve once and return (gains, next_st). Each saved time contains per output-row matrices (J[i:i, :] * inv(F))' * (J[i:i, :] * inv(F)). Here F includes the prior and all continuous/discrete information and must be nonsingular. Their traces measure the magnitude of marginal improvement in A-optimality before interval/event weighting for symmetric information. Output nesting, row order, and reset-side behavior match local_information_gain; sum a vector measurement's rows for its shared weight. This uses current prior information and performs no additional solve after the single trajectory evaluation.

CorleoneOED.update_fim — Function
update_fim(oed, experiments, st)

Return state with the information from completed experiments added to F_init. Each experiment supplies ps and may supply its own st (otherwise use st). Existing priors are excluded from each experiment's contribution to avoid counting them repeatedly. The two-argument form starts from freshly initialized state. An empty collection returns the original state. Otherwise return a merged state without mutating the destination prior. Every supplied record is re-evaluated; keep the parameters and state used by that completed experiment. Single-experiment priors use its direction coordinates; multi-experiment priors use the sorted union of physical coordinates. Numerical records are not detached from AD.

Optimization facade

Corleone.CorleoneDynamicOptProblem — Method
CorleoneDynamicOptProblem(oed; ...)
CorleoneDynamicOptProblem(
    oed,
    criterion,
    constraints;
    ps,
    st,
    rng,
    M,
    lcons,
    ucons,
    kwargs...
)

Prepare an OED objective with the root optimization facade. User constraints follow Corleone's callback/expression and structured-bound conventions. Optional M adds one upper budget per measurement, continuous then discrete, before the automatic shooting equalities. Supply ps and st together to retain their current values. For a single experiment the prepared model stores its augmented ShootingLayer; for multiple experiments it stores the container. The objective computes information from the same trajectory without an additional solve and reads the current prior from the supplied state, not a prior captured at setup.

M must contain one nonnegative upper budget per measurement (not per observation row). Multiple experiments concatenate experiment order; within each experiment, continuous measurements precede discrete measurements. User constraint bounds follow Corleone's scalar/vector/in-place callback and structured subtree rules. Constraint order is user constraints, budgets, then automatic shooting equalities. Multi-experiment timed expressions are unsupported; use named-trajectory callbacks. Supply matching lcons/ucons for all user constraints.

Preparation predicts once to validate outputs and saved layout. Reprepare after changing schedules, saved layout, or constraint output sizes. This constructor needs neither Optimization.jl nor ComponentArrays.

SciMLBase.OptimizationProblem — Method
OptimizationProblem(
    layer,
    criterion;
    AD,
    vectorize,
    ps,
    st,
    rng,
    M,
    integer_weights,
    constraints,
    lcons,
    ucons,
    kwargs...
)

Prepare an OED model and use Corleone's SciMLBase optimization bridge. Optional M adds budgets in experiment order (continuous then discrete); shooting equalities follow user constraints and budgets. integer_weights=true marks measurement weights only and works with any vectorizer implementing pack. It requires an integer-capable solver; continuous solvers do not enforce binary decisions merely because a mask is present. Physical controls and shooting variables are excluded from the mask. Supply ps/st together, or omit both to run setup once.

AD=AutoForwardDiff() selects the default outer differentiation backend. pack(vectorize, parameters) must flatten parameters, variable bounds, and masks in the same order and reconstruct named access from the current optimizer vector. The default vectorizer requires Corleone's loaded ComponentArrays extension; a custom vectorize implementation does not. SciMLBase constructs the problem without importing Optimization.jl; a solver frontend is needed to solve it. Extra keywords go to the shared optimization bridge. See optimization and vectorization.

Criteria

CorleoneOED.AbstractCriterion — Type
abstract type AbstractCriterion

Interface for an optimal-design criterion.

Calling a criterion on an AbstractMatrix wraps it in Symmetric. Supply symmetric information; criteria do not regularize it or check positive definiteness. For a statistical covariance interpretation, positive-definite information is the relevant case. Inverse criteria require invertibility. See criteria for the exact definitions, which use neither logarithms nor dimension normalization.

Concrete criteria must implement (::MyCriterion)(F::Symmetric) and return a scalar objective from a Fisher information matrix. The generic layer method calls fisher_information(layer, x, ps, st) and returns (value, st) while preserving the updated layer state. Criteria are pure with respect to the matrix input and must not mutate the layer state.

Example

using CorleoneOED, LinearAlgebra
struct TraceCriterion <: AbstractCriterion end
(::TraceCriterion)(F::Symmetric) = tr(F)
CorleoneOED.ACriterion — Type
struct ACriterion <: CorleoneOED.AbstractCriterion

Minimizes $\operatorname{tr}(F^{-1})$. This is an A-optimality criterion and is defined for a nonsingular symmetric Fisher information matrix.

CorleoneOED.DCriterion — Type
struct DCriterion <: CorleoneOED.AbstractCriterion

Minimizes $\det(F^{-1})$ for a nonsingular symmetric Fisher information matrix.

CorleoneOED.ECriterion — Type
struct ECriterion <: CorleoneOED.AbstractCriterion

Minimizes the largest eigenvalue of $F^{-1}$ for a symmetric Fisher information matrix. It requires nonsingular information; repeated extreme eigenvalues can make the objective nondifferentiable.

CorleoneOED.FisherACriterion — Type
struct FisherACriterion <: CorleoneOED.AbstractCriterion

Maximizes $\operatorname{tr}(F)$ by minimizing its negative.

CorleoneOED.FisherDCriterion — Type
struct FisherDCriterion <: CorleoneOED.AbstractCriterion

Maximizes $\det(F)$ by minimizing its negative.

CorleoneOED.FisherECriterion — Type
struct FisherECriterion <: CorleoneOED.AbstractCriterion

Maximizes the smallest eigenvalue of F by minimizing its negative. Repeated smallest eigenvalues can make the objective nondifferentiable.