Skip to content

Commit

Permalink
check for expression before integral in Lagrange / Bolza cost
Browse files Browse the repository at this point in the history
  • Loading branch information
jbcaillau committed May 23, 2024
1 parent 8d9638b commit 6c3a438
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 113 deletions.
36 changes: 2 additions & 34 deletions src/ctparser_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ replace_call(e, x::Vector{Symbol}, t, y) = begin
@assert length(x) == length(y)
foo(x, t, y) = (h, args...) -> begin
ee = Expr(h, args...)
@match ee begin
@match ee begin
:( $eee($tt) ) && if tt == t end =>
let ch = false
for i 1:length(x)
Expand Down Expand Up @@ -202,7 +202,7 @@ julia> has(e, :u, :t)
true
```
"""
has(e, x, t::Symbol) = begin
has(e, x, t::Union{Symbol, Real}) = begin
foo(x, t) = (h, args...) -> begin
ee = Expr(h, args...)
if :yes args
Expand All @@ -215,38 +215,6 @@ has(e, x, t::Symbol) = begin
expr_it(e, foo(x, t), x -> x) == :yes
end

# todo: has_call(e, t) == true if e = ...(t)... i.e. if e contains an evaluation (call) at t
# slight update of has(e, x, t); intended to check expression to be incorporated into Lagrange integrand, see onepass.jl
# TBI
"""
$(TYPEDSIGNATURES)
Return true if e contains a `(...)(t)` call.
# Example
```jldoctest
julia> e = :( ∫( x[1](t)^2 + 2*u(t) ) → min )
:(∫((x[1])(t) ^ 2 + 2 * u(t)) → min)
julia> has_call(e, :t)
julia> has_call(e, :x)
julia> has_call(:( 2f(t) ), :t)
```
"""
has_call(e, t::Symbol) = begin
foo(t) = (h, args...) -> begin
ee = Expr(h, args...)
if :yes args
:yes
else @match ee begin
:( $eee($tt) ) => (tt == t) ? :yes : ee
_ => ee end
end
end
expr_it(e, foo(t), x -> x) == :yes
end

"""
$(TYPEDSIGNATURES)
Expand Down
149 changes: 70 additions & 79 deletions src/onepass.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,88 +78,79 @@ parse!(p, ocp, e; log=false) = begin
# aliases
:( $a = $e1 ) =>
@match e1 begin
:( ($names) R^$q, variable ) => p_variable!(p, ocp, a, q; components_names=names, log)
:( [$names] R^$q, variable ) => p_variable!(p, ocp, a, q; components_names=names, log)
:( ($names) R^$n, state ) => p_state!(p, ocp, a, n; components_names=names, log)
:( [$names] R^$n, state ) => p_state!(p, ocp, a, n; components_names=names, log)
:( ($names) R^$m, control ) => p_control!(p, ocp, a, m; components_names=names, log)
:( [$names] R^$m, control ) => p_control!(p, ocp, a, m; components_names=names, log)
:( ($names) R, $dummy ) => return __throw("unknown syntax", p.lnum, p.line)
:( [$names] R, $dummy ) => return __throw("unknown syntax", p.lnum, p.line)
_ => p_alias!(p, ocp, a, e1; log) # alias
end
# variable
:( ($e1, $e2) R^$q, variable ) => return __throw("unknown syntax: please provide a name to the variable", p.lnum, p.line)
:( $v R^$q, variable ) => p_variable!(p, ocp, v, q; log)
:( $v R , variable ) => p_variable!(p, ocp, v ; log)
:( $v , variable ) => p_variable!(p, ocp, v ; log) # todo: remove
# time
:( $t [ $t0, $tf ], time ) => p_time!(p, ocp, t, t0, tf; log)
# state
:( ($e1, $e2) R^$n, state ) => return __throw("unknown syntax: please provide a name to the state", p.lnum, p.line)
:( $x R^$n, state ) => p_state!(p, ocp, x, n; log)
:( $x R , state ) => p_state!(p, ocp, x ; log)
:( $x , state ) => p_state!(p, ocp, x ; log) # todo: remove
# control
:( ($e1, $e2) R^$m, control ) => return __throw("unknown syntax: please provide a name to the control", p.lnum, p.line)
:( $u R^$m, control ) => p_control!(p, ocp, u, m; log)
:( $u R , control ) => p_control!(p, ocp, u ; log)
:( $u , control ) => p_control!(p, ocp, u ; log) # todo: remove
# dynamics
:( ($x)($t) == $e1 ) => p_dynamics!(p, ocp, x, t, e1 ; log)
:( ($x)($t) == $e1, $label ) => p_dynamics!(p, ocp, x, t, e1, label; log)
# constraints
:( $e1 == $e2 ) => p_constraint!(p, ocp, e2 , e1, e2 ; log)
:( $e1 == $e2, $label ) => p_constraint!(p, ocp, e2 , e1, e2, label; log)
:( $e1 $e2 $e3 ) => p_constraint!(p, ocp, e1 , e2, e3 ; log)
:( $e1 $e2 $e3, $label ) => p_constraint!(p, ocp, e1 , e2, e3 , label; log)
:( $e2 $e3 ) => p_constraint!(p, ocp, nothing, e2, e3 ; log)
:( $e2 $e3, $label ) => p_constraint!(p, ocp, nothing, e2, e3 , label; log)
:( $e3 $e2 $e1 ) => p_constraint!(p, ocp, e1 , e2, e3 ; log)
:( $e3 $e2 $e1, $label ) => p_constraint!(p, ocp, e1 , e2, e3 , label; log)
:( $e2 $e1 ) => p_constraint!(p, ocp, e1 , e2, nothing ; log)
:( $e2 $e1, $label ) => p_constraint!(p, ocp, e1 , e2, nothing, label; log)
:( ($names) R^$q, variable ) => p_variable!(p, ocp, a, q; components_names=names, log)
:( [$names] R^$q, variable ) => p_variable!(p, ocp, a, q; components_names=names, log)
:( ($names) R^$n, state ) => p_state!(p, ocp, a, n; components_names=names, log)
:( [$names] R^$n, state ) => p_state!(p, ocp, a, n; components_names=names, log)
:( ($names) R^$m, control ) => p_control!(p, ocp, a, m; components_names=names, log)
:( [$names] R^$m, control ) => p_control!(p, ocp, a, m; components_names=names, log)
_ => p_alias!(p, ocp, a, e1; log) # alias
end
# variable
:( $v R^$q, variable ) => p_variable!(p, ocp, v, q; log)
:( $v R , variable ) => p_variable!(p, ocp, v ; log)
:( $v , variable ) => p_variable!(p, ocp, v ; log) # todo: remove
# time
:( $t [ $t0, $tf ], time ) => p_time!(p, ocp, t, t0, tf; log)
# state
:( $x R^$n, state ) => p_state!(p, ocp, x, n; log)
:( $x R , state ) => p_state!(p, ocp, x ; log)
:( $x , state ) => p_state!(p, ocp, x ; log) # todo: remove
# control
:( $u R^$m, control ) => p_control!(p, ocp, u, m; log)
:( $u R , control ) => p_control!(p, ocp, u ; log)
:( $u , control ) => p_control!(p, ocp, u ; log) # todo: remove
# dynamics
:( ($x)($t) == $e1 ) => p_dynamics!(p, ocp, x, t, e1 ; log)
:( ($x)($t) == $e1, $label ) => p_dynamics!(p, ocp, x, t, e1, label; log)
# constraints
:( $e1 == $e2 ) => p_constraint!(p, ocp, e2 , e1, e2 ; log)
:( $e1 == $e2, $label ) => p_constraint!(p, ocp, e2 , e1, e2, label; log)
:( $e1 $e2 $e3 ) => p_constraint!(p, ocp, e1 , e2, e3 ; log)
:( $e1 $e2 $e3, $label ) => p_constraint!(p, ocp, e1 , e2, e3 , label; log)
:( $e2 $e3 ) => p_constraint!(p, ocp, nothing, e2, e3 ; log)
:( $e2 $e3, $label ) => p_constraint!(p, ocp, nothing, e2, e3 , label; log)
:( $e3 $e2 $e1 ) => p_constraint!(p, ocp, e1 , e2, e3 ; log)
:( $e3 $e2 $e1, $label ) => p_constraint!(p, ocp, e1 , e2, e3 , label; log)
:( $e2 $e1 ) => p_constraint!(p, ocp, e1 , e2, nothing ; log)
:( $e2 $e1, $label ) => p_constraint!(p, ocp, e1 , e2, nothing, label; log)
# lagrange cost
:( ($e1) min ) => p_lagrange!(p, ocp, e1 , :min; log)
:( - ($e1) min ) => p_lagrange!(p, ocp, :( -$e1 ) , :min; log)
:( $e1 * ($e2) min ) => p_lagrange!(p, ocp, :( $e1 * $e2 ), :min; log)
#:( - $e1 * ∫($e2) → min ) => p_lagrange!(p, ocp, :( -$e1 * $e2 ), :min; log)
:( ($e2) / $e1 min ) => p_lagrange!(p, ocp, :( $e2 / $e1 ), :min; log)
:( - ($e2) / $e1 min ) => p_lagrange!(p, ocp, :( -$e2 / $e1 ), :min; log)
:( ($e1) max ) => p_lagrange!(p, ocp, e1 , :max; log)
:( - ($e1) max ) => p_lagrange!(p, ocp, :( -$e1 ) , :max; log)
:( $e1 * ($e2) max ) => p_lagrange!(p, ocp, :( $e1 * $e2 ), :max; log)
#:( - $e1 * ∫($e2) → max ) => p_lagrange!(p, ocp, :( -$e1 * $e2 ), :max; log)
:( ($e2) / $e1 max ) => p_lagrange!(p, ocp, :( $e2 / $e1 ), :max; log)
:( - ($e2) / $e1 max ) => p_lagrange!(p, ocp, :( -$e2 / $e1 ), :max; log)
:( ($e1) min ) => p_lagrange!(p, ocp, e1 , :min; log)
:( - ($e1) min ) => p_lagrange!(p, ocp, :( -$e1 ) , :min; log)
:( $e1 * ($e2) min ) => has(e1, p.t) ? ( return __throw("time $(p.t) must not appear in $e1", p.lnum, p.line) ) :
p_lagrange!(p, ocp, :( $e1 * $e2 ), :min; log)
:( ($e1) max ) => p_lagrange!(p, ocp, e1 , :max; log)
:( - ($e1) max ) => p_lagrange!(p, ocp, :( -$e1 ) , :max; log)
:( $e1 * ($e2) max ) => has(e1, p.t) ? ( return __throw("time $(p.t) must not appear in $e1", p.lnum, p.line) ) :
p_lagrange!(p, ocp, :( $e1 * $e2 ), :max; log)
# bolza cost
:( $e1 + ($e2) min ) => p_bolza!(p, ocp, e1, e2 , :min; log)
:( $e1 + $e2 * ($e3) min ) => p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :min; log)
:( $e1 + ($e3) / $e2 min ) => p_bolza!(p, ocp, e1, :( $e3 / $e2 ), :min; log)
:( $e1 - ($e2) min ) => p_bolza!(p, ocp, e1, :( -$e2 ) , :min; log)
:( $e1 - $e2 * ($e3) min ) => p_bolza!(p, ocp, e1, :( -$e2 * $e3 ), :min; log)
:( $e1 - ($e3) / $e2 min ) => p_bolza!(p, ocp, e1, :( -$e3 / $e2 ), :min; log)
:( $e1 + ($e2) max ) => p_bolza!(p, ocp, e1, e2 , :max; log)
:( $e1 + $e2 * ($e3) max ) => p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :max; log)
:( $e1 + ($e3) / $e2 max ) => p_bolza!(p, ocp, e1, :( $e3 / $e2 ), :max; log)
:( $e1 - ($e2) max ) => p_bolza!(p, ocp, e1, :( -$e2 ) , :max; log)
:( $e1 - $e2 * ($e3) max ) => p_bolza!(p, ocp, e1, :( -$e2 * $e3 ), :max; log)
:( $e1 - ($e3) / $e2 max ) => p_bolza!(p, ocp, e1, :( -$e3 / $e2 ), :max; log)
:( ($e2) + $e1 min ) => p_bolza!(p, ocp, e1, e2 , :min; log)
:( $e2 * ($e3) + $e1 min ) => p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :min; log)
:( ($e3) / $e2 + $e1 min ) => p_bolza!(p, ocp, e1, :( $e3 / $e2 ), :min; log)
:( ($e2) - $e1 min ) => p_bolza!(p, ocp, :( -$e1 ), e2 , :min; log)
:( $e2 * ($e3) - $e1 min ) => p_bolza!(p, ocp, :( -$e1 ), :( $e2 * $e3 ), :min; log)
:( ($e3) / $e2 - $e1 min ) => p_bolza!(p, ocp, :( -$e1 ), :( $e3 / $e2 ), :min; log)
:( ($e2) + $e1 max ) => p_bolza!(p, ocp, e1, e2 , :max; log)
:( $e2 * ($e3) + $e1 max ) => p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :max; log)
:( ($e3) / $e2 + $e1 max ) => p_bolza!(p, ocp, e1, :( $e3 / $e2 ), :max; log)
:( ($e2) - $e1 max ) => p_bolza!(p, ocp, :( -$e1 ), e2 , :max; log)
:( $e2 * ($e3) - $e1 max ) => p_bolza!(p, ocp, :( -$e1 ), :( $e2 * $e3 ), :max; log)
:( ($e3) / $e2 - $e1 max ) => p_bolza!(p, ocp, :( -$e1 ), :( $e3 / $e2 ), :max; log)
:( $e1 + ($e2) min ) => p_bolza!(p, ocp, e1, e2 , :min; log)
:( $e1 + $e2 * ($e3) min ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :min; log)
:( $e1 - ($e2) min ) => p_bolza!(p, ocp, e1, :( -$e2 ) , :min; log)
:( $e1 - $e2 * ($e3) min ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, e1, :( -$e2 * $e3 ), :min; log)
:( $e1 + ($e2) max ) => p_bolza!(p, ocp, e1, e2 , :max; log)
:( $e1 + $e2 * ($e3) max ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :max; log)
:( $e1 - ($e2) max ) => p_bolza!(p, ocp, e1, :( -$e2 ) , :max; log)
:( $e1 - $e2 * ($e3) max ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, e1, :( -$e2 * $e3 ), :max; log)
:( ($e2) + $e1 min ) => p_bolza!(p, ocp, e1, e2 , :min; log)
:( $e2 * ($e3) + $e1 min ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :min; log)
:( ($e2) - $e1 min ) => p_bolza!(p, ocp, :( -$e1 ), e2 , :min; log)
:( $e2 * ($e3) - $e1 min ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, :( -$e1 ), :( $e2 * $e3 ), :min; log)
:( ($e2) + $e1 max ) => p_bolza!(p, ocp, e1, e2 , :max; log)
:( $e2 * ($e3) + $e1 max ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, e1, :( $e2 * $e3 ), :max; log)
:( ($e2) - $e1 max ) => p_bolza!(p, ocp, :( -$e1 ), e2 , :max; log)
:( $e2 * ($e3) - $e1 max ) => has(e2, p.t) ? ( return __throw("time $(p.t) must not appear in $e2", p.lnum, p.line) ) :
p_bolza!(p, ocp, :( -$e1 ), :( $e2 * $e3 ), :max; log)
# mayer cost
:( $e1 min ) => p_mayer!(p, ocp, e1, :min; log)
:( $e1 max ) => p_mayer!(p, ocp, e1, :max; log)
:( $e1 min ) => p_mayer!(p, ocp, e1, :min; log)
:( $e1 max ) => p_mayer!(p, ocp, e1, :max; log)
#
_ => begin
if e isa LineNumberNode
Expand Down

0 comments on commit 6c3a438

Please sign in to comment.