Skip to content

[WIP] Improvements to the dynamic optimization interface#4394

Draft
SebastianM-C wants to merge 13 commits intoSciML:masterfrom
SebastianM-C:smc/dyn_opt
Draft

[WIP] Improvements to the dynamic optimization interface#4394
SebastianM-C wants to merge 13 commits intoSciML:masterfrom
SebastianM-C:smc/dyn_opt

Conversation

@SebastianM-C
Copy link
Member

Checklist

  • Appropriate tests were added
  • Any code changes were done in a way that does not break public API
  • All documentation related to code changes were updated
  • The new code follows the
    contributor guidelines, in particular the SciML Style Guide and
    COLPRAC.
  • Any new documentation only uses public API

Additional context

Add any other context about the problem here.

SebastianM-C and others added 13 commits March 12, 2026 01:13
Add `scale` metadata option for symbolic variables, following the same
pattern as `bounds` and `guess`. Scales provide characteristic magnitudes
used to normalize dynamics constraints in optimal control formulations,
preventing ill-conditioning from variables with vastly different scales.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FunctionWrapper parameters (e.g., interpolators) fail during fixpoint_sub
with fold=Val(true) because they can't accept JuMP types. Register them
as JuMP nonlinear operators instead, with automatic derivative detection
via Symbolics' derivative_rule system.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ensure that observed equations and constraints referencing pre-binding
parameter names can be fully substituted by propagating parameter
bindings into the substitution map.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After mtkcompile, all declared inputs are bound in equations, making
unbound_inputs return empty. For optimal control, all declared inputs
should become control variables regardless of binding status.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow users to provide constraint scaling, variable bounds, and
function-valued start trajectories at problem construction time.
All keys are normalized via default_toterm for consistent lookup.
Thread kwargs through all backend extensions (InfiniteOpt, CasADi, Pyomo).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace inequality-constraint-based bounds with JuMP set_lower_bound/
set_upper_bound via dispatched set_variable_bounds!. Extract bounds
logic into extract_variable_bounds with support for user-provided
bounds that override metadata. This gives Ipopt better barrier method
structure for optimal control problems.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow users to provide function-valued initial trajectories for state
variables via the initial_trajectory kwarg. Functions are applied via
dispatched set_initial_trajectory! after variable creation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Formulate dynamics as (∂x - tₛ*f(x)) / scale == 0 instead of scaling
each side independently. This prevents degenerate tₛ → 0 solutions and
improves Ipopt convergence for problems with multi-scale state variables.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Substitute observed variables before parameters so that observed
equations referencing parameters get fully resolved during fixpoint_sub.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Set print_level after set_optimizer to prevent the optimizer reset
from discarding the attribute.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend the optimal control bounds system to support observed variables:
- `extract_variable_bounds` now returns `observed_bounds` from variable
  metadata and user `bounds` dict (user bounds take priority)
- InfiniteOpt backend lifts observed bounds into auxiliary bounded
  decision variables with equality constraints, which interior-point
  solvers handle much more efficiently than nonlinear inequalities
- Auxiliary variables get proper start values computed from the initial
  state, and equality constraints are scaled via `scales` dict or
  variable metadata
- Change `add_initial_constraints!` from `fix` to `@constraint` to
  preserve variable bounds at the initial time point

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fixup! Add observed variable bounds lifting and fix initial constraints

Remove aux variable start value computation. Setting start values from
the initial state (e.g. power=15680) creates badly scaled initial points
without improving convergence. The equality constraint (expr-aux)/s==0
drives aux to the correct value regardless of start.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@SebastianM-C SebastianM-C changed the title Improvements to the dynamic optimization interface [WIP] Improvements to the dynamic optimization interface Mar 16, 2026
@SebastianM-C SebastianM-C marked this pull request as draft March 16, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant