From 13822c70b391d56f1eac218b7ef44e9e4703b094 Mon Sep 17 00:00:00 2001 From: Pierre Martinon Date: Thu, 13 Jun 2024 15:10:08 +0200 Subject: [PATCH 01/10] add some boolean indicators for OCP --- src/model.jl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/model.jl b/src/model.jl index 4c4bc551..99b3edc1 100644 --- a/src/model.jl +++ b/src/model.jl @@ -101,6 +101,36 @@ Return `true` if the model has been defined as variable independent. """ is_variable_independent(ocp::OptimalControlModel) = !is_variable_dependent(ocp) + +""" +$(TYPEDSIGNATURES) + +Return `true` if the model has been defined with free initial time. +""" +has_free_initial_time(ocp::OptimalControlModel) = (typeof(ocp.initial_time)==Index) + +""" +$(TYPEDSIGNATURES) + +Return `true` if the model has been defined with free final time. +""" +has_free_final_time(ocp::OptimalControlModel) = (typeof(ocp.final_time)==Index) + +""" +$(TYPEDSIGNATURES) + +Return `true` if the model has been defined with lagrange cost. +""" +has_lagrange_cost(ocp::OptimalControlModel) = !isnothing(ocp.lagrange) + +""" +$(TYPEDSIGNATURES) + +Return `true` if the model has been defined with mayer cost. +""" +has_mayer_cost(ocp::OptimalControlModel) = !isnothing(ocp.mayer) + + """ $(TYPEDSIGNATURES) From 0414e278b40ccbf900ac154042a0cda89fbcaa8d Mon Sep 17 00:00:00 2001 From: Pierre Martinon Date: Thu, 13 Jun 2024 15:50:29 +0200 Subject: [PATCH 02/10] added trivial constructor in OCPInit for unified calls --- src/init.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/init.jl b/src/init.jl index b40e5f17..6ec5b9e1 100644 --- a/src/init.jl +++ b/src/init.jl @@ -66,4 +66,10 @@ mutable struct OCPInit end + # trivial version that just returns its argument + # used for unified syntax in caller functions + function OCPInit(init::OCPInit) + return init + end + end From ea3be6964e086779489133c9f5caec9a76f3eacf Mon Sep 17 00:00:00 2001 From: Pierre Martinon Date: Fri, 14 Jun 2024 17:26:21 +0200 Subject: [PATCH 03/10] ok for free times, objective type and variable indicators --- src/CTBase.jl | 1 + src/model.jl | 22 ++++++++++++++++++++++ src/types.jl | 11 +++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/CTBase.jl b/src/CTBase.jl index 44d30887..a93c210b 100644 --- a/src/CTBase.jl +++ b/src/CTBase.jl @@ -150,6 +150,7 @@ export Model export variable!, time!, constraint!, dynamics!, objective!, state!, control!, remove_constraint!, constraint export is_time_independent, is_time_dependent, is_min, is_max, is_variable_dependent, is_variable_independent export nlp_constraints, constraints_labels +export has_free_final_time, has_free_initial_time, has_lagrange_cost, has_mayer_cost # solution export OptimalControlSolution diff --git a/src/model.jl b/src/model.jl index 99b3edc1..b3feba2b 100644 --- a/src/model.jl +++ b/src/model.jl @@ -1212,6 +1212,28 @@ function nlp_constraints(ocp::OptimalControlModel) return val end + # set specific constraints dimensions + ocp.dim_control_constraints = length(ξf) + ocp.dim_state_constraints = length(ηf) + ocp.dim_mixed_constraints = length(ψf) + ocp.dim_path_constraints = ocp.dim_control_constraints + ocp.dim_state_constraints + ocp.dim_mixed_constraints + ocp.dim_boundary_conditions = length(ϕf) + ocp.dim_variable_constraints = length(θf) + ocp.dim_control_box = length(uind) + ocp.dim_state_box = length(xind) + ocp.dim_variable_box = length(vind) + return (ξl, ξ, ξu), (ηl, η, ηu), (ψl, ψ, ψu), (ϕl, ϕ, ϕu), (θl, θ, θu), (ul, uind, uu), (xl, xind, xu), (vl, vind, vu) end + +# getters for constraints dimensions +dim_control_constraints(ocp::OptimalControlModel) = ocp.dim_control_constraints +dim_state_constraints(ocp::OptimalControlModel) = ocp.dim_state_constraints +dim_mixed_constraints(ocp::OptimalControlModel) = ocp.dim_mixed_constraints +dim_path_constraints(ocp::OptimalControlModel) = ocp.dim_path_constraints +dim_boundary_conditions(ocp::OptimalControlModel) = ocp.dim_boundary_conditions +dim_variable_constraints(ocp::OptimalControlModel) = ocp.dim_variable_constraints +dim_control_box(ocp::OptimalControlModel) = ocp.dim_control_box +dim_state_box(ocp::OptimalControlModel) = ocp.dim_state_box +dim_variable_box(ocp::OptimalControlModel) = ocp.dim_variable_box diff --git a/src/types.jl b/src/types.jl index 04fea379..a6e87e21 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1174,6 +1174,17 @@ $(TYPEDFIELDS) criterion::Union{Symbol,Nothing}=nothing dynamics::Union{Dynamics,Nothing}=nothing constraints::Dict{Symbol, Tuple{Vararg{Any}}}=Dict{Symbol, Tuple{Vararg{Any}}}() + + # internal dimensions for constraints + dim_control_constraints::Int64=0 + dim_state_constraints::Int64=0 + dim_mixed_constraints::Int64=0 + dim_path_constraints::Int64=0 + dim_boundary_conditions::Int64=0 + dim_variable_constraints::Int64=0 + dim_control_box::Int64=0 + dim_state_box::Int64=0 + dim_variable_box::Int64=0 end # used for checkings From a6c87be09e1a910eb9661ad2f18602fc6550bd51 Mon Sep 17 00:00:00 2001 From: Pierre Martinon Date: Fri, 14 Jun 2024 17:57:19 +0200 Subject: [PATCH 04/10] constraints dims seem ok --- src/CTBase.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CTBase.jl b/src/CTBase.jl index a93c210b..caedb15e 100644 --- a/src/CTBase.jl +++ b/src/CTBase.jl @@ -151,6 +151,7 @@ export variable!, time!, constraint!, dynamics!, objective!, state!, control!, r export is_time_independent, is_time_dependent, is_min, is_max, is_variable_dependent, is_variable_independent export nlp_constraints, constraints_labels export has_free_final_time, has_free_initial_time, has_lagrange_cost, has_mayer_cost +export dim_boundary_conditions, dim_control_constraints, dim_state_constraints, dim_variable_constraints, dim_mixed_constraints, dim_path_constraints, dim_control_box, dim_state_box, dim_variable_box # solution export OptimalControlSolution From 60143dd27a822b350edf4bc00b0d2e498fac8706 Mon Sep 17 00:00:00 2001 From: Pierre Martinon Date: Fri, 14 Jun 2024 18:10:36 +0200 Subject: [PATCH 05/10] ctdirect test suite is ok --- src/model.jl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/model.jl b/src/model.jl index b3feba2b..aa8d36d7 100644 --- a/src/model.jl +++ b/src/model.jl @@ -1213,15 +1213,15 @@ function nlp_constraints(ocp::OptimalControlModel) end # set specific constraints dimensions - ocp.dim_control_constraints = length(ξf) - ocp.dim_state_constraints = length(ηf) - ocp.dim_mixed_constraints = length(ψf) + ocp.dim_control_constraints = length(ξl) + ocp.dim_state_constraints = length(ηl) + ocp.dim_mixed_constraints = length(ψl) ocp.dim_path_constraints = ocp.dim_control_constraints + ocp.dim_state_constraints + ocp.dim_mixed_constraints - ocp.dim_boundary_conditions = length(ϕf) - ocp.dim_variable_constraints = length(θf) - ocp.dim_control_box = length(uind) - ocp.dim_state_box = length(xind) - ocp.dim_variable_box = length(vind) + ocp.dim_boundary_conditions = length(ϕl) + ocp.dim_variable_constraints = length(θl) + ocp.dim_control_box = length(ul) + ocp.dim_state_box = length(xl) + ocp.dim_variable_box = length(vl) return (ξl, ξ, ξu), (ηl, η, ηu), (ψl, ψ, ψu), (ϕl, ϕ, ϕu), (θl, θ, θu), (ul, uind, uu), (xl, xind, xu), (vl, vind, vu) From 782a2d95ed3a9fd8eeb7692a8cf91444e19ee21d Mon Sep 17 00:00:00 2001 From: Pierre Martinon Date: Fri, 14 Jun 2024 19:19:49 +0200 Subject: [PATCH 06/10] use Dimension type for dimensions --- src/types.jl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/types.jl b/src/types.jl index a6e87e21..656e298c 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1176,15 +1176,15 @@ $(TYPEDFIELDS) constraints::Dict{Symbol, Tuple{Vararg{Any}}}=Dict{Symbol, Tuple{Vararg{Any}}}() # internal dimensions for constraints - dim_control_constraints::Int64=0 - dim_state_constraints::Int64=0 - dim_mixed_constraints::Int64=0 - dim_path_constraints::Int64=0 - dim_boundary_conditions::Int64=0 - dim_variable_constraints::Int64=0 - dim_control_box::Int64=0 - dim_state_box::Int64=0 - dim_variable_box::Int64=0 + dim_control_constraints::Dimension=0 + dim_state_constraints::Dimension=0 + dim_mixed_constraints::Dimension=0 + dim_path_constraints::Dimension=0 + dim_boundary_conditions::Dimension=0 + dim_variable_constraints::Dimension=0 + dim_control_box::Dimension=0 + dim_state_box::Dimension=0 + dim_variable_box::Dimension=0 end # used for checkings From a03c2e6658eac6a4af924e1d9da4d78f954425b6 Mon Sep 17 00:00:00 2001 From: Pierre Martinon Date: Thu, 20 Jun 2024 09:56:14 +0200 Subject: [PATCH 07/10] rename OCPInit to OptimalControlInit --- src/CTBase.jl | 2 +- src/init.jl | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/CTBase.jl b/src/CTBase.jl index caedb15e..2fd77a4a 100644 --- a/src/CTBase.jl +++ b/src/CTBase.jl @@ -158,7 +158,7 @@ export OptimalControlSolution export plot, plot! # initialization -export OCPInit +export OptimalControlInit # utils export ctgradient, ctjacobian, ctinterpolate, ctindices, ctupperscripts diff --git a/src/init.jl b/src/init.jl index 6ec5b9e1..cb73791f 100644 --- a/src/init.jl +++ b/src/init.jl @@ -5,22 +5,22 @@ Initialization of the OCP solution that can be used when solving the discretized # Constructors: -- `OCPInit()`: default initialization -- `OCPInit(x_init, u_init, v_init)`: constant vector and/or function handles -- `OCPInit(sol)`: from existing solution +- `OptimalControlInit()`: default initialization +- `OptimalControlInit(x_init, u_init, v_init)`: constant vector and/or function handles +- `OptimalControlInit(sol)`: from existing solution # Examples ```julia-repl -julia> init = OCPInit() -julia> init = OCPInit(x_init=[0.1, 0.2], u_init=0.3) -julia> init = OCPInit(x_init=[0.1, 0.2], u_init=0.3, v_init=0.5) -julia> init = OCPInit(x_init=[0.1, 0.2], u_init=t->sin(t), v_init=0.5) -julia> init = OCPInit(sol) +julia> init = OptimalControlInit() +julia> init = OptimalControlInit(x_init=[0.1, 0.2], u_init=0.3) +julia> init = OptimalControlInit(x_init=[0.1, 0.2], u_init=0.3, v_init=0.5) +julia> init = OptimalControlInit(x_init=[0.1, 0.2], u_init=t->sin(t), v_init=0.5) +julia> init = OptimalControlInit(sol) ``` """ -mutable struct OCPInit +mutable struct OptimalControlInit state_init::Function control_init::Function @@ -30,7 +30,7 @@ mutable struct OCPInit info::Symbol # warm start from solution - function OCPInit(sol::OptimalControlSolution) + function OptimalControlInit(sol::OptimalControlSolution) init = new() init.info = :from_solution @@ -43,7 +43,7 @@ mutable struct OCPInit end # constant / functional init with explicit arguments - function OCPInit(; state::Union{Nothing, ctVector, Function}=nothing, control::Union{Nothing, ctVector, Function}=nothing, variable::Union{Nothing, ctVector}=nothing) + function OptimalControlInit(; state::Union{Nothing, ctVector, Function}=nothing, control::Union{Nothing, ctVector, Function}=nothing, variable::Union{Nothing, ctVector}=nothing) init = new() init.info = :constant_or_function @@ -57,18 +57,18 @@ mutable struct OCPInit # version with arguments as collection/iterable # (may be fused with version above ?) - function OCPInit(init) + function OptimalControlInit(init) x_init = :state ∈ keys(init) ? init[:state] : nothing u_init = :control ∈ keys(init) ? init[:control] : nothing v_init = :variable ∈ keys(init) ? init[:variable] : nothing - return OCPInit(state=x_init, control=u_init, variable=v_init) + return OptimalControlInit(state=x_init, control=u_init, variable=v_init) end # trivial version that just returns its argument # used for unified syntax in caller functions - function OCPInit(init::OCPInit) + function OptimalControlInit(init::OptimalControlInit) return init end From 89f91e1d488111e39a23ab96b72016c90c62e9dd Mon Sep 17 00:00:00 2001 From: Olivier Cots Date: Thu, 20 Jun 2024 23:53:59 +0200 Subject: [PATCH 08/10] foo --- src/types.jl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/types.jl b/src/types.jl index 656e298c..e886bef7 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1176,15 +1176,15 @@ $(TYPEDFIELDS) constraints::Dict{Symbol, Tuple{Vararg{Any}}}=Dict{Symbol, Tuple{Vararg{Any}}}() # internal dimensions for constraints - dim_control_constraints::Dimension=0 - dim_state_constraints::Dimension=0 - dim_mixed_constraints::Dimension=0 - dim_path_constraints::Dimension=0 - dim_boundary_conditions::Dimension=0 - dim_variable_constraints::Dimension=0 - dim_control_box::Dimension=0 - dim_state_box::Dimension=0 - dim_variable_box::Dimension=0 + dim_control_constraints::Union{Dimension, Nothing}=nothing + dim_state_constraints::Union{Dimension, Nothing}=nothing + dim_mixed_constraints::Union{Dimension, Nothing}=nothing + dim_path_constraints::Union{Dimension, Nothing}=nothing + dim_boundary_conditions::Union{Dimension, Nothing}=nothing + dim_variable_constraints::Union{Dimension, Nothing}=nothing + dim_control_box::Union{Dimension, Nothing}=nothing + dim_state_box::Union{Dimension, Nothing}=nothing + dim_variable_box::Union{Dimension, Nothing}=nothing end # used for checkings From b3cc4edd8d2f90dc839a478f2be4471cd04b590f Mon Sep 17 00:00:00 2001 From: Olivier Cots Date: Thu, 20 Jun 2024 23:57:47 +0200 Subject: [PATCH 09/10] foo --- src/print.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/print.jl b/src/print.jl index 769ce397..613b6ebb 100644 --- a/src/print.jl +++ b/src/print.jl @@ -190,7 +190,7 @@ function Base.show(io::IO, ::MIME"text/plain", ocp::OptimalControlModel{<: TimeD # println(io) printstyled(io, "Declarations ", bold=true) - printstyled(io, "(* for required):\n", bold=false) + printstyled(io, "(* required):\n", bold=false) #println(io) # print table of settings From 5a74f24bbfd4f9554c8512294fc1401088b27275 Mon Sep 17 00:00:00 2001 From: Olivier Cots Date: Fri, 21 Jun 2024 00:05:45 +0200 Subject: [PATCH 10/10] add update constraints dim --- src/model.jl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/model.jl b/src/model.jl index 259d70c7..75b654f9 100644 --- a/src/model.jl +++ b/src/model.jl @@ -655,12 +655,14 @@ function constraint!( ". Please choose in [ :initial, :final, :control, :state, :variable ] or check the arguments of the constraint! method.")) end ocp.constraints[label] = (type, fun_rg, lb, ub) - nothing # to force to return nothing end # _ => throw(IncorrectArgument("Provided arguments are inconsistent.")) end + # update constraints dimensions + __set_dim_constraints(ocp) + end """ @@ -805,6 +807,7 @@ function remove_constraint!(ocp::OptimalControlModel, label::Symbol) ". Please check the list of constraints: ocp.constraints.")) end delete!(ocp.constraints, label) + __set_dim_constraints(ocp) # update constraints dimensions nothing end @@ -1006,6 +1009,12 @@ function nlp_constraints(ocp::OptimalControlModel) end +# +function __set_dim_constraints(ocp::OptimalControlModel) + nlp_constraints(ocp) + nothing +end + # getters for constraints dimensions dim_control_constraints(ocp::OptimalControlModel) = ocp.dim_control_constraints dim_state_constraints(ocp::OptimalControlModel) = ocp.dim_state_constraints