Skip to content

Commit ac8d281

Browse files
authored
Merge pull request #124 from control-toolbox/108-dev-coordinate-wise-dynamics
Coordinate wise dynamics
2 parents 34a4cbe + 68fbc8a commit ac8d281

18 files changed

+733
-5910
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ CTModelsPlots = "Plots"
2828
[compat]
2929
CTBase = "0.16"
3030
DocStringExtensions = "0.9"
31-
Interpolations = "0.15"
31+
Interpolations = "0.16"
3232
JLD2 = "0.5"
3333
JSON3 = "1.14"
3434
LinearAlgebra = "1"

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
44

55
[compat]
66
Documenter = "1"
7+
Plots = "1.40"
78
julia = "1.10"

src/constraints.jl

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ function __constraint!(
6262
)
6363

6464
# checkings: the constraint must not be set before
65-
label keys(ocp_constraints) && throw(
65+
@ensure(!(label keys(ocp_constraints)),
6666
CTBase.UnauthorizedCall(
6767
"the constraint named " * String(label) * " already exists."
6868
),
6969
)
7070

7171
# checkings: lb and ub cannot be both nothing
72-
(isnothing(lb) && isnothing(ub)) && throw(
72+
@ensure(!(isnothing(lb) && isnothing(ub)),
7373
CTBase.UnauthorizedCall(
7474
"The lower bound `lb` and the upper bound `ub` cannot be both nothing."
7575
),
@@ -80,7 +80,7 @@ function __constraint!(
8080
isnothing(ub) && (ub = Inf * ones(eltype(lb), length(lb)))
8181

8282
# lb and ub must have the same length
83-
length(lb) != length(ub) && throw(
83+
@ensure(length(lb) == length(ub),
8484
CTBase.IncorrectArgument(
8585
"the lower bound `lb` and the upper bound `ub` must have the same length."
8686
),
@@ -107,28 +107,28 @@ function __constraint!(
107107
),
108108
)
109109
end
110-
(length(rg) != length(lb)) && throw(CTBase.IncorrectArgument(txt))
110+
@ensure(length(rg) == length(lb), CTBase.IncorrectArgument(txt))
111111
__constraint!(ocp_constraints, type, n, m, q; rg=rg, lb=lb, ub=ub, label=label)
112112
end
113113

114114
(::OrdinalRange{<:Int}, ::Nothing, ::ctVector, ::ctVector) => begin
115115
txt = "the range `rg`, the lower bound `lb` and the upper bound `ub` must have the same dimension"
116-
(length(rg) != length(lb)) && throw(CTBase.IncorrectArgument(txt))
116+
@ensure(length(rg) == length(lb), CTBase.IncorrectArgument(txt))
117117
# check if the range is valid
118118
if type == :state
119-
!all(1 .≤ rg .≤ n) && throw(
119+
@ensure(all(1 .≤ rg .≤ n),
120120
CTBase.IncorrectArgument(
121121
"the range of the state constraint must be contained in 1:$n",
122122
),
123123
)
124124
elseif type == :control
125-
!all(1 .≤ rg .≤ m) && throw(
125+
@ensure(all(1 .≤ rg .≤ m),
126126
CTBase.IncorrectArgument(
127127
"the range of the control constraint must be contained in 1:$m",
128128
),
129129
)
130130
elseif type == :variable
131-
!all(1 .≤ rg .≤ q) && throw(
131+
@ensure(all(1 .≤ rg .≤ q),
132132
CTBase.IncorrectArgument(
133133
"the range of the variable constraint must be contained in 1:$q",
134134
),
@@ -192,50 +192,44 @@ julia> constraint!(ocp, :control, rg=1:2, lb=[0.0], ub=[1.0], label=:control_con
192192
function constraint!(
193193
ocp::PreModel,
194194
type::Symbol;
195-
rg::Union{Int,OrdinalRange{Int},Nothing}=nothing,
196-
f::Union{Function,Nothing}=nothing,
197-
lb::Union{ctNumber,ctVector,Nothing}=nothing,
198-
ub::Union{ctNumber,ctVector,Nothing}=nothing,
199-
label::Symbol=__constraint_label(),
195+
rg::Union{Int, OrdinalRange{Int}, Nothing} = nothing,
196+
f::Union{Function, Nothing} = nothing,
197+
lb::Union{ctNumber, ctVector, Nothing} = nothing,
198+
ub::Union{ctNumber, ctVector, Nothing} = nothing,
199+
label::Symbol = __constraint_label(),
200200
)
201201

202202
# checkings: times, state and control must be set before adding constraints
203-
!__is_state_set(ocp) &&
204-
throw(CTBase.UnauthorizedCall("the state must be set before adding constraints."))
205-
!__is_control_set(ocp) &&
206-
throw(CTBase.UnauthorizedCall("the control must be set before adding constraints."))
207-
!__is_times_set(ocp) &&
208-
throw(CTBase.UnauthorizedCall("the times must be set before adding constraints."))
209-
210-
# checkings: if the ocp has no variable, then the constraint! function cannot be used with type=:variable
211-
!__is_variable_set(ocp) &&
212-
type == :variable &&
213-
throw(
214-
CTBase.UnauthorizedCall(
215-
"the ocp has no variable" *
216-
", you cannot use constraint! function with type=:variable. If it is a mistake, please set the variable first.",
217-
),
218-
)
203+
@ensure __is_state_set(ocp) CTBase.UnauthorizedCall("the state must be set before adding constraints.")
204+
@ensure __is_control_set(ocp) CTBase.UnauthorizedCall("the control must be set before adding constraints.")
205+
@ensure __is_times_set(ocp) CTBase.UnauthorizedCall("the times must be set before adding constraints.")
206+
207+
# checkings: variable must be set if using type=:variable
208+
@ensure (type != :variable || __is_variable_set(ocp)) CTBase.UnauthorizedCall(
209+
"the ocp has no variable, you cannot use constraint! function with type=:variable. If it is a mistake, please set the variable first."
210+
)
219211

220212
# dimensions
221213
n = dimension(ocp.state)
222214
m = dimension(ocp.control)
223215
q = dimension(ocp.variable)
216+
224217
# add the constraint
225218
return __constraint!(
226219
ocp.constraints,
227220
type,
228221
n,
229222
m,
230223
q;
231-
rg=as_range(rg),
232-
f=f,
233-
lb=as_vector(lb),
234-
ub=as_vector(ub),
235-
label=label,
224+
rg = as_range(rg),
225+
f = f,
226+
lb = as_vector(lb),
227+
ub = as_vector(ub),
228+
label = label,
236229
)
237230
end
238231

232+
239233
as_vector(::Nothing) = nothing
240234
(as_vector(x::T)::Vector{T}) where {T<:ctNumber} = [x]
241235
as_vector(x::Vector{T}) where {T<:ctNumber} = x

src/control.jl

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,24 @@ julia> control_components(ocp)
4242
function control!(
4343
ocp::PreModel,
4444
m::Dimension,
45-
name::T1=__control_name(),
46-
components_names::Vector{T2}=__control_components(m, string(name)),
47-
)::Nothing where {T1<:Union{String,Symbol},T2<:Union{String,Symbol}}
48-
49-
# checkings
50-
__is_control_set(ocp) &&
51-
throw(CTBase.UnauthorizedCall("the control has already been set."))
52-
53-
(m > 0) &&
54-
(size(components_names, 1) m) &&
55-
throw(
56-
CTBase.IncorrectArgument(
57-
"the number of control names must be equal to the control dimension"
58-
),
59-
)
60-
61-
# if the dimension is 0 then throw an error
62-
(m == 0) &&
63-
throw(CTBase.IncorrectArgument("the control dimension must be greater than 0"))
45+
name::T1 = __control_name(),
46+
components_names::Vector{T2} = __control_components(m, string(name)),
47+
)::Nothing where {T1<:Union{String,Symbol}, T2<:Union{String,Symbol}}
48+
49+
# checkings using @ensure
50+
@ensure !__is_control_set(ocp) CTBase.UnauthorizedCall("the control has already been set.")
51+
@ensure m > 0 CTBase.IncorrectArgument("the control dimension must be greater than 0")
52+
@ensure size(components_names, 1) == m CTBase.IncorrectArgument(
53+
"the number of control names must be equal to the control dimension"
54+
)
6455

6556
# set the control
6657
ocp.control = ControlModel(string(name), string.(components_names))
6758

6859
return nothing
6960
end
7061

62+
7163
# ------------------------------------------------------------------------------ #
7264
# GETTERS
7365
# ------------------------------------------------------------------------------ #

src/dual_model.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ function dual(sol::Solution, model::Model, label::Symbol)
107107
end
108108
end
109109

110-
# return an exception if the label is not found
111-
return CTBase.IncorrectArgument("Label $label not found in the model.")
110+
# throw an exception if the label is not found
111+
throw(CTBase.IncorrectArgument("Label $label not found in the model."))
112+
112113
end
113114

114115
"""

0 commit comments

Comments
 (0)