TEMPO
Create time-dependent pulses.
@author: hakalas
- class tempo.pulse.Pulse(recipe: Pulse_recipe, start_time: float = 0, duration: float = 0, coeff_params: dict | None = None)[source]
Bases:
objectA class for creating pulses or time-dependent Hamiltonian objects.
One of the attributes of
Pulseis recipe, which is an instance ofpulse_recipe.Pulse_recipe, but there is a clear distinction between the two. Pulse recipe can be summarized as a blueprint (a recipe), while individual pulses are created according to the blueprint. Any number of pulses can be created with the same pulse recipe, but they can differ in the numerical values for the input parameters of the time-dependent coefficient.A dictionary of parameters is passed in the constructor and used to evaluate the time-dependent coefficient of the pulse. The dictionary should contain all of the entries listed in the pulse recipe’s recipe.param_keys list of labels.
- Parameters:
recipe (
pulse_recipe.Pulse_recipe) – Pulse_recipe instance to provide a model for the kind of pulse.start_time (float) – Start time of pulse.
duration (float) – Duration of pulse.
params (dict of float) – Dictionary of parameters to be passed in the coefficient function of recipe. All entries of recipe’s param_keys must be included in the dictionary.
- recipe
pulse_recipe.Pulse_recipeinstance to provide a model for the kind of pulse.- Type:
pulse_recipe.Pulse_recipe
- start_time
Start time of pulse.
- Type:
float
- duration
Duration of pulse.
- Type:
float
- coeff_params
Dictionary of parameters to be passed in the time-dependent coefficient function pulse_recipe.coeff_func.
- Type:
dict of float
- eval_coeff(t: float, args: dict = {}) float[source]
Evaluate coefficient of pulse at time t. If args is not given, then coeff_params is used as parameter input for coefficient function. If the pulse is off at time t, the coefficient is 0. Warning that using args will mean coeff_params is entirely ignored this execution.
- Parameters:
t (float) – The time for which to evaluate the coefficient.
args (dict of float, optional) – Parameters to use in recipe.coeff_func to evaluate coefficient. If not given, coeff_params is used.
- Returns:
pulsecoeff – Pulse coefficient at time t.
- Return type:
float
- serial_eval_coeff(t: float, args: dict = {}) float[source]
Evaluate coefficient of pulse at time t. Differs from eval_coeff in that the start- and endtimes of the pulse are not taken into account; the coefficient will be evaluated whether the pulse is on or off. This method is called by the method evolver.serial_evolve in the
evolver.Evolverclass.- Parameters:
t (float) – The time for which to evaluate the coefficient.
args (dict of float, default = {}) – Always an empty dictionary. coeff_params is used to evaluate the coefficient via recipe.coeff_func
- Returns:
coeff – Pulse coefficient at time t.
- Return type:
float
The Pulse_recipe class to create time-dependent pulse models.
@author: hakalas
- class tempo.pulse_recipe.Pulse_recipe(ham: Hamiltonian | None = None, param_keys: Iterable[str] | None = None, coeff_func: LambdaType | None = None)[source]
Bases:
objectA class for defining types of pulses.
The Pulse_recipe class is used to create models, or recipes, for different types of pulses or time-dependent Hamiltonians. The pulse.Pulse class is then used to create individual pulse instances.
The Pulse_recipe object is composed of a time-dependent coefficient and an operator. The constructor takes the operator, a list of parameter names, and a callback function. The function, which calculates the time-dependent coefficient of the operator at a time t, must have a signature
f(t: float, args: dict) -> float, for exampledef func(t, args): return args['amp']*np.cos(2*np.pi*args['freq']*t)
In this example the list of parameter names passed would be
keys = ['amp', 'freq']. The dictionary args is not part of the Pulse_recipe class; it is incorporated in the pulse.Pulse class, where one can evaluate the numerical value of the callback function based on a particular dictionary of values. The callback function should not include checks for whether the pulse is on or off; this can be achieved by defining the particular pulse’s start time and end time in the pulse.Pulse class.- Parameters:
ham (
hamiltonian.Hamiltonian) – Hamiltonian instance that describes the operator part of the pulse.param_keys (list of str) – List of names of parameters used in coeff_func. Names should be strings.
coeff_func (function) – Callback function that calculates the time-dependent coefficient using a time t and a dictionary of args.
- ham
Hamiltonian instance that describes the operator part of the pulse.
- Type:
hamiltonian.Hamiltonian
- param_keys
List of names of parameters used in coeff_func. Names should be strings.
- Type:
list of str
- coeff_func
Callback function that calculates the time-dependent coefficient using a time t and a dictionary of args.
- Type:
function
Sequence (list) of pulses.
@author: hakalas
- class tempo.pulse_sequence.Pulse_sequence(pulses: Iterable[Pulse] | None = None, Hstat: Hamiltonian | Qobj | None = None)[source]
Bases:
objectClass for creating sequences or lists of pulses.
A Pulse sequence object stores all pulses applied to a system during a single simulation. If there is a static (time-independent) Hamiltonian that applies throughout the entire simulation, this should be passed to the constructor separately.
The pulses may be added all at once in a list in the constructor, or they may be added one by one after the initialization of the pulse sequence.
- Parameters:
pulses (list of
pulse.Pulse) – List ofpulse.Pulseinstances that make up the pulse sequence. Pulses do not have to be ordered in any way.Hstat (
hamiltonian.Hamiltonianorqutip.Qobj, optional) – Time-independent Hamiltonian that applies at all times in the simulation.
- pulses
List of
pulse.Pulseinstances that make up the pulse sequence.- Type:
list of
pulse.Pulse
- Hstat
Time-independent Hamiltonian that applies at all times in the simulation.
- Type:
qutip.Qobj
- add_pulse(pls: Pulse | Iterable[Pulse])[source]
Add a pulse or list of pulses to the sequence.
- Parameters:
pls (
pulse.Pulseor list ofpulse.Pulse) – Pulse(s) to be added.
- remove_pulse(pls: Pulse | Iterable[Pulse])[source]
Remove a pulse or list of pulses from the sequence. If there are multiple copies of the same pulse in the sequence, then only the first instance is removed.
- Parameters:
pls (
pulse.Pulseor list ofpulse.Pulse) – Pulse(s) to be removed.
- timing_info() dict[source]
Get a dictionary with the start time, duration, and end time of the entire pulse sequence. Start time is the start time of the earliest pulse in the sequence, and end time is accordingly the end time of the last-ending pulse in the sequence. Note that the simulation itself may span a longer time duration than this if the times at which the state of the system is evaluated extend outside of the pulse sequence time range; for example, there may be a duration of time at the beginning or end of the simulation where only the static Hamiltonian applies.
The Hamiltonian class for representing Hamiltonian operators.
@author: hakalas
- class tempo.hamiltonian.Hamiltonian(ops: dict = {}, op_params: dict = {}, func: LambdaType | None = None)[source]
Bases:
objectA class for representing time-independent Hamiltonian operators.
The Hamiltonian object is composed of a numerical coefficient and an operator. The constructor takes a dictionary of parameters and a dictionary of operators, along with a callback function. The Python function tells the Hamiltonian how to combine the parameters and operators into a single term. For example, if the Hamiltonian term is \(a/bC\cdot D\), then
def func(ops, op_params): return op_params['a']/op_params['b']*ops['C']*ops['D'] ops = {'C': C, 'D': D} op_params = {'a': a, 'b': b}
- Parameters:
ops (dict of
qutip.Qobjorqutip.Qobj) – Dictionary of all operators that make up the final Hamiltonian. If the Hamiltonian has no specified numerical coefficient and is only composed of one operator, the operator may be passed directly as aqutip.Qobj. In this case params and func are not needed as inputs.op_params (dict, optional) – Dictionary of numerical parameters that make up the coefficient of the final Hamiltonian.
func (function, optional) – Callback function that takes the operators and parameters to combine.
- ops
Dictionary of all operators that make up the final Hamiltonian.
- Type:
dict of
qutip.Qobjorqutip.Qobj
- op_params
Dictionary of scalars that make up the coefficient of the final Hamiltonian.
- Type:
dict of float / float array, Qobj
- func
Callback function that takes the operators and scalars to combine.
- Type:
function
- property H
Time-independent Hamiltonian term as a
qutip.Qobj.- Parameters:
ops (dict of
qutip.Qobj, optional) – Dictionary of operators to pass to the callback function. If None, then the dictionary ops passed in the constructor is used.op_params (dict of float, optional) – Dictionary of numerical parameters to pass to the callback function. If None, then the dictionary op_params passed in the constructor is used.
- Returns:
H – Time-independent Hamiltonian with a numerical coefficient part and an operator part.
- Return type:
qutip.Qobj
Class to implement time-evolution of a state under applied pulses.
@author: hakalas
- class tempo.evolver.Evolver(state_init: Qobj | None = None, tlist: Iterable[float] | None = None, pulse_seq: Pulse_sequence | None = None, c_ops: Iterable[Qobj] | None = None, e_ops: Iterable[Qobj] | Iterable[LambdaType] | None = None, opts: Options | None = None)[source]
Bases:
objectTime-evolution of a state under a pulse sequence.
The Evolver object stores information about a particular pulse sequence simulation. Its evolve method evolves the given initial state state_init when the pulses in pulse_seq are applied. evolve relies on QuTiP’s qutip.mesolve method and the inputs c_ops, e_ops, and opts, if defined, are directly passed to mesolve. For these, see mesolve documentation https://qutip.org/docs/latest/apidoc/functions.html#module-qutip.mesolve.
- Parameters:
state_init (
qutip.Qobj) – Initial state vector or density matrix.pulse_seq (
pulse_sequence.Pulse_sequence) – Sequence of pulses to be applied to initial state.tlist (list of float) – List of times at which to evaluate the system’s state or the expectation value of the operator(s) in e_ops.
Hstat (
hamiltonian.Hamiltonianorqutip.Qobj, optional) – Time-independent Hamiltonian that applies at all times in the simulation.c_ops (list of
qutip.Qobj) – List of collapse operators.e_ops (list of
qutip.Qobjor callback functions) – List of operators for which to evaluate expectation values.opts (
qutip.Options) – Options for qutip.mesolve.
- state_init
Initial state vector or density matrix.
- Type:
qutip.Qobj
- tlist
List of times at which to evaluate the system’s state or the expectation value of the operator(s) in e_ops.
- Type:
list of float
- pulse_seq
Sequence of pulses to be applied to initial state.
- Type:
pulse_sequence.Pulse_sequence
- c_ops
List of collapse operators.
- Type:
list of
qutip.Qobj
- e_ops
List of operators for which to evaluate expectation values.
- Type:
list of
qutip.Qobjor callback functions
- opts
Options for mesolve.
- Type:
qutip.Options
- evolve(state_init: Qobj | None = None, tlist: Iterable[float] | None = None, pulse_seq: Pulse_sequence | None = None, c_ops: Iterable[Qobj] | None = None, e_ops: Iterable[Qobj] | None = None, opts: Options | None = None, method: str = 'serial', t_rtol: float = 1e-08) Result[source]
Evolve state_init using given pulse sequence. Collapse operators c_ops may be passed. Return a qutip.Result object which stores output for each timestamp given in tlist. If e_ops is left as None, qutip.Result contains the state vector of the system at each timestamp in its states attribute. Otherwise, the expectation values of the operator(s) listed in e_ops are stored in qutip.Result.expect in a 2-dimensional list.
The parameter evolve_method may take one of three values: ‘regular’, ‘serial’, or ‘serial_safe’. These describe different ways of solving the evolution of the state, but ultimately all use qutip.mesolve at their base. The two serial options significantly reduce runtime for evolving systems with many pulses, especially if the total number of pulses is much larger than the number of overlapping pulses at any given instant. ‘serial’ is the fastest of the three, but ‘serial_safe’ is slightly more true to the plain qutip.mesolve (denoted by ‘regular’) in terms of state accuracy. One can additionally control the relative error tolerance in integration by changing the parameter t_rtol, which applies to ‘serial’ and ‘serial_safe’.
- Parameters:
state_init (qutip.Qobj) – Initial state vector or density matrix.
tlist (list of float) – List of times at which to evaluate the system’s state or the expectation value of the operator(s) in e_ops.
pulse_seq (pulse_sequence.Pulse_sequence) – Pulse sequence instance containing the pulses for this simulation.
c_ops (list of qutip.Qobj) – List of collapse operators.
e_ops (list of qutip.Qobj) – List of operators for which to evaluate expectation values.
opts (qutip.Options) – Options for mesolve.
method (str {'regular', 'serial', 'serial_safe'}, default = 'serial') – Choice of which solving method to use.
t_rtol (float, default = 1e-8) – Relative time-step tolerance. Determines which relative time differences can be resolved in serial and serial_safe evolve methods.
- Returns:
result – System state or expectation value at tlist timestamps.
- Return type:
qutip.Result
- generate_H(pulse_seq: Pulse_sequence)[source]
Put Hamiltonian terms (static Hamiltonian and pulses) in a list together. The static Hamiltonian is first. Time-dependent (pulse) terms are [operator, callback function] pairs. The resulting list is in the correct format to be passed directly into mesolve as H. Return types are equivalent to mesolve.
- Parameters:
pulse_seq (
pulse_sequence.Pulse_sequence) – Sequence of pulses to be applied to the state.- Returns:
H – List of
qutip.Qobjinstances and [qutip.Qobj, callback function] pairs. List of Hamiltonian terms and their coefficients at each point in time.- Return type:
list of
qutip.Qobjor list of [qutip.Qobj, function]
- serial_evolve(pulse_seq: Pulse_sequence, state_init: Qobj, tlist: Iterable[float], c_ops: Iterable[Qobj], e_ops: Iterable[Qobj], opts: Options, t_rtol: float)[source]
- serial_generate_H(pulselist: Iterable[Pulse], safe: bool = False)[source]
Generate H (Hamiltonian) for use given a pulselist.
- Parameters:
pulselist (Iterable of type Pulse) – List with which to build the Hamiltonian.
safe (Boolean) – Whether or not we should use the serial_eval_coeff for the pulses (unsafe) or the eval_coeff (safe).
- Returns:
H – List with the Hamiltonians of each pulse and the coefficient [[H, coeff], …]
- Return type:
List
- serial_safe_evolve(pulse_seq: Pulse_sequence, state_init: Qobj, tlist: Iterable[float], c_ops: Iterable[Qobj] | None = None, e_ops: Iterable[Qobj] | None = None, opts: Iterable[Qobj] | Iterable[LambdaType] | None = None, t_rtol: float = 1e-08)[source]