SpinChain

class qugradlab.systems.semiconducting.esr.rotating_wave_approximation.SpinChain(spins: int, zeeman_detunings: ndarray[float], max_drive_strength: float, J_max: float, J_min: float = 0, feromagnetic: bool = True, use_graph: bool = True)[source]

Bases: Controls, QubitSystem

A qugrad.QuantumSystem for a spin chain with electron spin resonance (ESR) controls with a linear array of qubits under the rotating wave approximation. The Hamiltonian is given by

\[ H(t) = \frac{1}{4} \sum_{i=0}^{\texttt{spins}-1} \left[I_i(t) X_i + Q_i(t)Y_i\right] + \frac{1}{4} \sum_{i=0}^{\texttt{spins}-2} J_i(t)\left[Z_iZ_{i+1} +\cos(\omega_i t)\left[X_iX_{i+1}+Y_iY_{i+1}\right] +\sin(\omega_i t)\left[X_iY_{i+1}-Y_iX_{i+1}\right]\right], \]
where \(X_i\), \(Y_i\), and \(Z_i\) are the Pauli-x, -y, and -z operators acting on the \(i\)th spin, \(\omega_i\) are the Zeeman detunings, \(J_i(t)\) is the exchange coupling.

Attributes

H0

The systems drift Hamiltonian as a dim x dim matrix.

Hs

An array of the system's control Hamiltonians with shape (n_ctrl, dim, dim).

J_max

The maximum value of the exchange coupling \(J\)

J_min

The minimum value of the exchange coupling \(J\)

dim

The dimension of states in the quantum system.

evolver

The integrator used for time evolutions of the system.

ferromagnetic

Whether the exchange coupling is ferromagnetic or antiferromagnetic

hilbert_space

The Hilbert space of the system

max_drive_strength

The maximum drive strength that can be applied to the system

n_ctrl

The number of control Hamiltonians.

state_shape

The shape of the states in the system.

using_graph

Whether to use TensorFlow graphs during computation.

zeeman_detunings

The Zeeman detunings of the spins

Methods

H

Computes the system Hamiltonian for the specified control amplitudes.

__init__

Initialises a spin chain with ESR controls.

_envolope_processing

When calling any evolution method (listed in the See also section section) _pre_processing() is executed on the arguements before the control amplitudes are modulated by the frequencies during _envolope_processing() and then finally the modulated control amplitudes are used by the evolution method.

_pre_processing

When calling any evolution method (listed in the See also section) _pre_processing() is executed on the arguments before the control amplitudes are modulated by the frequencies (during _envolope_processing()) and then finally the modulated control amplitudes are used by the evolution method.

evolved_expectation_value

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the expectation value of a specified observable with respect to the final state using evolved_expectation_value() from PySTE.

evolved_expectation_value_all

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the expectation value of a specified observable with respect to the state at each time-step using evolved_expectation_value_all() from PySTE.

evolved_gate_infidelity

Evolves the system under the time-dependent Hamiltonian defined by the control amplitudes and computes the gate infidelity to the target gate using evolved_gate_infidelity() from PySTE.

evolved_inner_product

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the inner product of the final state vector with a fixed vector using evolved_inner_product() from PySTE.

evolved_inner_product_all

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the innper product of state at each time-step with a fixed vector using evolved_inner_product_all() from PySTE.

gate_gradient

Evolves the system under the time-dependent Hamiltonian defined by the control amplitudes and computes the gate infidelity to the target gate and then computes the gradient with respect to the first argument (args[0]) using gate_switching_function() from PySTE.

get_driving_pulses

When calling any evolution method (listed in the See also section) get_driving_pulses() is executed on the arguements before the evolution method.

get_evolution

Computes the unitary evolution of the system under the time-dependent Hamiltonian defined by the control amplitudes using get_evolution() from PySTE.

gradient

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the expectation value of a specified observable with respect to the final state and then computes the gradient of the final state with respect to the first argument (args[0]) using switching_function() from PySTE.

initialise_evolver

Initialises evolver with an evolver from PySTE.

propagate

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes using propagate() from PySTE.

propagate_all

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes using propagate_all() from PySTE and returns the state at each time-step.

propagate_collection

Evolves a collection of state vectors under the time-dependent Hamiltonian defined by the control amplitudes using propagate_collection() from PySTE.

pulse_form

Initialises a new QuantumSystem in which _pre_processing() corresponds to executing pulse_function() and piping the output into the previous definition of _pre_processing().

H(ctrl_amp: ndarray[float] | ndarray[Callable[[float], ndarray[float]]]) ndarray[complex] | Callable[[float], ndarray[complex]]

Computes the system Hamiltonian for the specified control amplitudes.

Parameters:

ctrl_amp (NDArray[Shape[s := Any_Shape, n_ctrl], float | Callable[[float], np.ndarray[float]]]) – The control amplitudes (stored in the last axis). The prior axes allow for multiple sets of control amplitudes to be passed and the Hamiltonian for each computed. The control amplitudes can be passed as np.ndarray[float] to compute the system Hamiltonian for a specific value of the control ampltiudes. Alternatively, the control amplitudes can be passed as np.ndarray[Callable[[float], np.ndarray[float]]] where each element is a function of time. This will generate a time-dependent Hamiltonian: a function that takes a single parameter (time) and returns the Hamiltonian at this time.

Returns:

Either the systems Hamiltonian stored in the last two axes (if specific control amplitudes were passed) or a collection of time-dependent Hamiltonians (if time-dependent controls were passed).

Return type:

NDArray[Shape[s, dim, dim], complex] | NDArray[Shape[s], Callable[[float], np.ndarray[complex]]]]

__init__(spins: int, zeeman_detunings: ndarray[float], max_drive_strength: float, J_max: float, J_min: float = 0, feromagnetic: bool = True, use_graph: bool = True)[source]

Initialises a spin chain with ESR controls. The Hamiltonian is given by:

\[ H(t) = \frac{1}{4} \sum_{i=0}^{\texttt{spins}-1} \left[I_i(t) X_i + Q_i(t)Y_i\right] + \frac{1}{4} \sum_{i=0}^{\texttt{spins}-2} J_i(t)\left[Z_iZ_{i+1} +\cos(\omega_i t)\left[X_iX_{i+1}+Y_iY_{i+1}\right] +\sin(\omega_i t)\left[X_iY_{i+1}-Y_iX_{i+1}\right]\right], \]
where \(X_i\), \(Y_i\), and \(Z_i\) are the Pauli-x, -y, and -z operators acting on the \(i\)th spin, \(\omega_i\) are the Zeeman detunings, \(J_i(t)\) is the exchange coupling.

Parameters:
  • spins (int) – The number of spins in the chain

  • zeeman_detunings (NDArray[Shape[spins], float]) – The Zeeman detuning of each of the spins

  • max_drive_strength (float) –

    The maximum drive strength that can be applied at a specific frequency and quadrature. That is if their are n_drive_ctrl frequencies and both quadratures are used then the maximum amplitude of the drive that can be applied to the device is:

    np.sqrt(2) * n_drive_ctrl * max_drive_strength
    

  • J_max (float) – The minimum value of the exchange coupling \(J\)

  • J_min (float) – The maximum value of the exchange coupling \(J\), by default 0

  • feromagnetic (bool) – If True, the exchange coupling is ferromagnetic. If False, the exchange coupling is antiferromagnetic. By default, True.

  • use_graph (bool) – Whether to use TensorFlow graphs during computation, by default True

_envolope_processing(ctrl_amp, dt: float, frequencies, number_channels: list[int]) tuple

When calling any evolution method (listed in the See also section section) _pre_processing() is executed on the arguements before the control amplitudes are modulated by the frequencies during _envolope_processing() and then finally the modulated control amplitudes are used by the evolution method.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

Returns:

The modulated control amplitudes

Return type:

tf.Tensor[Shape[n_time_steps, n_ctrl], tf.complex128]

_pre_processing(drive_ctrl_amp: ndarray[complex], drive_frequencies: ndarray[complex], J_ctrl_amp: ndarray[complex], initial_state: ndarray[complex], dt: float) tuple

When calling any evolution method (listed in the See also section) _pre_processing() is executed on the arguments before the control amplitudes are modulated by the frequencies (during _envolope_processing()) and then finally the modulated control amplitudes are used by the evolution method.

_pre_processing() can be overridden to produce desired pulse shapes. You can either override _pre_processing() directly by creating a child class, or you can use pulse_form().

For gradient() to function correctly _pre_processing() should be written in TensorFlow.

Parameters:
  • drive_ctrl_amp (NDArray[Shape[n_time_steps, n_drive_ctrl], complex]) – The control amplitudes for the global Rabi-drive Hamiltonian. These values should be in the range [-1, 1] and will be linearly rescaled to the range [− max_drive_strength, max_drive_strength] where -1 corresponds to the − max_drive_strength and 1 to the max_drive_strength.

  • drive_frequencies (NDArray[Shape[n_drive_ctrl], complex]) – The detuning frequencies from the rotating frame frequency to modulate the control amplitude of the global Rabi-drive Hamiltonian

  • J_ctrl_amp (NDArray[Shape[n_time_steps, n_J_ctrl], complex]) – The control amplitudes for the exchange Hamiltonians. These values should be in the range [-1, 1] and will be linearly rescaled to the range [J_min, J_max] where -1 corresponds to the J_min and 1 to the J_max.

  • initial_state (NDArray[Shape[dim], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

Returns:

A tuple of 1. The control amplitude envolopes 2. The initial state 3. The integrator time step 4. The frequencies to modulate the control amplitude envolopes with 5. A list of the number of channels for each control Hamiltonian

Warning

The number of channels for each control Hamiltonian must be stored as a list and not an NDArray or a TensorFlow tensor.

Return type:

tuple[tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128], tf.Tensor[Shape[state_shape], tf.complex128], float, tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128], list[int]]

evolved_expectation_value(ctrl_amp: ndarray[complex], initial_state: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int], observable: ndarray[complex]) complex

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the expectation value of a specified observable with respect to the final state using evolved_expectation_value() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

  • observable (NDArray[Shape[dim, dim], complex]) – The observable to take the expectation value of.

Warning

Keyword arguments are not supported.

Returns:

The expectation value.

Return type:

complex

evolved_expectation_value_all(ctrl_amp: ndarray[complex], initial_state: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int], observable: ndarray[complex]) ndarray[complex]

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the expectation value of a specified observable with respect to the state at each time-step using evolved_expectation_value_all() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

  • observable (NDArray[Shape[dim, dim], complex]) – The observable to take the expectation value of.

Warning

Keyword arguments are not supported.

Returns:

The expectation value of the state at each integrator time step (including the initial state) with respect to the observable.

Return type:

NDArray[Shape[n_time_steps+1], complex]

evolved_gate_infidelity(*args) float

Evolves the system under the time-dependent Hamiltonian defined by the control amplitudes and computes the gate infidelity to the target gate using evolved_gate_infidelity() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – This is a redundant parameter for this function.

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

  • target (NDArray[Shape[dim, dim], complex]) – The target gate to calculate the gate infidelity with respect to.

Warning

Keyword arguments are not supported.

Returns:

The gate infidelity

Return type:

float

See also

evolved_inner_product(*args) complex

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the inner product of the final state vector with a fixed vector using evolved_inner_product() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

  • fixed_vector (NDArray[Shape[dim, dim], complex]) – The fixed vector to calculate the inner product with.

Warning

Keyword arguments are not supported.

Returns:

The inner product of the evolved state vector with the fixed vector.

Return type:

complex

evolved_inner_product_all(*args) complex

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the innper product of state at each time-step with a fixed vector using evolved_inner_product_all() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

  • fixed_vector (NDArray[Shape[dim, dim], complex]) – The fixed vector to calculate the inner product with.

Warning

Keyword arguments are not supported.

Returns:

The inner product of state at each integrator time step (including the initial state) with the fixed vector.

Return type:

NDArray[Shape[n_time_steps+1], complex]

gate_gradient(*args) tuple[float, ndarray[float]]

Evolves the system under the time-dependent Hamiltonian defined by the control amplitudes and computes the gate infidelity to the target gate and then computes the gradient with respect to the first argument (args[0]) using gate_switching_function() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – This is a redundant parameter for this function.

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

  • observable (NDArray[Shape[dim, dim], complex]) – The observable to take the expectation value of.

Warning

Keyword arguments are not supported.

Returns:

A tuple of the gate infidelity value and the gradient.

Return type:

tuple[complex, NDArray[Shape[n_parameters], float]]

get_driving_pulses(ctrl_amp: ndarray[complex], initial_states: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int]) tuple[ndarray[complex], ndarray[complex], float]

When calling any evolution method (listed in the See also section) get_driving_pulses() is executed on the arguements before the evolution method.

Parameters:
  • ctrl_amp (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

Warning

Keyword arguments are not supported.

Returns:

A tuple of: 1. Control amplitudes 2. Initial state 3. Integrator time step

Return type:

tuple[NDArray[Shape[n_time_steps, n_ctrl], complex], NDArray[Shape[state_shape], complex], float]

get_evolution(*args) ndarray[complex]

Computes the unitary evolution of the system under the time-dependent Hamiltonian defined by the control amplitudes using get_evolution() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – This is a redundant parameter for this function.

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

Warning

Keyword arguments are not supported.

Returns:

The unitary corresponding to the evolution of the system.

Return type:

NDArray[Shape[dim, dim], complex]

gradient(ctrl_amp: ndarray[complex], initial_state: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int], observable: ndarray[complex]) tuple[float, ndarray[float]]

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes and computes the expectation value of a specified observable with respect to the final state and then computes the gradient of the final state with respect to the first argument (args[0]) using switching_function() from PySTE.

Parameters:
  • ctrl_amp (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (tf.Tensor[Shape[n_time_steps, total_n_channels], tf.complex128]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

  • observable (NDArray[Shape[dim, dim], complex]) – The observable to take the expectation value of.

Warning

Keyword arguments are not supported.

Returns:

A tuple of the expectation value and the gradient.

Return type:

tuple[complex, NDArray[Shape[n_parameters], float]]

initialise_evolver(sparse: bool = False, force_dynamic: bool = False)

Initialises evolver with an evolver from PySTE. PySTE is Python wrapper around the C++ header-only library Suzuki-Trotter-Evolver: a fast Schrödinger solver utilising the first-order Suzuki-Trotter expansion.

Warning

This can take a very long time to execute, especially for large Hilbert space dimensions. If you plan to evolve the same quantum system many times we recommended pickling the evolver.

Parameters:
  • sparse (bool) – Whether to use sparse or dense matrices during integration. To make a decision on whether sparse or dense matrices are likely to lead to faster integration you can consult the benchmarks at https://PySTE.readthedocs.io/en/latest/benchmarks.

  • force_dynamic (bool) –

    Whether to force PySTE to use a dynamic evolver.

    Note

    PySTE has precompiled evolvers for specific Hilbert space dimensions and numbers of control Hamiltonians. When these cannot be found PySTE uses less efficient evolvers with the Hilbert space dimension and the number of controls determined dynamically at runtime.

propagate(ctrl_amp: ndarray[complex], initial_state: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int]) ndarray[complex]

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes using propagate() from PySTE.

Parameters:
  • ctrl_amp (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

Warning

Keyword arguments are not supported.

Returns:

The final state

Return type:

NDArray[Shape[state_shape], complex]

propagate_all(ctrl_amp: ndarray[complex], initial_states: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int]) ndarray[complex]

Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes using propagate_all() from PySTE and returns the state at each time-step.

Parameters:
  • ctrl_amp (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The envolope control amplitudes

  • initial_state (NDArray[Shape[state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

Warning

Keyword arguments are not supported.

Returns:

The state at each integrator time step (including the initial state).

Return type:

NDArray[Shape[state_shape, n_time_steps+1], complex]

propagate_collection(ctrl_amp: ndarray[complex], initial_states: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int]) ndarray[complex]

Evolves a collection of state vectors under the time-dependent Hamiltonian defined by the control amplitudes using propagate_collection() from PySTE.

Parameters:
  • ctrl_amp (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The envolope control amplitudes

  • initial_states (NDArray[Shape[n_states, state_shape], complex]) – The initial state for the integrator

  • dt (float) – The itegration time step

  • frequencies (NDArray[Shape[n_time_steps, n_ctrl], complex]) – The frequencies to modulate the control amplitudes with

  • number_channels (list[int]) –

    The number of channels associated with each control Hamiltonian

    Warning

    This must be a list and not an NDArray or a TensorFlow tensor.

Warning

Keyword arguments are not supported.

Returns:

The final state

Return type:

NDArray[Shape[n_states, state_shape], complex]

pulse_form(pulse_function: Callable, path: str | None = None) PulseForm

Initialises a new QuantumSystem in which _pre_processing() corresponds to executing pulse_function() and piping the output into the previous definition of _pre_processing().

Parameters:
  • pulse_function (Callable) – The function to compose with _pre_processing().

  • append (bool, optional) – Whether to prepend (self._pre_processing(*pulse_function())) or append (pulse_function(*self._pre_processing())) pulse_function. By default False.

Returns:

The new QuantumSystem

Return type:

PulseForm

property H0: ndarray[complex]

The systems drift Hamiltonian as a dim x dim matrix.

See also

Hs

property Hs: ndarray[complex]

An array of the system’s control Hamiltonians with shape (n_ctrl, dim, dim).

See also

H0

property J_max: float

The maximum value of the exchange coupling \(J\)

property J_min: float

The minimum value of the exchange coupling \(J\)

property dim: int

The dimension of states in the quantum system.

See also

state_shape

property evolver: UnitaryEvolver

The integrator used for time evolutions of the system.

Note

The evolver can take a while to initialise and so is not initialised until evolver is is first used or when initialise_evolver() is called. Using evolver before calling initialise_evolver() initialises the evolver with the default parameters of initialise_evolver().

property ferromagnetic: bool

Whether the exchange coupling is ferromagnetic or antiferromagnetic

property hilbert_space: HilbertSpace

The Hilbert space of the system

property max_drive_strength: float

The maximum drive strength that can be applied to the system

property n_ctrl: int

The number of control Hamiltonians.

property state_shape: tuple[int]

The shape of the states in the system.

See also

dim

property using_graph: bool

Whether to use TensorFlow graphs during computation. Using a TensorFlow graph will increase the speed of computation. However, you have to be careful that function parameters have not been baked into the graph leading to unexpected behaviour.

property zeeman_detunings: ndarray[complex]

The Zeeman detunings of the spins