SkeletalSystem¶
- class qugradlab.systems.skeletons.SkeletalSystem(drift_coefficients: list[ndarray], drift_skeletons: list[ndarray], ctrl_coefficients: list[ndarray], ctrl_skeletons: list[ndarray], hilbert_space: HilbertSpace, use_graph: bool = True)[source]¶
Bases:
QuantumSystemA quantum system with a Hamiltonian built upon an operator skeleton.
Attributes
An array of the system's control Hamiltonians with shape (
n_ctrl,dim,dim).The dimension of states in the quantum system.
The integrator used for time evolutions of the system.
The Hilbert space of the system
The number of control Hamiltonians.
The shape of the states in the system.
Whether to use TensorFlow graphs during computation.
Methods
Computes the system Hamiltonian for the specified control amplitudes.
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.When calling any evolution method (listed in the See also 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.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.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.When calling any evolution method (listed in the See also section)
get_driving_pulses()is executed on the arguements before the evolution method.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]) usingswitching_function()from PySTE.Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes using
propagate()from PySTE.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.Evolves a collection of state vectors under the time-dependent Hamiltonian defined by the control amplitudes using
propagate_collection()from PySTE.Initialises a new
QuantumSystemin which_pre_processing()corresponds to executingpulse_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 asnp.ndarray[float]to compute the system Hamiltonian for a specific value of the control ampltiudes. Alternatively, the control amplitudes can be passed asnp.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__(drift_coefficients: list[ndarray], drift_skeletons: list[ndarray], ctrl_coefficients: list[ndarray], ctrl_skeletons: list[ndarray], hilbert_space: HilbertSpace, use_graph: bool = True)[source]¶
- Parameters:
drift_coefficients (list[np.ndarray]) – The coefficients of the drift Hamiltonian
drift_skeletons (list[np.ndarray]) – The operator skeletons for the drift Hamiltonian
coefficients (list[np.ndarray]) – The coefficients of the control Hamiltonians
skeletons (list[np.ndarray]) – The operator skeletons for the control Hamiltonians
hilbert_space (HilbertSpace) – The Hilbert space of the system
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
The number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor a TensorFlow tensor.
- Returns:
The modulated control amplitudes
- Return type:
tf.Tensor[Shape[n_time_steps,
n_ctrl], tf.complex128]
- _pre_processing(ctrl_amp: ndarray[complex], initial_state: ndarray[complex], dt: float, frequencies: ndarray[complex], number_channels: list[int]) tuple¶
When calling any evolution method (listed in the See also 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()should be overridden to produce desired pulse shapes. You can either override_pre_processing()directly by creating a child class, or you can usepulse_form().For
gradient()to function correctly_pre_processing()should be written in TensorFlow.- Parameters:
ctrl_amp (NDArray[Shape[n_time_steps,
n_ctrl], complex]) – The envolope control amplitudesinitial_state (NDArray[Shape[
state_shape], complex]) – The initial state for the integratordt (float) – The itegration time step
frequencies (NDArray[Shape[n_time_steps,
n_ctrl], complex]) – The frequencies to modulate the control amplitudes withThe number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor a TensorFlow tensor.
- 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
listand not anNDArrayor 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]]
Warning
Keyword arguments are not supported.
- 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 integratordt (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
The number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor 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:
- 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 integratordt (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
The number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor 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 state at each integrator time step (including the initial state).
- Return type:
NDArray[Shape[n_time_steps+1], complex]
See also
- 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 amplitudesinitial_state (NDArray[Shape[
state_shape], complex]) – The initial state for the integratordt (float) – The itegration time step
frequencies (NDArray[Shape[n_time_steps,
n_ctrl], complex]) – The frequencies to modulate the control amplitudes withThe number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor 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]
- 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]) usingswitching_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 integratordt (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
The number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor a TensorFlow tensor.observable (NDArray[Shape[
dim,dim], complex]) – The observable to take the expectation value of.
Warning
Keyword arguments are not supported.
- initialise_evolver(sparse: bool = False, force_dynamic: bool = False)¶
Initialises
evolverwith 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.
- 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 amplitudesinitial_state (NDArray[Shape[
state_shape], complex]) – The initial state for the integratordt (float) – The itegration time step
frequencies (NDArray[Shape[n_time_steps,
n_ctrl], complex]) – The frequencies to modulate the control amplitudes withThe number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor a TensorFlow tensor.
Warning
Keyword arguments are not supported.
- Returns:
The final state
- Return type:
NDArray[Shape[
state_shape], complex]
See also
- 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 amplitudesinitial_state (NDArray[Shape[
state_shape], complex]) – The initial state for the integratordt (float) – The itegration time step
frequencies (NDArray[Shape[n_time_steps,
n_ctrl], complex]) – The frequencies to modulate the control amplitudes withThe number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor 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[n_time_steps+1,
state_shape], complex]
See also
- 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 amplitudesinitial_states (NDArray[Shape[n_states,
state_shape], complex]) – The initial state for the integratordt (float) – The itegration time step
frequencies (NDArray[Shape[n_time_steps,
n_ctrl], complex]) – The frequencies to modulate the control amplitudes withThe number of channels associated with each control Hamiltonian
Warning
This must be a
listand not anNDArrayor a TensorFlow tensor.
Warning
Keyword arguments are not supported.
- Returns:
The final state
- Return type:
NDArray[Shape[n_states,
state_shape], complex]
See also
- pulse_form(pulse_function: Callable, path: str | None = None) PulseForm¶
Initialises a new
QuantumSystemin which_pre_processing()corresponds to executingpulse_function()and piping the output into the previous definition of_pre_processing().- Parameters:
pulse_function (Callable) – The function to compose with
_pre_processing().- Returns:
The new
QuantumSystem- Return type:
PulseForm
- property Hs: ndarray[complex]¶
An array of the system’s control Hamiltonians with shape (
n_ctrl,dim,dim).See also
- 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 callinginitialise_evolver()initialises the evolver with the default parameters ofinitialise_evolver().
- property hilbert_space: HilbertSpace¶
The Hilbert space of the system
- 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.