Skip to content
Draft
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
d1023d1
ControlParameter Rework
AlCap23 Mar 6, 2026
3ef70b2
Remake works;
AlCap23 Mar 6, 2026
29b4e7d
Rename test file;
AlCap23 Mar 6, 2026
450f544
Add tests for initial condition; fixed typos
AlCap23 Mar 6, 2026
e8f09f5
Works for symbols typestable
AlCap23 Mar 7, 2026
4d7fd8a
Indexing and type stable
AlCap23 Mar 9, 2026
690a75f
Rework MTK approach
AlCap23 Mar 10, 2026
55972fd
Switch to tspans
AlCap23 Mar 10, 2026
45359dc
Update plots
AlCap23 Mar 10, 2026
7c589cb
Format
AlCap23 Mar 10, 2026
1c0c897
Update docstrings
AlCap23 Mar 10, 2026
8752038
Minor fixes for plotting and trajectory
AlCap23 Mar 11, 2026
223dd2b
Rework controls and introduce fixed controls
AlCap23 Mar 11, 2026
507bc82
Fix Zygote
AlCap23 Mar 11, 2026
8e2bfb9
Add parallel and multiple shooting
AlCap23 Mar 12, 2026
a882ba9
Reiterating tests I
AlCap23 Mar 12, 2026
4eb811b
Fix control tests
AlCap23 Mar 12, 2026
b908b2e
Initializer tests
AlCap23 Mar 12, 2026
4fb9a45
Add LQR testcases
AlCap23 Mar 12, 2026
d6dcf88
Fix typo
AlCap23 Mar 12, 2026
86e8f16
Add more tests
AlCap23 Mar 12, 2026
4908fc2
Adapt lotka optimal control
AlCap23 Mar 12, 2026
babb0d4
Fix test errors
AlCap23 Mar 12, 2026
f1848cb
Update methods for dynprob
AlCap23 Mar 13, 2026
be46e87
Start working on exprs
AlCap23 Mar 14, 2026
120bbf6
Timegrid handling
AlCap23 Mar 16, 2026
db0c587
Add expression based API for evaluation of objective and constraints
AlCap23 Mar 16, 2026
b83ad88
Adapted observed
AlCap23 Mar 16, 2026
b4302f8
Switch to Runtimegenerated
AlCap23 Mar 16, 2026
e744fcf
Rework AI slop
AlCap23 Mar 16, 2026
6938735
Simplify ObservedLayer
AlCap23 Mar 16, 2026
213d2b3
Fix remake and update timegrids
AlCap23 Mar 16, 2026
b61e74d
Update tests for observed layer
AlCap23 Mar 16, 2026
20a8ca0
Format
AlCap23 Mar 16, 2026
1575561
Update Dynprob and extension
AlCap23 Mar 16, 2026
5b854ed
Update dynprob
AlCap23 Mar 17, 2026
a210e46
Fix bounds
AlCap23 Mar 17, 2026
a7ad6b0
Fix bounds of FixedControl
AlCap23 Mar 17, 2026
661508b
Update tests and remove prints
AlCap23 Mar 17, 2026
6f538c4
Update tests and format
AlCap23 Mar 17, 2026
2377639
Rmv observed
AlCap23 Mar 17, 2026
a8a1461
Update docstrings
AlCap23 Mar 17, 2026
c3fa160
Format
AlCap23 Mar 17, 2026
5275620
Remove MTK Extensions for now
AlCap23 Mar 17, 2026
e1ccaae
Fix tests
AlCap23 Mar 17, 2026
0bdae97
Update minor fixes
AlCap23 Mar 17, 2026
9d7a74d
Rmv legacy comments
AlCap23 Mar 17, 2026
8835fa8
Minor fix
AlCap23 Mar 17, 2026
35bd1df
Fix typos and format
AlCap23 Mar 17, 2026
b24a35b
Fix wrong index of lcons and ucons
AlCap23 Mar 17, 2026
4eabfcc
Potential fix for pull request finding
AlCap23 Mar 17, 2026
3fbc8a0
Fix Copilot code
AlCap23 Mar 17, 2026
b1dfa37
Adapt parameter handling
AlCap23 Mar 17, 2026
914f5db
Update MS and tests
AlCap23 Mar 17, 2026
899109f
Adapt to parameter observed interface.
AlCap23 Mar 19, 2026
9dd0218
Remove old MTK API
AlCap23 Mar 25, 2026
498f449
Remove old code
AlCap23 Mar 26, 2026
1d6b002
Add prompts for agentic development
AlCap23 Mar 26, 2026
722dc70
Initialize MTK extension
AlCap23 Mar 26, 2026
e4c1b3e
Start drafting test
AlCap23 Mar 26, 2026
692d9af
Fix MTK symbolic indexing in Trajectory
AlCap23 Mar 26, 2026
6b0ab85
Add test for MTK symbolic indexing
AlCap23 Mar 26, 2026
e3cba93
Fix MTK symbolic indexing with _maybesymbolifyme normalization
AlCap23 Mar 26, 2026
9400fd0
Fix CorleoneMakieExtension for MTK symbolic variables
AlCap23 Mar 26, 2026
de22499
Add MTK tests to runtests.jl
AlCap23 Mar 26, 2026
1ed2054
Format
AlCap23 Mar 26, 2026
4a94693
Add comprehensive MTK optimal control tests
AlCap23 Mar 26, 2026
f6b0183
Format
AlCap23 Mar 26, 2026
9347e5c
Clean up test files and Project.toml
AlCap23 Mar 26, 2026
76f1840
Improve MTK test coverage to match lotka_oc.jl structure
AlCap23 Mar 27, 2026
1362c4d
Add IPOPT optimization tests for MTK interface
AlCap23 Mar 27, 2026
4d85869
Add MTK symbolic DynamicOptimizationLayer interface with Integral sup…
AlCap23 Mar 27, 2026
202327a
test: Add MTK symbolic DynamicOptimizationLayer tests with Integral s…
AlCap23 Mar 28, 2026
ce98898
test: Update MTK test
AlCap23 Mar 30, 2026
30ac3ca
Fix MTK tests: Remove tunable params, use test_broken for IPOPT tests
AlCap23 Mar 30, 2026
94d71d7
Fix constants and paramters
AlCap23 Mar 30, 2026
b24d0ee
Fix project toml and finalize tests
AlCap23 Mar 30, 2026
e3ff54c
Format
AlCap23 Mar 30, 2026
8857dda
Merge pull request #46 from SciML/CJM-MTK
AlCap23 Mar 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,19 @@ OhMyThreads = "67456a42-1dca-4109-a031-0a68de7e3ad5"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
RuntimeGeneratedFunctions = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
SciMLStructures = "53ae85a6-f571-4167-b2af-e1d143709226"
SymbolicIndexingInterface = "2efcf032-c050-4f8e-a9bb-153293bab1f5"

[weakdeps]
ComponentArrays = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66"
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"

[extensions]
CorleoneComponentArraysExtension = "ComponentArrays"
CorleoneMakieExtension = "Makie"
CorleoneComponentArraysExtension = ["ComponentArrays"]
CorleoneModelingToolkitExtension = "ModelingToolkit"

[compat]
Aqua = "0.8"
Expand All @@ -51,6 +50,7 @@ OrdinaryDiffEqTsit5 = "1"
Random = "1"
RecursiveArrayTools = "3.30"
Reexport = "1.2"
RuntimeGeneratedFunctions = "0.5"
SafeTestsets = "0.1"
SciMLBase = "2.110"
SciMLSensitivity = "7.87"
Expand Down
34 changes: 31 additions & 3 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
# API Reference

```@autodocs
Modules = [Corleone]
Order = [:type, :function]
## Types

```@docs
Corleone.ControlParameter
Corleone.ControlParameters
Corleone.ControlSignal
Corleone.InitialCondition
Corleone.SingleShootingLayer
Corleone.Trajectory
```

## Functions

```@docs
Corleone.default_controls
Corleone.find_idx
Corleone.get_block_structure
Corleone.get_bounds
Corleone.get_lower_bound
Corleone.get_new_system
Corleone.get_timegrid
Corleone.get_tspan
Corleone.get_upper_bound
Corleone.is_shooted
Corleone.is_shooting_solution
Corleone.mythreadmap
Corleone.remake_system
Corleone.shooting_violations
Corleone.to_val
Corleone.ttype
Corleone.utype
```
24 changes: 9 additions & 15 deletions ext/CorleoneComponentArraysExtension.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,18 @@ module CorleoneComponentArraysExtension
using Corleone
using ComponentArrays

struct CAFunctionWrapper{A, F} <: Corleone.AbstractCorleoneFunctionWrapper
"The axes of the componentarray"
ax::A
"The original function"
f::F
Corleone.to_vec(::Val{:ComponentArrays}, u) = begin
collect(ComponentArray(u))
end

(f::CAFunctionWrapper)(ps, st) = f.f(ComponentArray(ps, f.ax), st)
(f::CAFunctionWrapper)(res, ps, st) = f.f(res, ComponentArray(ps, f.ax), st)

Corleone.to_vec(::CAFunctionWrapper, x...) = map(x -> isnothing(x) ? x : (collect ∘ ComponentArray)(x), x)

function Corleone.wrap_functions(::Val{:ComponentArrays}, u0::NamedTuple, f...)
u0 = ComponentVector(u0)
ax = getaxes(u0)
return map(f) do fi
isnothing(fi) ? fi : CAFunctionWrapper{typeof(ax), typeof(fi)}(ax, fi)
function Corleone.WrappedFunction(::Val{:ComponentArrays}, f, p, st; kwargs...)
u0 = ComponentVector(p)
pre = let ax = getaxes(u0)
(p) -> ComponentArray(p, ax)
end
return Corleone.WrappedFunction{
typeof(f), typeof(pre),
}(f, pre)
end

end
62 changes: 44 additions & 18 deletions ext/CorleoneMakieExtension.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module CorleoneMakieExtension
using Corleone
using SymbolicIndexingInterface
using Makie

Makie.plottype(sol::Trajectory) = Makie.Lines
Expand All @@ -8,34 +9,59 @@ function Makie.used_attributes(::Type{<:Plot}, sol::Trajectory)
return (:vars, :idxs)
end

maybevec(x::AbstractArray) = eachrow(reduce(hcat, x))
maybevec(x) = x

_getindex(x, i) = getindex(x, i)
_getindex(x::Symbol, i) = x

function Makie.convert_arguments(
PT::Type{<:Plot},
sol::Trajectory;
vars = nothing,
idxs = nothing
idxs::AbstractVector{<:Int} = Int64[],
vars::AbstractVector = [],
kwargs...
)

if !isnothing(vars)
(!isnothing(idxs)) && error("Can't simultaneously provide vars and idxs!")
idxs = vars
if !isempty(idxs)
append!(
vars,
variable_symbols(sol)[idxs]
)
end
if isempty(vars)
for v in variable_symbols(sol)
push!(vars, variable_index(sol, v))
end
end
ts = []
xs = []
labels = String[]
foreach(vars) do var
if is_timeseries_parameter(sol, var)
x_current = maybevec(getp(sol, var)(sol))
append!(xs, x_current)
for i in eachindex(x_current)
push!(ts, sol.controls.collection[1].t)
push!(labels, string(_getindex(var, i)))
end
else
x_current = maybevec(getsym(sol, var)(sol))
append!(xs, x_current)
for i in eachindex(x_current)
push!(ts, sol.t)
push!(labels, string(_getindex(var, i)))
end
end
end

idxs = isnothing(idxs) ? eachindex(sol.u[1]) : idxs
idxs = eltype(idxs) == Symbol ? [sol.sys.variables[i] for i in idxs] : idxs

plot_vecs = reduce(hcat, sol.u)[idxs, :]

plot_type_sym = Makie.plotsym(PT)

inv_sys_variables = Dict(value => key for (key, value) in sol.sys.variables)
labels = string.([inv_sys_variables[i] for i in idxs])

return map(
(x, y, label, i) -> PlotSpec(plot_type_sym, Point2f.(x, y); label, color = Cycled(i)),
[sol.t for _ in eachindex(idxs)],
eachrow(plot_vecs),
(x, y, label, i) -> PlotSpec(plot_type_sym, Point2f.(x, y); label, color = Cycled(i), kwargs...),
ts,
xs,
labels,
eachindex(idxs)
eachindex(labels)
)
end
end
84 changes: 83 additions & 1 deletion ext/CorleoneModelingToolkitExtension.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,92 @@ using ModelingToolkit.Setfield
using ModelingToolkit.SymbolicIndexingInterface
using ModelingToolkit.Symbolics.RuntimeGeneratedFunctions

using ModelingToolkit: IndexCache, DiscreteIndex, BufferTemplate, ParameterTimeseriesIndex

@info "Loading MTK Extension..."

RuntimeGeneratedFunctions.init(@__MODULE__)

function _control_timeseries_pairs(controls)
pairs = Pair[]
for (i, c) in enumerate(values(controls.controls))
name = c.name
# Whole control timeseries, e.g. `u(t)`.
push!(pairs, name => ParameterTimeseriesIndex(i, :))
# Per-component access for array-valued controls, e.g. `u[1]`.
try
for j in eachindex(name)
push!(
pairs, name[j] => ParameterTimeseriesIndex(i, j)
)
end
catch
nothing
end
end
return pairs
end

function _mtk_parameter_index_map(sys, controls)
syms = collect(parameter_symbols(sys))

# Add component symbols for array-valued parameters so `traj.ps[α[1]]` works.
for sym in copy(syms)
try
for j in eachindex(sym)
subsym = sym[j]
if !any(isequal(subsym), syms)
push!(syms, subsym)
end
end
catch
nothing
end
end

for c in values(controls.controls)
name = c.name
if !any(isequal(name), syms)
push!(syms, name)
end
try
for j in eachindex(name)
sym = name[j]
if !any(isequal(sym), syms)
push!(syms, sym)
end
end
catch
nothing
end
end

idxmap = Dict{Any, Any}()
for sym in syms
idxmap[sym] = parameter_index(sys, sym)
end
return idxmap
end

function Corleone.remake_system(sys::ModelingToolkit.AbstractSystem, controls)
control_symbols = map(values(controls.controls)) do ci
csym = ci.name
csym => ParameterTimeseriesIndex(1, parameter_index(sys, csym))
end
ps = map(parameters(sys)) do xi
xi => parameter_index(sys, xi)
end
return SymbolCache(
unknowns(sys),
ps,
independent_variable_symbols(sys);
timeseries_parameters = Dict(reduce(vcat, control_symbols)),
)
end

#=
include("MTKExtension/utils.jl")

include("MTKExtension/optimal_control.jl")

=#
end
Loading
Loading