[Doc] Examples for the sign convention of duals and costate (min/max, writing of constraints, direct vs indirect)
Maintainer thường phản hồi trong vòng 1 ngày
@ocots đang làm issue này rồi.
Từ ngày 23/10/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
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
- Ngôn ngữ chính
- Julia
- Star
- 135
- Fork
- 11
- Merge trung bình
- 7 giờ 49 phút
- Pull request đã merge (30 ngày)
- 23
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của control-toolbox/OptimalControl.jl
-
[Doc] A pull request without the preview label announces a deployment that never happensCó thể đã có người làm @ocots đã nhận 1 ngày trước. Đang mởdocumentation
control-toolbox/OptimalControl.jl#1042 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Doc] User guide to the duals: every kind, constraint ↔ dual, direct ↔ indirectCó thể đã có người làm @ocots đã nhận 7 ngày trước. Đang mở
control-toolbox/OptimalControl.jl#1035 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Tests of the duals: every kind of constraint, direct vs indirect, pinned algorithmsCó thể đã có người làm @ocots đã nhận 7 ngày trước. Đang mở
control-toolbox/OptimalControl.jl#1034 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Documentation: sign conventions (min/max, p⁰, constraints, duals) and how they appear in a solutionCó thể đã có người làm @ocots đã nhận 18 ngày trước. Đang mởdocumentation
control-toolbox/OptimalControl.jl#1015 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Tests fail on Julia 1.13: keyword-only anonymous function in test/problems/goddard.jlCó thể đã có người làm @ocots đã nhận 20 ngày trước. Đang mở
control-toolbox/OptimalControl.jl#996 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của control-toolbox/OptimalControl.jl
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
Maintainer thường phản hồi trong vòng 1 ngày
-
lux
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
JuliaGraphs/GraphNeuralNetworks.jl#732 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
erfinv(::Float16) and erfcinv(::Float16) are wrong for abs(x) <= 0.75 (erfinv(Float16(0)) == 0.2201)Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
JuliaMath/SpecialFunctions.jl#571 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100