[Doc] Examples for the sign convention of duals and costate (min/max, writing of constraints, direct vs indirect)
Los mantenedores suelen responder en 1 día
@ocots ya está trabajando en esto.
Desde el 23/10/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Follow-up of #1014 (the convention) and companion of #1015 (the page that states it). This issue lists the examples to add to the documentation, so that a user can see that the signs do not depend on the solver, on the sense of the criterion, or on the way a constraint is written. Each example should also become a test: run in a docs page, it fails loudly if a convention moves.
The implementation is in three draft PRs:
- control-toolbox/CTSolvers.jl#289: one multiplier convention for every NLP solver.
min fandmax -fhave the same multipliers; a constraint with a single bound has a nonnegative multiplier; equalities keep their sign. - control-toolbox/CTFlows.jl#494: the solution of
Flow(ocp, law; constraint=:label, multiplier=μ)carriesdual(sol, ocp, :label), in the same convention. - control-toolbox/CTModels.jl#483:
dualon a solution that holds the duals of some constraints only, and the jumps of the duals in the plots of a multi-phase solution.
The convention, as the user should read it (for #1015)
- The dual of an inequality constraint is nonnegative, whatever the constraint and the sense of the criterion.
g(x) ≤ 0and-g(x) ≥ 0, orx(t) ≥ 0.1and0.1 - x(t) ≤ 0, are the same constraint and have the same dual. - An equality keeps its sign:
c = 0and-c = 0have opposite duals. min Jandmax -Jare the same problem: they have the same duals and the same costatep. Only the objective changes sign.- Indirect method: the pseudo-Hamiltonian
H = p·f + p⁰ℓ + μ·g(g ≥ 0,μ ≥ 0) is always maximised, withp⁰ = -1for a minimisation and+1for a maximisation.dual(sol, ocp, :label)of a flow solution is theμgiven to the flow (0off the boundary arc). - A constraint with two finite bounds,
lb ≤ c ≤ ub, has a signed dual:+μwhen the upper side is active,-μwhen the lower side is.
Examples to add
-
The signs do not change with
min/max. Solveẋ = u,x(0) = -1,x(t) + u(t) ≤ 0,0 ≤ u(t):- once as
∫ -u(t) dt → min, once as∫ u(t) dt → max; - with Ipopt and with MadNLP.
Show that
costate(sol)anddual(sol, ocp, :mixed)are the same in the four cases. The closed form isp(t) = e^{t-1} - 1anddual = e^{t-1}. - once as
-
The signs do not change with the way a constraint is written. The same problem with
x(t) + u(t) ≤ 0written as-x(t) - u(t) ≥ 0: the same dual. -
Direct and indirect give the same duals. Rebuild the solution of example 1 with
Flow(ocp, (x, p) -> -x; constraint=:mixed, multiplier=(x, p) -> p + 1), then comparedual(sol_direct, ocp, :mixed)anddual(sol_flow, ocp, :mixed)on one plot. They agree up to the discretisation error. -
A boundary arc in a multi-phase indirect solution. The problem of control-toolbox/CTFlows.jl#440 (
x ≥ 0.1, three arcs).plot(sol)shows the dual,0then2x = 0.2on the boundary arc then0, with its jumps at the junctions and the phase labels. Compare with a direct solve of the same problem. -
Why the label matters. In a flow, a constraint given as a function has no label: its dual cannot be placed in the solution, the flow warns, and
dualthrows. Show the labelled form,constraint=:labelor:label => :upper.
Possible tests (OptimalControl test suite, the cross-package level): examples 1 to 3, with Ipopt and MadNLP (and Uno), as @test on the closed form.
Still open (not for the user page)
- Box constraints. The dual of a box (
0 ≤ u(t) ≤ 1declared as a box) has the opposite sign to the same constraint written as a path constraint, and it is not divided by the step (control-toolbox/CTDirect.jl#639). The page should say so until it is fixed, or wait for it. - Boundary and box duals of a flow solution are not rebuilt (
dualthrows aPreconditionError). - Two-sided constraints: the signed value is kept. Is that what the page should present, or a pair (lower, upper)?
🤖 Generated with Claude Code
- Lenguaje dominante
- Julia
- Estrellas
- 135
- Forks
- 11
- Merge medio
- 7 h 51 min
- PR fusionados (30 d)
- 22
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de control-toolbox/OptimalControl.jl
-
[Doc] User guide to the duals: every kind, constraint ↔ dual, direct ↔ indirectPosiblemente ocupada @ocots la tomó hace 6 días. Abierto
control-toolbox/OptimalControl.jl#1035 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Tests of the duals: every kind of constraint, direct vs indirect, pinned algorithmsPosiblemente ocupada @ocots la tomó hace 6 días. Abierto
control-toolbox/OptimalControl.jl#1034 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Documentation: sign conventions (min/max, p⁰, constraints, duals) and how they appear in a solutionPosiblemente ocupada @ocots la tomó hace 17 días. Abiertodocumentation
control-toolbox/OptimalControl.jl#1015 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Tests fail on Julia 1.13: keyword-only anonymous function in test/problems/goddard.jlPosiblemente ocupada @ocots la tomó hace 19 días. Abierto
control-toolbox/OptimalControl.jl#996 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Docs: use Makie.Figure() instead of Makie.plot() for an empty canvasPosiblemente ocupada @ocots la tomó hace 19 días. Abierto
control-toolbox/OptimalControl.jl#994 · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de control-toolbox/OptimalControl.jl
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Add project: Typst_jll.jlPosiblemente ocupada @github-actions la tomó hoy. Abiertoadd-project
Dificultad 1/5 Menos de una hora Aptitud para principiantes 76/100
YDX-2147483647/best-of-typst#590 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100