krotov.optimize module¶
Summary¶
Data:
optimize_pulses |
Use Krotov’s method to optimize towards the given objectives |
__all__
: optimize_pulses
Reference¶
-
krotov.optimize.
optimize_pulses
(objectives, pulse_options, tlist, *, propagator, chi_constructor, mu=None, sigma=None, iter_start=0, iter_stop=5000, check_convergence=None, state_dependent_constraint=None, info_hook=None, modify_params_after_iter=None, storage='array', parallel_map=None, store_all_pulses=False)[source]¶ Use Krotov’s method to optimize towards the given objectives
Optimize all time-dependent controls found in the Hamiltonians of the given objectives.
Parameters: - objectives (list[Objective]) – List of objectives
- pulse_options (dict) –
Mapping of time-dependent controls found in the Hamiltonians of the objectives to a dictionary of options for that control. There must be an options-dict for each control. As numpy arrays are unhashable and thus cannot be used as dict keys, the options for a control that is an array must set using the key
pulse_options[id(control)] = ...
. The options-dict of any particular control must contain the following keys:'lambda_a'
: the Krotov step size (float value). This governs the overall magnitude of the pulse update. Large values result in small updates. Small values may lead to sharp spikes and numerical instability.'shape'
: Function S(t) in the range [0, 1] that scales the pulse update for the pulse value at t. This can be used to ensure boundary conditions (S(0) = S(T) = 0), and enforce smooth switch-on and switch-off. This can be a callable that takes a single argument t; or the values 1 or 0 for a constant update-shape. The value 0 disables the optimization of that particular control.
For example, for objectives that contain a Hamiltonian of the form
[H0, [H1, u], [H2, g]]
, whereH0
,H1
, andH2
areQobj
instances,u
is a numpy array of control values, andg
is a control function (a callable), a possible value for pulse_options would look like this:from krotov.shapes import flattop from functools import partial pulse_options = { id(u): {'lambda_a': 1.0, 'shape': 1}, g: dict( lambda_a=1.0, shape=partial( flattop, t_start=0, t_stop=10, t_rise=1.5 ) ) }
- tlist (numpy.ndarray) – Array of time grid values, cf.
mesolve()
- propagator (callable or list[callable]) – Function that propagates the
state backward or forwards in time by a single time step, between
two points in tlist. Alternatively, a list of functions, one for
each objective. If the propagator is stateful, it should be an
instance of
krotov.propagators.Propagator
. Seekrotov.propagators
for details. - chi_constructor (callable) – Function that calculates the boundary condition for the backward propagation. This is where the final-time functional (indirectly) enters the optimization.
- mu (None or callable) – Function that calculates the derivative
\(\frac{\partial H}{\partial\epsilon}\) for an equation of motion
\(\dot{\phi}(t) = -i H[\phi(t)]\) of an abstract operator \(H\) and an
abstract state \(\phi\). If None, defaults to
krotov.mu.derivative_wrt_pulse()
, which covers the standard Schrödinger and master equations. Seekrotov.mu
for a full explanation of the role of mu in the optimization, and the required function signature. - sigma (None or krotov.second_order.Sigma) – Function (instance of a
Sigma
subclass) that calculates the second-order contribution. If None, the first-order Krotov method is used. - iter_start (int) – The formal iteration number at which to start the optimization
- iter_stop (int) – The iteration number after which to end the optimization, whether or not convergence has been reached
- check_convergence (None or callable) – Function that determines whether
the optimization has converged. If None, the optimization will only
end when iter_stop is reached. See
krotov.convergence
for details. - state_dependent_constraint (None or callable) – Function that evaluates a state-dependent constraint. If None, optimize without any state-dependent constraint. Currently not implemented.
- info_hook (None or callable) – Function that is called after each
iteration of the optimization, for the purpose of analysis. Any
value returned by info_hook (e.g. an evaluated functional
\(J_T\)) will be stored, for each iteration, in the info_vals
attribute of the returned
Result
. The info_hook must have the same signature askrotov.info_hooks.print_debug_information()
. It should not modify its arguments in any way, except for shared_data. - modify_params_after_iter (None or callable) – Function that is called after each iteration, which may modify its arguments for certain advanced use cases, such as dynamically adjusting lambda_vals, or applying spectral filters to the optimized_pulses. It has the same interface as info_hook but should not return anything. The modify_params_after_iter function is called immediately before info_hook, and can transfer arbitrary data to any subsequent info_hook via the shared_data argument.
- storage (callable) – Storage constructor for the storage of
propagated states. Must accept an integer parameter N and return
an empty array-like container of length N. The default value
‘array’ is equivalent to
functools.partial(numpy.empty, dtype=object)
. - parallel_map (callable or tuple or None) – Parallel function evaluator.
If given as a callable, the argument must have the same
specification as
qutip.parallel.serial_map()
. A value of None is the same as passingqutip.parallel.serial_map()
. If given as a tuple, that tuple must contain three callables, each of which has the same specification asqutip.parallel.serial_map()
. These three callables are used to parallelize (1) the initial forward-propagation, (2) the backward-propagation under the guess pulses, and (3) the forward-propagation by a single time step under the optimized pulses. Seekrotov.parallelization
for details. - store_all_pulses (bool) – Whether or not to store the optimized pulses
from all iterations in
Result
.
Returns: The result of the optimization.
Return type: Raises: ValueError
– If any controls are not real-valued, or if any update shape is not a real-valued function in the range [0, 1].