How-to Guides
Contents
- How to define a functional $J_T$ that depends on more than just target states
- How to deal with long-running calculations
Also see the following how-to guides from the QuantumPropagators documentation:
- How to implement a new propagation method
- How to specify the spectral range for a Chebychev propagation
- How to define a parameterized control
How to define a functional $J_T$ that depends on more than just target states
All of the optimization methods in the JuliaQuantumControl organization target a final-time functional $J_T$ via an argument J_T
, see QuantumControl.optimize
, that has the interface
J_T
: A functionJ_T(Ψ, trajectories)
that evaluates the final time functional from a listΨ
of forward-propagated states andproblem.trajectories
. The functionJ_T
may also take a keyword argumenttau
. If it does, a vector containing the complex overlaps of the target states (target_state
property of each trajectory inproblem.trajectories
) with the propagated states will be passed toJ_T
.
If the functional does not depend solely on a set of states Ψ
and a set of corresponding target states, that raises the question of how to include additional information in J_T
, within the constraints of the API that does not allow for additional arguments to J_T
. For example, we might want to reference an operator in J_T
whose expectation value should be maximized or minimized. There are three fundamental approaches:
- Hard-code the relevant data inside the definition of
J_T
. This is the most straightforward, but not very flexible. - Attach the data to the function
J_T
. This makes sense when the data is independent of thetrajectories
. Typically, this is done via a closure, e.g., via amake_J_T(op)
function that returns a functionJ_T(Ψ, trajectories)
that referencesJ_T
, or, in trivial cases, with an anonymous function for the keyword argumentJ_T
ofoptimize
. This is often the most flexible approach, but be aware of the performance implications of closures. - Attach the data to the
trajectories
. EachTrajectory
takes arbitrary keyword arguments that can be used to attach any data as attributes that a customJ_T
function may then reference. This makes sense when the data is unique to eachtrajectory
. In fact, the standard (but optional!)target_state
itself is an example of this; for functionals where atarget_state
does not make sense, it can be omitted and replaced by arbitrary other data, like maybe atarget_op
. Note that if thattarget_op
is the same for all trajectories, it would be less redundant to associate it withJ_T
, see item 2.
How to deal with long-running calculations
For any calculation that runs for more than a couple of minutes, use the QuantumControl.run_or_load
function. A particular case of a long-running calculation is a call to QuantumControl.optimize
for a system of non-trivial size. For optimizations in particular, there is QuantumControl.@optimize_or_load
that uses run_or_load
around optimize
, and stores the optimization result together with the (truncated) output from the optimization.
As an alternative to QuantumControl.run_or_load
, you might also consider the use of the DrWatson package, which provides DrWatson.produce_or_load
. It has a slightly more opinionated approach to saving and uses automatic file names based on parameters in a config
data structure. In contrast, QuantumControl.run_or_load
gives more control over the filename and does not force you to organize parameters in a config
.