t0 = 0.
tf = 1.
x0 = [0.; 0.]
α = 1.
function hv(x, p)
return [p[1]; α+p[2]; 0.; 0.]
end
z = Flow(hv)
function shoot(p0)
xf, pf = z(t0, x0, p0, tf)
return [xf[1]-1.; pf[2]]
end
jshoot(p0) = ForwardDiff.jacobian(shoot, p0)
p0_guess = [0.1; 0.1]
sol = nlsolve(shoot, jshoot, p0_guess; xtol=1e-8, method=:trust_region, show_trace=true);
p0_sol = sol.zero;
ode_sol = z((t0, tf), x0, p0_sol);
#
plt = plot([1, 1], [-2, 2], c="blue", xlabel="x1", ylabel="x2", linewidth=2.0) # cible
annotate!(plt, 1.05, -1.0, text("c=0", :left, :blue, 12))
# trajectoire optimale
t = ode_sol.t
x = ode_sol[1:2, :]
p = ode_sol[1:2, :]
i = argmin(abs.(t.-(t0+tf)/2.0))
plot!(plt, x[1, 1:i], x[2, 1:i], c="red", legend=false, xlims=(0,2.5), linewidth=2.0, arrow=arrow(:closed, :head))
plot!(plt, x[1, i:end], x[2, i:end], c="red", legend=false, xlims=(0,2.5), linewidth=2.0)
annotate!(plt, x[1,i], x[2,i]-0.2, text("x(•)", :top, :red, 12))
#
zf = ode_sol[:, end]
xf = zf[1:2]
pf = zf[3:4]
quiver!(plt, [xf[1]], [xf[2]], quiver=([pf[1]], [pf[2]]), c="green", linewidth=2.0) # vecteur adjoint final
annotate!(plt, xf[1]+0.5*pf[1], xf[2]+0.5*pf[2]-1e-1, text("p(tf)", :top, :green, 12))