Open FernandoGago opened 6 years ago
Yes, that would definitely be nice to have. I'm not sure it will make it into the initial release, but we'll see.
In any case, the way to implement this is to add a parametrize
field to the PulseOptions
.
I actually think that it might be possible to optimize parametrized pulses without making any changes at all to the krotov
package (albeit not in the most user-friendly way): The workaround for a "proper" implementation might be to use a custom propagator
routine and custom mu
routine as arguments for optimize_pulses
.
One would set up the Hamiltonian as H = [H0, [H1, u]]
(this is what goes in the H
attribute of the objectives). Note that that the time dependency is u(t), not ϵ(t). The optimization will internally call the propagator
function with the argument [H0, [H1, c]]
where c
is the value of u(t=t_i)
at the midpoint of the i'th interval on the time grid. Since the propagator
is user-supplied, it can be a function that actually propagates H_0 + ϵ(u(t=t_i)) H_1
where ϵ(c) inside the function. That the propagator uses the physical field ϵ(t) instead of the underlying u(t).
In addition to the propagator
, the routine mu
will have to be user-supplied to implements ∂H/∂u. Since H is non-linear in u, it may be necessary to use a large value for lambda_a
in the pulse_options
, so that the pulse update in each iteration is relatively small (updated u ≈ guess u in each iteration).
So basically, Krotov will only know about u(t), not ϵ(t), and calculate updates for that u(t). The parametrization of the pulse is only taken into account for the propagation, which is external to the optimization, and via ∂H/∂u, which is the only place where the equation of motion enters the optimization explicitly. Obviously, there are some caveats: the Objectives.mesolve
will give nonsense, for example, since it won't know about the parametrization and propagate the linear H_0 + u(t) H_1
.
I might be overlooking something, but I think this should work.
This would be really nice! Is there any way to modify 'Objectives.mesolve' to return only a warning or to call it in a way that is meaningful?
I actually think that it might be possible to optimize parametrized pulses without making any changes at all to the
krotov
package (albeit not in the most user-friendly way): The workaround for a "proper" implementation might be to use a custompropagator
routine and custommu
routine as arguments foroptimize_pulses
.One would set up the Hamiltonian as
H = [H0, [H1, u]]
(this is what goes in theH
attribute of the objectives). Note that that the time dependency is u(t), not ϵ(t). The optimization will internally call thepropagator
function with the argument[H0, [H1, c]]
wherec
is the value ofu(t=t_i)
at the midpoint of the i'th interval on the time grid. Since thepropagator
is user-supplied, it can be a function that actually propagatesH_0 + ϵ(u(t=t_i)) H_1
where ϵ(c) inside the function. That the propagator uses the physical field ϵ(t) instead of the underlying u(t).In addition to the
propagator
, the routinemu
will have to be user-supplied to implements ∂H/∂u. Since H is non-linear in u, it may be necessary to use a large value forlambda_a
in thepulse_options
, so that the pulse update in each iteration is relatively small (updated u ≈ guess u in each iteration).So basically, Krotov will only know about u(t), not ϵ(t), and calculate updates for that u(t). The parametrization of the pulse is only taken into account for the propagation, which is external to the optimization, and via ∂H/∂u, which is the only place where the equation of motion enters the optimization explicitly. Obviously, there are some caveats: the
Objectives.mesolve
will give nonsense, for example, since it won't know about the parametrization and propagate the linearH_0 + u(t) H_1
.I might be overlooking something, but I think this should work.
Is there any way to modify 'Objectives.mesolve' to return only a warning or to call it in a way that is meaningful?
Not within the constraints of this "hacky" solution: There is no way that QuTiP could know whether it receives [H0, [H1, u]]
or [H0, [H1, ϵ]]
where u
and ϵ
are just numbers in either case.
This still leaves room for a more user-friendly implementation of parametrization that works transparently for the user, but requires some minimal changes in the Krotov code.
I actually have a working implementation in #92 that does all of this correctly. It still requires testing and documentation, though.
Specially when talking about bounded variables, using an optimization for a Hamiltonian H( f ( Ɛ(t) )) can be really useful, with Ɛ(t) being the parameter to optimize and f a function with a bounded image.
So as Christiane and Daniel R. used in one of their past works, for a variable α with bounds [a,b] one could write α = b*( tanh(Ɛ) + 1)/2 + a and try to optimize Ɛ. Due to the monotonic behaviour in tanh I don't think second order Krotov would be necessary for this to work, so it would be a nice feature to have even in first order Krotov.