Getting Started¶
What is PySTE¶
PySTE is a Python wrapper around Suzuki-Trotter-Evolver: a header-only library for evolving unitaries and states under the Schrödinger equation,
using the first-order Suzuki-Trotter expansion and computing switching functions. This library assumes Hamiltonians take the form:
where \(H_0\) is called the drift Hamiltonian and \(\left\{H_j\right\}_{j=1}^{\textrm{length}}\) are the control Hamiltonians which are modulated by the control amplitudes \(\left\{a_j(t)\right\}_{j=1}^{\textrm{length}}\). PySTE integrates the Schrödinger equation by diagonalising the drift and control Hamiltonians ahead of time so that no matrix exponentials are required in the Suzuki-Trotter expansion. This yields an upfront cost of \(O(\dim^3)\) where \(\dim\) is the dimension of the vector space the Hamiltonians act upon. However, integrating the Schrödinger equation will scale with \(\dim\) as \(O(\dim^2)\) opposed to \(O(\dim^3)\).
This user guide is almost identical to the user guide for Suzuki-Trotter-Evolver but with C++ examples replaced with Python examples.
Installation¶
PySTE can be installed as follows:
pip install py-ste
However, the package should be imported as:
import py_ste
Support¶
Current support:
macOS Intel |
macOS Apple Silicon |
Windows 64bit |
Windows 32bit |
Windows Arm64 |
manylinux |
Other Linux |
|
|---|---|---|---|---|---|---|---|
CPython 3.8 |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
Build from source |
CPython 3.9 |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
Build from source |
CPython 3.10 |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
Build from source |
CPython 3.11 |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
Build from source |
CPython 3.12 |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
Build from source |
CPython 3.13 |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
Build from source |
CPython 3.14 |
✅ |
✅ |
✅ |
✅ |
✅ |
✅ |
Build from source |
Currently, the pre-built wheels only include the dynamic evolvers. For the faster static evolvers please build from source.
Requirements¶
Requires:
NumPy (>= 1.21, < 3)
Suzuki-Trotter-Evolver (== 1.1.0, packaged with PySTE)
Eigen3 (== 3.4.90, packaged with PySTE)
Note that Suzuki-Trotter-Evolver and Eigen3 are packaged with PySTE and so do not need to be installed separately.
If on Linux and using a conda environment you may encounter an error
version `GLIBCXX_...' not found
to fix this you also need to execute:
conda install -c conda-forge libstdcxx-ng
Additional requirements for testing¶
Additional requirements for benchmarking¶
Build from source¶
There are several flags that can be passed which will rebuild PySTE from source using various optimisations. The flags are:
--config-setting="cmake.define.NCTRL_FIXED_SIZES=RANGE"
Defines the strategy used to compile evolvers with a fixed number of controls. The options are:OFF: There will only be evolvers with a dynamic number of controls.SINGLE: There will only be a single evolver with a fixed number of controls specified by--config-setting="cmake.define.NCTRL=...".RANGE(default option): There will be evolvers with a fixed number of controls in the range \([1,\)MAX_NCTRL\(]\) whereMAX_NCTRLcan be set with--config-setting="cmake.define.MAX_NCTRL=..."POWER: The evolvers with a fixed number of controls will have a number of controls given by powers in the range \([1,\)MAX_POWER_NCTRL\(]\) of the baseBASE_NCTRLwhereMAX_POWER_NCTRLcan be set with--config-setting="cmake.define.MAX_POWER_NCTRL=..."andBASE_NCTRLwith--config-setting="cmake.define.BASE_NCTRL=..."
--config-setting="cmake.define.NCTRL=1"
The number of controls when using--config-setting="cmake.define.NCTRL_FIXED_SIZES=SINGLE". A positive integer, by default 1.--config-setting="cmake.define.MAX_NCTRL=14"
The maximum number of controls when using--config-setting="cmake.define.NCTRL_FIXED_SIZES=RANGE". A positive integer, by default 14.--config-setting="cmake.define.MAX_POWER_NCTRL=3"
The maximum power when using--config-setting="cmake.define.NCTRL_FIXED_SIZES=POWER". A positive integer, by default 3.--config-setting="cmake.define.BASE_NCTRL=2"
The base of the powers when using--config-setting="cmake.define.NCTRL_FIXED_SIZES=POWER". A positive integer, by default 2.--config-setting="cmake.define.DIM_FIXED_SIZES=RANGE"
Defines the strategy used to compile evolvers with a fixed vector space dimension. The options are:OFF: There will only be evolvers with a dynamic vector space dimension.SINGLE: There will only be a single evolver with a fixed vector space dimension specified by--config-setting="cmake.define.DIM=...".RANGE(default option): There will be evolvers with a fixed vector space dimension in the range \([1,\)MAX_DIM\(]\) whereMAX_DIMcan be set with--config-setting="cmake.define.MAX_DIM=..."POWER: The evolvers with a fixed vector space dimension will have a vector space dimension given by powers in the range \([1,\)MAX_POWER_DIM\(]\) of the baseBASE_DIMwhereMAX_POWER_DIMcan be set with--config-setting="cmake.define.MAX_POWER_DIM=..."andBASE_DIMwith--config-setting="cmake.define.BASE_DIM=..."
--config-setting="cmake.define.DIM=2"
The vector space dimension when using--config-setting="cmake.define.DIM_FIXED_SIZES=SINGLE". A positive integer, by default 2.--config-setting="cmake.define.MAX_DIM=16"
The maximum vector space dimension when using--config-setting="cmake.define.DIM_FIXED_SIZES=RANGE". A positive integer, by default 16.--config-setting="cmake.define.MAX_POWER_DIM=4"
The maximum power when using--config-setting="cmake.define.DIM_FIXED_SIZES=POWER". A positive integer, by default 4.--config-setting="cmake.define.BASE_DIM=2"
The base of the powers when using--config-setting="cmake.define.DIM_FIXED_SIZES=POWER". A positive integer, by default 2.
For example,
pip install --no-binary py-ste py-ste \
--no-cache-dir \
--config-setting="cmake.define.NCTRL_FIXED_SIZES=SINGLE" \
--config-setting="cmake.define.NCTRL=2" \
--config-setting="cmake.define.DIM_FIXED_SIZES=POWER" \
--config-setting="cmake.define.MAX_POWER_DIM=3" \
--verbose
will build PySTE from source and optimises evolvers at compile time with 2 control Hamiltonians acting on a vector space of dimensions 2, 4, and 8. Increasing the number of optimised evolvers increases the compile time. The --no-binary py-ste flag instructs pip to build py-ste from source and the following py-ste instructs pip that py-ste is one of the packages to collect (indeed the only package). The --no-cache-dir flag ensures that a cached .whl file is not used instead and the package is actually built from source. Finally, the --verbose flag allows the progress of the build to be seen. This is useful as the builds can often take a long time.
Note building from source requires approximately 16GB of RAM.
Quick Start¶
A good starting point in experimenting with a new integrator for quantum systems is to try and reproduce a Rabi Oscillation. Consider the Hamiltonian
where \(X\) and \(Z\) are the Pauli-\(x\) and -\(z\) matrices, respectively. This Hamiltonian produces on resonance Rabi-oscillations at a frequency \(f\). Suppose we initialise a in the state \(\psi(0)=\begin{pmatrix}1&0\end{pmatrix}^\intercal\) and want to know the state \(\psi(t=T)\) at a time \(t=T\). The following program will print this state to the console:
# examples/Rabi_oscillation.py
import numpy as np
from py_ste import get_unitary_evolver
X = np.array([[0, 1], # Pauli X
[1, 0]])
Z = np.array([[1, 0], # Pauli Z
[0, -1]])
# Parameters
v: float = 1
f: float = 1
T: float = 1
N: int = 1000
initial_state = np.array([1, 0], dtype=np.complex128)
# Setting up the evolver
drift_hamiltonian = v/2 * Z
control_hamiltonian = X
evolver = get_unitary_evolver(drift_hamiltonian, control_hamiltonian)
# Specifying the control amplitudes
dt = T / N
ts = dt*np.arange(N, dtype=np.complex128)
ctrl_amp = f*np.cos(v * ts)
# Propagating the initial state
psi = evolver.propagate(ctrl_amp, initial_state, dt)
# Outputting the final state
print(psi)