Getting Started
Installation
CTBase.jl is typically installed as a dependency of another package in the ecosystem (e.g. OptimalControl.jl). To install it directly:
julia
import Pkg
Pkg.add("CTBase")Requires Julia ≥ 1.10.
Mental Model
CTBase is the base layer of the control-toolbox ecosystem. It provides infrastructure shared by every package above it.
Three things to keep in mind:
- No top-level exports.
using CTBaseloads the package but brings no symbols into scope. Every symbol is accessed via its qualified path:
julia
CTBase.Descriptions.add # ✓ always works
CTBase.Exceptions.NotImplemented- Submodule-first API. The public API lives in named submodules (
Descriptions,Exceptions,DevTools,Core,Unicode). You can bring a submodule's exports into scope explicitly:
julia
using CTBase.Exceptions # brings IncorrectArgument, NotImplemented, … into scope- Extension-backed features.
run_tests,postprocess_coverage, andautomatic_reference_documentationrequire loading the matching weak dependency (Test,Coverage,Documenterrespectively) before they become active.
5-Minute Walkthrough
Working with Descriptions
A description is a Tuple of Symbols that declaratively identifies an algorithm or configuration. Catalogues collect known descriptions; complete resolves a partial description to an exact one.
julia
julia> using CTBase
julia> # Build a catalogue
descs = CTBase.Descriptions.add((), (:euler, :explicit))
(:euler, :explicit)
julia> descs = CTBase.Descriptions.add(descs, (:euler, :implicit))
(:euler, :explicit)
(:euler, :implicit)
julia> descs = CTBase.Descriptions.add(descs, (:runge_kutta, :explicit))
(:euler, :explicit)
(:euler, :implicit)
(:runge_kutta, :explicit)
julia> # Partial completion: find the unique entry containing :implicit
CTBase.Descriptions.complete(:implicit; descriptions=descs)
(:euler, :implicit)
julia> # :euler matches two entries; priority (first in catalog) resolves the tie
CTBase.Descriptions.complete(:euler; descriptions=descs)
(:euler, :explicit)
julia> # No entry contains both :runge_kutta and :implicit → raises AmbiguousDescription
CTBase.Descriptions.complete(:runge_kutta, :implicit; descriptions=descs)
AmbiguousDescription → top-level scope, REPL[7]:2
│
│ cannot find matching description
│
│ Diagnostic No complete match — no description contains all symbols
│ Requested (:runge_kutta, :implicit)
│ Available (:euler, :explicit)
│ (:euler, :implicit)
│ (:runge_kutta, :explicit)
│
│ Context description completion
│ Hint Try one of the closest matches:
└─For more, see the Descriptions guide.
Working with Exceptions
CTBase defines a typed exception hierarchy rooted at CTBase.Exceptions.CTException. Each type carries structured context fields for actionable error messages.
julia
julia> # IncorrectArgument — invalid input value
throw(CTBase.Exceptions.IncorrectArgument(
"state dimension must be positive";
got="0",
expected="n > 0",
suggestion="Pass a positive integer for the state dimension",
))
IncorrectArgument → top-level scope, REPL[1]:2
│
│ state dimension must be positive
│
│ Got 0
│ Expected n > 0
│
│ Hint Pass a positive integer for the state dimension
└─
julia> # NotImplemented — interface stub
throw(CTBase.Exceptions.NotImplemented(
"solve! is not implemented";
required_method="solve!(::MyStrategy, ocp)",
suggestion="Import the package that provides this strategy",
))
NotImplemented → top-level scope, REPL[2]:2
│
│ solve! is not implemented
│
│ Method solve!(::MyStrategy, ocp)
│
│ Hint Import the package that provides this strategy
└─For more, see the Exceptions guide.
Next Steps
| Topic | Guide |
|---|---|
| Descriptions catalogue and completion | Descriptions |
| Exception hierarchy and best practices | Exceptions |
| Modular test runner setup | Test Runner |
| Coverage report generation | Coverage |
| Auto-generated API reference | API Documentation |
| Full API reference | API Reference (left sidebar) |