qugrad.systems.TransformedSystem¶
- class qugrad.systems.TransformedSystem(original_system: QuantumSystem, H0: ndarray[complex], Hs: ndarray[complex], hilbert_space: HilbertSpace)[source]¶
Bases:
QuantumSystemA base class for representing a transformation on a
qugrad.QuantumSystem.Attributes
An array of the system's control Hamiltonians with shape (
n_ctrl,dim,dim).The system before any transformations were applied.
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 system that was transformed into this system
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.
Performs a transformation on a
qugrad.QuantumSystem.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 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__(original_system: QuantumSystem, H0: ndarray[complex], Hs: ndarray[complex], hilbert_space: HilbertSpace)[source]¶
Performs a transformation on a
qugrad.QuantumSystem.- Parameters:
original_system (QuantumSystem) – The system to be transformed into this system
H0 (NDArray[Shape[
dim,dim], complex]) – The new drift HamiltonianHs (NDArray[Shape[”
n_ctrl,dim,dim”], complex] | NDArray[Shape[n_ctrl*dim,dim], complex]) – The new control Hamiltonians either as an array of control Hamiltonians or the control Hamiltonians stacked along the first axis.hilbert_space (HilbertSpace) – The new Hilbert space of the system
- _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
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(*args)[source]¶
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.This is a placeholder for
original_system._pre_processing().- Parameters:
*args – The placeholder parameters. The actual parameters will be the same as
original_system._pre_processing().- 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]]
- evolved_expectation_value(*args) complex[source]¶
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(*args) ndarray[complex][source]¶
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:
- Returns:
- NDArray[Shape[n_time_steps+1], complex] – The state at each integrator time step (including the initial
state).
See Also
——–
- get_driving_pulses(*args) tuple[ndarray[complex], ndarray[complex], float][source]¶
When calling any evolution method (listed in the See also section)
get_driving_pulses()is executed on the arguements before the evolution method.- Parameters:
*args – The placeholder parameters. The actual parameters will be the same as
original_system._pre_processing().- 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(*args) tuple[float, ndarray[float]][source]¶
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:
- 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
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(*args) ndarray[complex][source]¶
Evolves a state vector under the time-dependent Hamiltonian defined by the control amplitudes using
propagate()from PySTE.- Parameters:
*args – The placeholder parameters. The actual parameters will be the same as
original_system._pre_processing().- Returns:
The final state
- Return type:
NDArray[Shape[
state_shape], complex]
See also
- propagate_all(*args) ndarray[complex][source]¶
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:
*args – The placeholder parameters. The actual parameters will be the same as
original_system._pre_processing().- 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(*args) ndarray[complex][source]¶
Evolves a collection of state vectors under the time-dependent Hamiltonian defined by the control amplitudes using
propagate_collection()from PySTE.- Parameters:
*args – The placeholder parameters. The actual parameters will be the same as
original_system._pre_processing().- 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:
- property Hs: ndarray[complex]¶
An array of the system’s control Hamiltonians with shape (
n_ctrl,dim,dim).See also
- property base_system: QuantumSystem¶
The system before any transformations were applied. That is
base_systemis the recursiveoriginal_system(original_system.original_system.original_system....) untiloriginal_systemis no longer aTransformedSystem.
- property dim: int¶
The dimension of states in the quantum system.
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 n_ctrl: int¶
The number of control Hamiltonians.
- property original_system: QuantumSystem¶
The system that was transformed into this 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.