It can also be imported with the command from qutip import *, that automatically imports all the QuTiP functions. However, here we use the first method, in order to explicitly see the QuTiP functions.
qutip.about()
QuTiP: Quantum Toolbox in Python
================================
Copyright (c) QuTiP team 2011 and later.
Current admin team: Alexander Pitchford, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Giguère, Boxi Li, Simon Cross, Asier Galicia, Paul Menczel, and Patrick Hopf.
Board members: Daniel Burgarth, Robert Johansson, Anton F. Kockum, Franco Nori and Will Zeng.
Original developers: R. J. Johansson & P. D. Nation.
Previous lead developers: Chris Granade & A. Grimsmo.
Currently developed through wide collaboration. See https://github.com/qutip for details.
QuTiP Version: 5.1.1
Numpy Version: 2.2.6
Scipy Version: 1.15.3
Cython Version: 3.1.1
Matplotlib Version: 3.10.3
Python Version: 3.13.4
Number of CPUs: 4
BLAS Info: Generic
INTEL MKL Ext: None
Platform Info: Linux (x86_64)
Installation path: /opt/hostedtoolcache/Python/3.13.4/x64/lib/python3.13/site-packages/qutip
Installed QuTiP family packages
-------------------------------
No QuTiP family packages installed.
================================================================================
Please cite QuTiP in your publication.
================================================================================
For your convenience a bibtex reference can be easily generated using `qutip.cite()`
9.1 Quantum Operators
Quantum operators play a crucial role in the formulation of quantum mechanics, representing physical observables and operations on quantum states. In QuTiP, operators are represented as Qobj instances, just like quantum states. This section introduces the creation and manipulation of quantum operators.
9.1.1 Creating Operators
Operators in quantum mechanics can represent measurements, such as position or momentum, and transformations, such as rotation. Let’s see how we can define some common operators in QuTiP.
The Annihilation Operator of the Quantum Harmonic oscillator
The harmonic oscillator is a fundamental model in quantum mechanics for understanding various physical systems. Its quantization leads to the concept of creation and annihilation operators, which respectively increase and decrease the energy of the system by one quantum of energy.
The annihilation operator, often denoted by \(\hat{a}\), acts on a quantum state to reduce its quantum number. The action of \(\hat{a}\) on a state \(|n\rangle\) is defined as:
\[
\hat{a} |n\rangle = \sqrt{n} |n-1\rangle
\]
Here, \(|n\rangle\) represents a quantum state with \(n\) quanta of energy (also known as a Fock state), and \(\sqrt{n}\) is the normalization factor. The matrix representation of the annihilation operator in an \(d\)-dimensional Hilbert space is given by an upper triangular matrix with the square roots of natural numbers as its off-diagonal elements.
# Define the annihilation operator for d-dimensional Hilbert spaced =7a = qutip.destroy(d)print("Annihilation operator (a) for d=7:")a
The Pauli matrices are fundamental in the study of quantum mechanics, representing the spin operators for a spin-1/2 particle and quantum two-level systems.
QuTiP supports various operations on operators, including addition, multiplication (both scalar and matrix), and the commutator. These operations are essential for constructing Hamiltonians, calculating observables, and more.
Example: Commutator of Pauli Matrices
The commutator of two operators \(A\) and \(B\) is defined as \([A, B] = AB - BA\). Let’s calculate the commutator of \(\sigma_x\) and \(\sigma_y\).
commutator_xy = qutip.commutator(sigma_x, sigma_y)print("Commutator of Sigma X and Sigma Y:")display(commutator_xy)commutator_xy ==2j* sigma_z
Quantum states describe the state of a quantum system. In QuTiP, states are represented again as Qobj instances. This section focuses on the representation and manipulation of quantum states.
9.2.1 Fock States
The most basic quantum states are the fock states, often denoted as \(|n\rangle\) (with \(n \in \mathbb{N}\)). Let’s see how we can create these in QuTiP.
9.2.2 Superposition States
Quantum mechanics allows particles to be in a superposition of states. Let’s create a superposition state.
Coherent states in QuTiP represent quantum states closest to classical waves, defined as \[
|\alpha\rangle = e^{-|\alpha|^2/2} \sum_{n=0}^{\infty} \frac{\alpha^n}{\sqrt{n!}} |n\rangle \, ,
\]
with minimal uncertainty.
The coherent state is an eigenstate of the annihilation operator \[
\hat{a} \vert \alpha \rangle = \alpha \vert \alpha \rangle
\]
Warning!
Remember that every Qobj lives in a truncated Hilbert space. If the \(\alpha\) value is too large, the state will become a non-physical state because it will touch the high energy levels of the truncated Hilbert space.
Quantum states can also be represented using density matrices, which are useful for describing mixed states.
Creating a Density Matrix
Let’s convert our superposition state into a density matrix.
# Creating a density matrix from a statedensity_matrix = superposition_state * superposition_state.dag() # Outer productprint("Density matrix of the superposition state:")density_matrix
The partial trace over a subsystem, say \(B\), of a composite system \(AB\), mathematically expresses as “tracing out” \(B\), leaving the reduced state of \(A\). For a bipartite state \(\rho_{AB}\), the partial trace over \(B\) is:
# Bell state between two qubitsphi_plus = ( qutip.tensor(qutip.spin_state(1/2, -1), qutip.spin_state(1/2, -1)) + qutip.tensor(qutip.spin_state(1/2, 1), qutip.spin_state(1/2, 1)) ).unit()# Reduced density matrix of the first qubitrho_1 = qutip.ptrace(phi_plus, 1)rho_1
We now apply the partial trace to a more complicated state, that is composed by two bosonic modes and two spins \(\vert j_1, m_1 \rangle\) and \(\vert j_2, m_2 \rangle\), with \(j_1 = 1\) and \(j_2 = \frac{1}{2}\), \(m_1 = 0\), and \(m_2 = 1\).
j1 =1j2 =1/2m1 =0m2 =1psi = qutip.tensor(qutip.fock(d, 3), qutip.fock(d, 1), qutip.spin_state(j1, 0), qutip.spin_state(j2, 1))# Trace only the second spin staterho_0 = qutip.ptrace(psi, [0, 1, 2])display(rho_0)# Trace only the first bosonic mode and the second spin staterho_1 = qutip.ptrace(psi, [1, 2])display(rho_1)# Trace all except the second bosonic moderho_2 = qutip.ptrace(psi, [1])rho_2
The eigenstates and eigenvalues of a system or an operator provide crucial insights into its properties. Let’s explore how to calculate these in QuTiP.
# Example: Eigenstates and eigenvalues of Pauli Zeigenvalues, eigenstates = sigma_z.eigenstates()print("Eigenvalues of Sigma Z:")display(eigenvalues)print("\n")print("Eigenstates of Sigma Z:")display(eigenstates)
The expectation value of an operator provides insight into the average outcome of a quantum measurement. For a quantum state \(|\psi\rangle\) and an operator \(\hat{O}\), the expectation value is given by:
Expectation values are crucial for predicting measurable quantities in quantum mechanics. Let’s compute the expectation value of the number operator \(\hat{n} = \hat{a}^\dagger \hat{a}\) for a coherent state, which represents a quantum state closest to a classical harmonic oscillator.
# Define the coherent state |psi> with alpha=2alpha =0.8psi = qutip.coherent(d, alpha)# Define the number operator n = a.dag() * an = a.dag() * a# Compute the expectation value of n for the state |psi>expectation_value_n = qutip.expect(n, psi)print("Expectation value of the number operator for |psi>:")display(expectation_value_n)print("\n")print("The squared modulus of alpha is:")display(abs(alpha) **2)
Expectation value of the number operator for |psi>:
0.639996733025295
The squared modulus of alpha is:
0.6400000000000001
9.5 A complete example: the Quantum Harmonic Oscillator
In Appendix A we have already defined the quantum harmonic oscillator, which is a fundamental model in quantum mechanics. In the energy eigenbasis, the quantum harmonic oscillator is described by the Hamiltonian
where \(\omega\) is the resonance frequency and \(\hat{a}\) is the bosonic annihilation operator. In this basis, the Hamiltonian is indeed diagonal, with eigenvalues \(E_n = \omega n\), where \(n \in \mathbb{N}\).
N =120# Hilbert space cutoffw =1# Resonance frequency of the harmonic oscillatora = qutip.destroy(N)H = w * a.dag() * aH
From the classical point of view, we are used to describe the harmonic oscillator in terms of position and momentum. In quantum mechanics, we can also express the system in terms of the position and momentum operators, which are related to the annihilation and creation operators as follows (\(\hbar = 1\)):
We now numerically diagonalize the position operator \(\hat{x}\), such that \(\hat{U}^\dagger \hat{x} \hat{U}\) is diagonal. Then we plot the eigenstates of the quantum harmonic oscillator in the new basis, obtained with
import matplotlib.pyplot as pltE, T = x.eigenstates()U = np.zeros((N, N)).astype(np.complex128)for i inrange(N): U[:,i] = T[i].full().flatten()U = qutip.Qobj(U)xlist = ( U.dag() * x * U ).diag()dx = xlist[1] - xlist[0]# Harmonic potentialV = w**2/2* xlist**2fig, ax = plt.subplots()ax.plot(xlist, V, color="black", ls="--", lw=2)for i inrange(5): factor =5# The purpose of this factor is to only make more visible the states ax.plot(xlist, factor * np.abs( (U.dag() * qutip.fock(N, i)).full() )**2+ i * w + w/2, lw=2)ax.set_xlabel(r"$x$")ax.set_xlim(-5, 5)ax.set_ylim(0, 5)# Show in Quartoplt.savefig("_tmp_fig.svg")plt.close(fig)SVG("_tmp_fig.svg")