Skip to content

Optimization¤

The optimizers that solve constrained form-finding problems, plus recorders to replay an optimization history.

Base optimizers¤

Optimizer ¤

Optimizer(disp: bool = False, **kwargs: Any)

The base class for optimizers backed by scipy.optimize.minimize.

Parameters:

  • disp (bool, default: False ) –

    Whether the SciPy backend prints its own console output. Off by default since jax_fdm prints its own progress.

Notes

Subclasses set name to their SciPy method identity and override the gradient, hessian, constraint, or minimization hooks as needed. problem assembles the objective, its gradient, bounds, and goal collections into an OptProblem, which solve then minimizes.

pm property writable ¤

The parameter manager, set up by problem() before a solve.

loads_static property writable ¤

loads_static: LoadsStatic

The static edge and face loads, set up by problem() before a solve.

constraints ¤

constraints(constraints: Sequence[Constraint], model: EquilibriumModel, structure: EquilibriumStructure, params_opt: Float[Array, parameters]) -> list[Any] | None

Convert constraints into the form the SciPy backend expects.

Parameters:

  • constraints (Sequence[Constraint]) –

    The constraints to convert.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure the constraints are defined on.

  • params_opt (Float[Array, parameters]) –

    The initial optimization parameters.

Returns:

  • constraints ( list[Any] | None ) –

    The converted constraints. The base optimizer supports none, so it warns and returns None.

gradient ¤

gradient(loss: Callable) -> Callable

Build the jitted gradient of a loss function.

Parameters:

  • loss (Callable) –

    The loss function to differentiate.

Returns:

  • gradient ( Callable ) –

    The jitted gradient with respect to the optimization parameters.

hessian ¤

hessian(loss: Callable) -> Callable | None

Build the hessian of a loss function.

Parameters:

  • loss (Callable) –

    The loss function to differentiate twice.

Returns:

  • hessian ( Callable | None ) –

    The hessian function, or None. The base optimizer provides none; second-order optimizers override this.

loss ¤

loss(params_opt: Float[Array, parameters], loss: Loss, model: EquilibriumModel, structure: EquilibriumStructure) -> Float[Array, '']

Evaluate the loss from a flat optimization parameter vector.

Parameters:

  • params_opt (Float[Array, parameters]) –

    The flat optimization parameter vector.

  • loss (Loss) –

    The loss function to evaluate.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure that provides the connectivity.

Returns:

  • loss ( Float[Array, ''] ) –

    The scalar loss value.

Notes

Expands the optimization vector into FDM parameters before calling the loss, so the optimizer can work in the reduced parameter space.

goals ¤

goals(loss: Loss, model: EquilibriumModel, structure: EquilibriumStructure) -> None

Collect and bind the loss's goals to a structure ahead of the solve.

Parameters:

  • loss (Loss) –

    The loss function whose error terms hold the goals.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure the goals are bound to.

Notes

Goals are batched into collections; each collection resolves its own index against the structure inside the jitted objective, once at trace time.

problem ¤

problem(model: EquilibriumModel, structure: EquilibriumStructure, datastructure: FDNetwork | FDMesh, loss: Loss, parameters: Sequence[Parameter] | None = None, constraints: Sequence[Constraint] | None = None, maxiter: int = 100, tol: float = 1e-06, callback: Callable | None = None, jit_fn: bool = True) -> OptProblem

Assemble an optimization problem from a model, loss, and parameters.

Parameters:

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure that provides the connectivity.

  • datastructure (FDNetwork | FDMesh) –

    The network or mesh being optimized.

  • loss (Loss) –

    The loss function to minimize.

  • parameters (Sequence[Parameter] | None, default: None ) –

    The optimization parameters. If None, every edge force density is used.

  • constraints (Sequence[Constraint] | None, default: None ) –

    The constraints to enforce. If None, the problem is unconstrained.

  • maxiter (int, default: 100 ) –

    The maximum number of optimizer iterations.

  • tol (float, default: 1e-06 ) –

    The convergence tolerance.

  • callback (Callable | None, default: None ) –

    A function invoked once per iteration.

  • jit_fn (bool, default: True ) –

    Whether to just-in-time compile the objective and hessian.

Returns:

  • problem ( OptProblem ) –

    The assembled optimization problem.

Notes

Warms up the compiled objective once and asserts the gradient is nan-free before returning, so compilation cost and gradient bugs surface up front.

options ¤

options(extra: dict[str, Any] | None = None) -> dict[str, Any]

Assemble the backend options dictionary.

Parameters:

  • extra (dict[str, Any] | None, default: None ) –

    Extra options to merge in, such as maxiter. None-valued entries are skipped.

Returns:

  • options ( dict[str, Any] ) –

    The options dictionary, always carrying the disp flag.

Raises:

  • ValueError

    If extra is given but is not a dictionary.

solve ¤

solve(opt_problem: OptProblem) -> Float[Array, parameters]

Minimize an assembled optimization problem.

Parameters:

  • opt_problem (OptProblem) –

    The problem to minimize.

Returns:

  • params_opt ( Float[Array, parameters] ) –

    The optimized parameter vector.

Notes

Also stores the full SciPy result on self.result and prints the final loss, gradient norm, and iteration counts.

parameters_bounds ¤

parameters_bounds() -> Bounds | list[tuple[float, float]]

Return the lower and upper bounds of the optimization parameters.

Most backends consume a scipy Bounds object; IPOPT overrides this to return a list of (low, high) pairs instead.

parameters_value ¤

parameters_value() -> Float[Array, parameters]

Return the initial values of the optimization parameters.

Returns:

  • values ( Float[Array, parameters] ) –

    The flat initial optimization parameter vector.

parameters_fdm ¤

parameters_fdm(params_opt: Float[Array, parameters]) -> EquilibriumParametersState

Expand optimization parameters into a full FDM parameter state.

Parameters:

  • params_opt (Float[Array, parameters]) –

    The flat optimization parameter vector.

Returns:

  • params_state ( EquilibriumParametersState ) –

    The force densities, fixed coordinates, and loads, with the static edge and face loads restored.

ConstrainedOptimizer ¤

ConstrainedOptimizer(disp: bool = False, **kwargs: Any)

A gradient-based optimizer that handles constraints.

constraints ¤

constraints(constraints: Sequence[Constraint], model: EquilibriumModel, structure: EquilibriumStructure, params_opt: Float[Array, parameters]) -> list[Any] | None

Convert constraints into SciPy NonlinearConstraint objects.

Parameters:

  • constraints (Sequence[Constraint]) –

    The constraints to convert.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure the constraints are defined on.

  • params_opt (Float[Array, parameters]) –

    The initial optimization parameters, used to warm up the jitted constraint and its Jacobian.

Returns:

  • constraints ( list[Any] | None ) –

    The SciPy constraints, or None when there are none.

Notes

Each constraint carries a jitted value function and a forward-mode Jacobian. Subclasses may return a different container: IPOPT returns cyipopt constraint dictionaries instead.

constraint ¤

constraint(params_opt: Float[Array, parameters], constraint: Constraint, model: EquilibriumModel, structure: EquilibriumStructure) -> Float[Array, constraints]

Evaluate a constraint from a flat optimization parameter vector.

Parameters:

  • params_opt (Float[Array, parameters]) –

    The flat optimization parameter vector.

  • constraint (Constraint) –

    The constraint to evaluate.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure that provides the connectivity.

Returns:

  • values ( Float[Array, constraints] ) –

    The constrained quantity for each element, flattened.

Notes

A constraint maps one element to one value, so a collection is reduced the equinox way: solve for equilibrium once, then vmap the single-element constraint over the collection's leading axis and flatten. The optimizer owns the vmap, mirroring how Error maps a goal over its collection.

GradientFreeOptimizer ¤

GradientFreeOptimizer(disp: bool = False, **kwargs: Any)

The base class for optimizers that minimize without gradients.

Notes

Overrides problem to build an objective without a gradient or hessian, so the loss is only jitted for its value. Constraints are not supported.

problem ¤

problem(model: EquilibriumModel, structure: EquilibriumStructure, datastructure: FDNetwork | FDMesh, loss: Loss, parameters: Sequence[Parameter] | None = None, constraints: Sequence[Constraint] | None = None, maxiter: int = 100, tol: float = 1e-06, callback: Callable | None = None, jit_fn: bool = True) -> OptProblem

Assemble a gradient-free optimization problem.

Parameters:

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure that provides the connectivity.

  • datastructure (FDNetwork | FDMesh) –

    The network or mesh being optimized.

  • loss (Loss) –

    The loss function to minimize.

  • parameters (Sequence[Parameter] | None, default: None ) –

    The optimization parameters. If None, every edge force density is used.

  • constraints (Sequence[Constraint] | None, default: None ) –

    Ignored; gradient-free optimizers do not support constraints.

  • maxiter (int, default: 100 ) –

    The maximum number of optimizer iterations.

  • tol (float, default: 1e-06 ) –

    The convergence tolerance.

  • callback (Callable | None, default: None ) –

    A function invoked once per iteration.

  • jit_fn (bool, default: True ) –

    Whether to just-in-time compile the objective.

Returns:

  • problem ( OptProblem ) –

    The assembled optimization problem, without a gradient or hessian.

solve ¤

solve(opt_problem: OptProblem) -> Float[Array, parameters]

Minimize an assembled gradient-free problem.

Parameters:

  • opt_problem (OptProblem) –

    The problem to minimize.

Returns:

  • params_opt ( Float[Array, parameters] ) –

    The optimized parameter vector.

SecondOrderOptimizer ¤

SecondOrderOptimizer(disp: bool = False, **kwargs: Any)

A gradient-based optimizer that uses the hessian to accelerate convergence.

hessian ¤

hessian(loss: Callable) -> Callable

Build the hessian of a loss function by nested autodiff.

Parameters:

  • loss (Callable) –

    The loss function to differentiate twice.

Returns:

  • hessian ( Callable ) –

    The hessian with respect to the optimization parameters.

Notes

Composed as jacfwd(jacrev(...)), which matches the speed of a dedicated hessian, whereas jacrev(jacfwd(...)) is about three times slower.


Gradient-based optimizers¤

GradientDescent ¤

GradientDescent(learning_rate: float = 0.01, **kwargs: Any)

A vanilla gradient descent optimizer with a fixed learning rate.

Parameters:

  • learning_rate (float, default: 0.01 ) –

    The step size applied to the negative gradient at each iteration.

BFGS ¤

BFGS(disp: bool = False, **kwargs: Any)

The Boyd-Fletcher-Floyd-Shannon optimizer.

LBFGSB ¤

LBFGSB(disp: bool = False, maxfun: int | None = None, maxls: int | None = None, maxcor: int | None = None, **kwargs: Any)

The limited-memory BFGS optimizer with box bounds (L-BFGS-B).

Parameters:

  • disp (bool, default: False ) –

    Whether the SciPy backend prints its own console output.

  • maxfun (int | None, default: None ) –

    The maximum number of function evaluations. If None, the backend default.

  • maxls (int | None, default: None ) –

    The maximum number of line-search steps per iteration. If None, the backend default.

  • maxcor (int | None, default: None ) –

    The number of correction pairs approximating the hessian. If None, the backend default.

options ¤

options(extra: dict[str, Any] | None = None) -> dict[str, Any]

Assemble the backend options, adding the L-BFGS-B specific limits.

Parameters:

  • extra (dict[str, Any] | None, default: None ) –

    Extra options to merge in. None-valued entries are skipped.

Returns:

  • options ( dict[str, Any] ) –

    The options dictionary with maxfun, maxls, and maxcor added and disp removed, as SciPy >= 1.16 no longer accepts it here.

LBFGSBS ¤

LBFGSBS(disp: bool = False, maxfun: int | None = None, maxls: int | None = None, maxcor: int | None = None, **kwargs: Any)

An L-BFGS-B variant that converts JAX gradients to NumPy for SciPy.

Notes

Wrapping each gradient in a NumPy array sidesteps SciPy compatibility issues with JAX arrays, at the cost of being slower than LBFGSB.

gradient ¤

gradient(loss: Callable) -> Callable

Build the gradient, returning NumPy arrays instead of JAX arrays.

Parameters:

  • loss (Callable) –

    The loss function to differentiate.

Returns:

  • gradient ( Callable ) –

    The jitted gradient wrapped to return a NumPy array.

SLSQP ¤

SLSQP(disp: bool = False, **kwargs: Any)

The sequential least-squares programming optimizer.

TruncatedNewton ¤

TruncatedNewton(disp: bool = False, **kwargs: Any)

Minimize a scalar function of one or more variables using a truncated Newton (TNC) algorithm.

TrustRegionConstrained ¤

TrustRegionConstrained(disp: bool = False, **kwargs: Any)

A trust-region algorithm for constrained optimization.


Second-order optimizers¤

NewtonCG ¤

NewtonCG(disp: bool = False, **kwargs: Any)

The truncated Newton method. It uses a CG method to the compute the search direction.

TrustRegionExact ¤

TrustRegionExact(disp: bool = False, **kwargs: Any)

A nearly exact trust-region optimization algorithm.

TrustRegionKrylov ¤

TrustRegionKrylov(disp: bool = False, **kwargs: Any)

A trust-region optimization algorithm.

It uses a nearly exact trust-region algorithm that only requires matrix vector products with the hessian matrix.

TrustRegionNewton ¤

TrustRegionNewton(disp: bool = False, **kwargs: Any)

A Newton conjugate gradient trust-region algorithm. A trust-region algorithm for unconstrained optimization.


Interior-point optimizers¤

Requires the ipopt extra.

IPOPT ¤

IPOPT(acc_tol: float = 1e-09, **kwargs: Any)

The interior point optimizer (Ipopt) for large-scale nonlinear optimization.

Parameters:

  • acc_tol (float, default: 1e-09 ) –

    The acceptable convergence tolerance Ipopt may settle for.

Notes

Supports box bounds and both equality and inequality constraints. Ipopt expects the loss and constraint functions to be twice differentiable, so this optimizer supplies hessians and constraint hessian-vector products.

constraint_eq ¤

constraint_eq(params_opt: Float[Array, parameters], constraint: Constraint, model: EquilibriumModel, structure: EquilibriumStructure) -> Float[Array, constraints]

The residual of an equality constraint, zero when satisfied.

Parameters:

  • params_opt (Float[Array, parameters]) –

    The flat optimization parameter vector.

  • constraint (Constraint) –

    The constraint to evaluate.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure that provides the connectivity.

Returns:

  • residual ( Float[Array, constraints] ) –

    The constrained quantity minus its (shared) bound.

constraint_ineq_up ¤

constraint_ineq_up(params_opt: Float[Array, parameters], constraint: Constraint, model: EquilibriumModel, structure: EquilibriumStructure) -> Float[Array, constraints]

The slack against a constraint's upper bound, non-negative when satisfied.

Parameters:

  • params_opt (Float[Array, parameters]) –

    The flat optimization parameter vector.

  • constraint (Constraint) –

    The constraint to evaluate.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure that provides the connectivity.

Returns:

  • slack ( Float[Array, constraints] ) –

    The upper bound minus the constrained quantity.

constraint_ineq_low ¤

constraint_ineq_low(params_opt: Float[Array, parameters], constraint: Constraint, model: EquilibriumModel, structure: EquilibriumStructure) -> Float[Array, constraints]

The slack against a constraint's lower bound, non-negative when satisfied.

Parameters:

  • params_opt (Float[Array, parameters]) –

    The flat optimization parameter vector.

  • constraint (Constraint) –

    The constraint to evaluate.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure that provides the connectivity.

Returns:

  • slack ( Float[Array, constraints] ) –

    The constrained quantity minus its lower bound.

hvp staticmethod ¤

hvp(x: Float[Array, parameters], v: Float[Array, constraints], f: Callable) -> Float[Array, 'parameters parameters']

The constraint hessian contracted with the Lagrange multipliers.

Parameters:

  • x (Float[Array, parameters]) –

    The point to evaluate the hessian-vector product at.

  • v (Float[Array, constraints]) –

    The vector of Lagrange multipliers, one per constraint component.

  • f (Callable) –

    The vector-valued constraint function.

Returns:

  • hvp ( Float[Array, 'parameters parameters'] ) –

    The sum of each constraint component's hessian scaled by its multiplier, applied at x.

parameters_bounds ¤

parameters_bounds() -> list[tuple[float, float]]

Return the parameter bounds as (low, high) pairs for cyipopt.

Returns:

  • bounds ( list[tuple[float, float]] ) –

    One (lower, upper) bound pair per optimization parameter.

constraints ¤

constraints(constraints: Sequence[Constraint], model: EquilibriumModel, structure: EquilibriumStructure, params_opt: Float[Array, parameters]) -> list[dict[str, Any]]

Convert constraints into cyipopt constraint dictionaries.

Parameters:

  • constraints (Sequence[Constraint]) –

    The constraints to convert.

  • model (EquilibriumModel) –

    The equilibrium model.

  • structure (EquilibriumStructure) –

    The structure the constraints are defined on.

  • params_opt (Float[Array, parameters]) –

    The initial optimization parameters, used to warm up the jitted functions.

Returns:

  • constraints ( list[dict[str, Any]] ) –

    One dictionary per constraint side, each with a value function, its Jacobian, and its hessian-vector product.

Notes

An equal lower and upper bound yields a single equality constraint; otherwise each finite bound becomes its own one-sided inequality.


Gradient-free optimizers¤

NelderMead ¤

NelderMead(disp: bool = False, **kwargs: Any)

The Nelder-Mead gradient-free optimizer with box constraints.

Powell ¤

Powell(disp: bool = False, **kwargs: Any)

The modified Powell algorithm for gradient-free optimization with box constraints.

DifferentialEvolution ¤

DifferentialEvolution(popsize: int = 20, vectorized: bool = False, num_workers: int = 1, seed: int = 43, **kwargs: Any)

A differential evolution global optimizer with box bounds.

Parameters:

  • popsize (int, default: 20 ) –

    The population size multiplier.

  • vectorized (bool, default: False ) –

    If True, the objective is vmapped over the whole population per generation.

  • num_workers (int, default: 1 ) –

    The number of parallel workers used to evaluate the population.

  • seed (int, default: 43 ) –

    The random seed. This algorithm has stochastic components, so mind the seed for reproducibility.

Notes

Local polishing is disabled, so the result is the best population member found.

DualAnnealing ¤

DualAnnealing(no_local_search: bool = True, seed: int = 42, **kwargs: Any)

A dual annealing global optimizer with box bounds.

Parameters:

  • no_local_search (bool, default: True ) –

    If True, run pure generalized simulated annealing without local search.

  • seed (int, default: 42 ) –

    The random seed. This algorithm has stochastic components, so mind the seed for reproducibility.


Recording¤

optimization ¤

OptimizationRecorder ¤

OptimizationRecorder(optimizer: Optimizer | None = None)

A COMPAS data object that logs the parameters visited during optimization.

Parameters:

  • optimizer (Optimizer | None, default: None ) –

    The optimizer whose iterates are recorded. If given, each iterate is expanded into FDM parameters before storing; if None, raw iterates are stored as a flat list.

Notes

As a COMPAS Data subclass the history serializes to and from JSON, so an optimization run can be saved and replayed.

__call__ ¤
__call__(xk: Float[Array, parameters], *args: Any, **kwargs: Any) -> None

Record one optimizer iterate; suitable as an optimizer callback.

Parameters:

  • xk (Float[Array, parameters]) –

    The current flat optimization parameter vector.

  • args (Any, default: () ) –

    Extra positional callback arguments, ignored.

  • kwargs (Any, default: {} ) –

    Extra keyword callback arguments, ignored.

record ¤
record(parameters: Any) -> None

Append one set of parameters to the history.

Parameters:

  • parameters (Any) –

    The parameters to store. With an optimizer, a parameter state whose leaves are appended into the history's matching leaves; without one, a single value appended to the flat history list.