1+ using OptimalControl # to define the optimal control problem and its flow
2+ using OrdinaryDiffEq # to get the Flow function from OptimalControl
3+ using MINPACK # NLE solver: use to solve the shooting equation
4+ using Plots # to plot the solution
5+
6+ const t0 = 0
7+ const tf = 1
8+ const x0 = - 1
9+ const xf = 0
10+ const α = 1.5
11+ ocp = @def begin
12+
13+ t ∈ [t0, tf], time
14+ x ∈ R, state
15+ u ∈ R, control
16+
17+ x (t0) == x0
18+ x (tf) == xf
19+
20+ ẋ (t) == - x (t) + α * x (t)^ 2 + u (t)
21+
22+ ∫ ( 0.5 u (t)^ 2 ) → min
23+
24+ end
25+ nothing # hide
26+
27+ u (x, p) = p
28+ φ = Flow (ocp, u)
29+
30+ π ((x, p)) = x
31+
32+ S (p0) = π ( φ (t0, x0, p0, tf) ) - xf # shooting function
33+
34+ ξ = [0.1 ] # initial guess
35+
36+ using MINPACK
37+ function fsolve (f, j, x; kwargs... )
38+ try
39+ MINPACK. fsolve (f, j, x; kwargs... )
40+ catch e
41+ println (" Erreur using MINPACK" )
42+ println (e)
43+ println (" hybrj not supported. Replaced by hybrd even if it is not visible on the doc." )
44+ MINPACK. fsolve (f, x; kwargs... )
45+ end
46+ end
47+
48+ using DifferentiationInterface
49+ import ForwardDiff
50+ backend = AutoForwardDiff ()
51+
52+ nle! = ( s, ξ) -> s[1 ] = S (ξ[1 ]) # auxiliary function
53+ jnle! = (js, ξ) -> jacobian! (nle!, similar (ξ), js, backend, ξ) #
54+
55+
56+ indirect_sol = fsolve (nle!, jnle!, ξ; show_trace= true ) # resolution of S(p0) = 0
57+ p0_sol = indirect_sol. x[1 ] # costate solution
58+ println (" \n costate: p0 = " , p0_sol)
59+ println (" shoot: |S(p0)| = " , abs (S (p0_sol)), " \n " )
60+
61+ sol = φ ((t0, tf), x0, p0_sol)
62+ plot (sol)
63+
64+ using Plots. PlotMeasures
65+ function Plots. plot (S:: Function , p0:: Float64 ; Np0= 20 , kwargs... )
66+
67+ # times for wavefronts
68+ times = range (t0, tf, length= 3 )
69+
70+ # times for trajectories
71+ tspan = range (t0, tf, length= 100 )
72+
73+ # interval of initial covector
74+ p0_min = - 0.5
75+ p0_max = 2
76+
77+ # covector solution
78+ p0_sol = p0
79+
80+ # plot of the flow in phase space
81+ plt_flow = plot ()
82+ p0s = range (p0_min, p0_max, length= Np0)
83+ for i ∈ eachindex (p0s)
84+ sol = φ ((t0, tf), x0, p0s[i])
85+ x = state (sol).(tspan)
86+ p = costate (sol).(tspan)
87+ label = i== 1 ? " extremals" : false
88+ plot! (plt_flow, x, p, color= :blue , label= label)
89+ end
90+
91+ # plot of wavefronts in phase space
92+ p0s = range (p0_min, p0_max, length= 200 )
93+ xs = zeros (length (p0s), length (times))
94+ ps = zeros (length (p0s), length (times))
95+ for i ∈ eachindex (p0s)
96+ sol = φ ((t0, tf), x0, p0s[i], saveat= times)
97+ xs[i, :] .= state (sol).(times)
98+ ps[i, :] .= costate (sol).(times)
99+ end
100+ for j ∈ eachindex (times)
101+ label = j== 1 ? " flow at times" : false
102+ plot! (plt_flow, xs[:, j], ps[:, j], color= :green , linewidth= 2 , label= label)
103+ end
104+
105+ #
106+ plot! (plt_flow, xlims= (- 1.1 , 1 ), ylims= (p0_min, p0_max))
107+ plot! (plt_flow, [0 , 0 ], [p0_min, p0_max], color= :black , xlabel= " x" , ylabel= " p" , label= " x=xf" )
108+
109+ # solution
110+ sol = φ ((t0, tf), x0, p0_sol)
111+ x = state (sol).(tspan)
112+ p = costate (sol).(tspan)
113+ plot! (plt_flow, x, p, color= :red , linewidth= 2 , label= " extremal solution" )
114+ plot! (plt_flow, [x[end ]], [p[end ]], seriestype= :scatter , color= :green , label= false )
115+
116+ # plot of the shooting function
117+ p0s = range (p0_min, p0_max, length= 200 )
118+ plt_shoot = plot (xlims= (p0_min, p0_max), ylims= (- 2 , 4 ), xlabel= " p₀" , ylabel= " y" )
119+ plot! (plt_shoot, p0s, S, linewidth= 2 , label= " S(p₀)" , color= :green )
120+ plot! (plt_shoot, [p0_min, p0_max], [0 , 0 ], color= :black , label= " y=0" )
121+ plot! (plt_shoot, [p0_sol, p0_sol], [- 2 , 0 ], color= :black , label= " p₀ solution" , linestyle= :dash )
122+ plot! (plt_shoot, [p0_sol], [0 ], seriestype= :scatter , color= :green , label= false )
123+
124+ # final plot
125+ plot (plt_flow, plt_shoot; layout= (1 ,2 ), leftmargin= 15 px, bottommargin= 15 px, kwargs... )
126+
127+ end
128+
129+ p0_sol
130+
131+ plot (S, p0_sol; size= (800 , 450 ))
0 commit comments