docs: modelling — describe an optimal control problem - #865
Merged
Conversation
Move the "Mathematical formulation" section from index.md to its own page under the sitemap's Modelling node, per docs/reports/03-modelling.md. index.md keeps a two-line pointer. The old math-formulation anchor is not preserved: Documenter only recognises @id on a link that is the sole child of a heading node, so a standalone [](@id math-formulation) is not valid syntax (confirmed against a full rebuild — it silently produced a broken-link warning instead of an anchor). No currently-built page references it.
Ported from docs/attic/manual-abstract.md, with one factual fix: the "control-free is upcoming, use a dummy control as a workaround" compat note directly contradicted the two working examples right above it. Confirmed against CTModels.jl/src/Building/control.jl and test/problems/control_free.jl that omitting the control declaration entirely is, and has been, the correct and only syntax — control!(pre, 0) is rejected. Replaced the stale note with a forward-link to the new Problems without a control page.
Rewritten, not ported, from docs/attic/manual-macro-free.md (899 lines -> 267). Two changes beyond trimming to one worked example (per the spec's own outline, rather than all 6 comparison examples the attic file accumulated): - Deleted the "Scalar vs vector: a subtlety of the functional API" section, which claimed callbacks always receive vectors even for 1-D components. That's false and contradicts the ecosystem's tested "1-D is a scalar" rule (test/suite/shape/test_shape_contract.jl). Replaced with a correct "Shapes in callbacks" section: scalars everywhere except the in-place output buffer, which is always a vector. Fixed the same wrong indexing in the one remaining example's callbacks and in the Canvas template's doc comments. - Deleted the closing inline @docs block (PR 4's generated API reference already covers it). Also worked around a real CTModels bug found while executing this page for the first time under Draft=false: plot(sol) throws on the default call for a plain direct solution once costate is in the default description with layout=:split. Filed as CTModels.jl#392; worked around here with an explicit plot(sol, :state, :control).
Assembled from docs/attic/example-control-free.md's two worked problems (exponential growth rate estimation, harmonic oscillator pulsation) plus new framing sections (how to declare it, how the package knows, adding a control back), matching docs/reports/03-modelling.md's outline. This page didn't exist before. The source's indirect-method shooting code used augment=true and a positional variable argument — both gone from current CTFlows. Fixed to the current signature after verifying it end-to-end (both examples, direct and indirect, recovering p=0.5 and omega=pi/2 as expected): variable is now a keyword, augment=true is variable_costate=true, and the trajectory call no longer takes saveat (removed call-time integrator-option override, see BREAKING.md). Same plot(sol) bug as functional-api.md (CTModels.jl#392) hit here too, for both direct solutions; same explicit-description workaround.
Ported from docs/attic/manual-model.md, which was already accurate. Dropped the "Model struct" section's docstring/getter-list wrapper (PR 4's generated API reference covers it) but kept and relocated the richer running-example OCP definition it also contained, since every later accessor example depends on it being in scope. Trimmed the opening "Main functionalities" teaser (a full solve + Flow/PMP mini-example) down to a couple of pointers to the solve and flows pages — this page is about reading a model back, not solving it; my own editorial call, not explicit in the spec.
Ported from docs/attic/manual-ai-llm.md, near-verbatim. Fixed all 6 occurrences of the stale target URL (the internal @ref, the prompt text, and 4 provider button hrefs) from manual-abstract.html to the new page's route, confirmed against the actual built output (/modelling/abstract-syntax, DocumenterVitepress clean URLs).
…rk board Verified against an independent full rebuild (docs/make.jl + vitepress build), not just the diff: zero undefined-binding/no-docs/ duplicate-docs (regression check on PR 4), zero build errors, zero failed or un-expanded @example blocks on the six modelling pages, zero unresolved @refs from them. One criterion dropped by decision (the math-formulation anchor) with the reasoning recorded inline.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Aug 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docs/src/modelling/), replacing the PR-2 stubs wholesale:formulation.md,abstract-syntax.md,functional-api.md,without-control.md(new page),inspect.md,with-ai.md.CTModels.jl,CTBase,CTFlows.jl,CTParser.jl) and live builds, not just ported fromdocs/attic/— several factual errors in the old docs were caught and fixed rather than carried forward:functional-api.md: removed the "callbacks always receive vectors" claim (contradicts the tested "1-D is a scalar" contract,test/suite/shape/test_shape_contract.jl), fixed the indexing (u[1]→u) across the worked example, and replaced it with an explicit## Shapes in callbackssection stating the real rule (the in-place output buffer is the one exception). Also dropped the spec's own example count down from the attic's six to the one the03-modelling.mdoutline actually calls for, deferring the rest to the future examples gallery (PR 10).abstract-syntax.md: removed a self-contradictory!!! compat "Upcoming feature"note claiming control-free problems aren't supported yet, immediately after two working examples showing they are — confirmed live againstCTModels.jl/src/Building/control.jland the test suite.without-control.md(new): assembled fromdocs/attic/example-control-free.md, with the indirect-method (shooting) code fixed to the currentCTFlows.jlcall signature (variable=,variable_costate=) — the attic version used a staleaugment=true/positional-variableAPI that no longer exists. Verified end-to-end against both real test fixtures (ExponentialGrowth: recovered p≈0.5;HarmonicOscillator: recovered ω≈π/2).inspect.md: dropped the docstring-wrapper section (now covered by PR 4's generated API reference), kept and relocated the richer running example.with-ai.md: fixed six stale URLs pointing at the oldmanual-abstract.htmlpage.formulation.md: moved fromindex.md, which is trimmed to a short pointer. The old@id math-formulationanchor is dropped rather than kept alive — Documenter only recognizes@idas the sole child of a heading, so a same-page dual anchor isn't achievable; no live page referenced it.plot(sol)throwsIncorrectArgument("a VBox needs at least one child")on a plain direct-solved solution whenever the defaultdescription(which includes:costate) is used withlayout=:split— found while executing these pages for real (Draft = false). Worked around in-content with explicitdescriptionargs; not fixed upstream in this PR since CTModels isn't owned by this repo.margin-top/margin-bottomon the<summary>ofindex.md's three collapsible sections (Version info / Package status / Complete manifest).Test plan
julia --project=docs docs/make.jl— full rebuild, from scratch, three iterations until clean: 0 undefined-binding/no-docs/duplicate-docs warnings, 0 errors, all six pages'@exampleblocks execute (Draft = false), 0 unresolved@refs from them.npx vitepress buildon the Documenter output — site builds; spot-checked thewith-ai.mdprovider-button URLs and the rocket-example asset path resolve in the built HTML.test/problems/control_free.jl,test/suite/problems/test_forms_equivalent.jl,test/suite/shape/test_shape_contract.jl— the three fixtures this PR's prose leans on are still green.typoson all new/changed files — clean.docs/reports/03-modelling.mdacceptance criteria re-checked against the real build (5/6 ticked; the@id math-formulationcriterion left unticked with the Documenter-limitation reasoning recorded inline).Depends on #854 (merged). Follows the same PR-per-section pattern as #854/#855/#856.
🤖 Generated with Claude Code