Defining states¶
There are various ways of defining states in QOptCraft. The main type (class) is State
, which subclasses into PureState
and MixedState
. For convenience, we also have a Fock
subclass of PureState
, which allows us to create pure states in a handy way with sums and products.
import numpy as np
from qoptcraft.state import Fock, PureState, MixedState, State
Pure states¶
Initialization¶
Let's define a state using the Fock
subclass
state = (Fock(1, 0) + Fock(0, 1)) / np.sqrt(2)
state
0.71 * (1, 0) + 0.71 * (0, 1)
By default, states are normalized conserving the proportions between the coefficients; thus, we can write the previous state as
state = Fock(1, 0) + Fock(0, 1)
state
0.71 * (1, 0) + 0.71 * (0, 1)
This state is not the same as
state = Fock(1, 0) + 2 * Fock(0, 1)
state
0.45 * (1, 0) + 0.89 * (0, 1)
The class keeps track of both the coefficients and the amplitudes:
print(f"coefficients = {state.coefs}")
print(f"amplitudes = {state.amplitudes}")
coefficients = [1 2] amplitudes = [0.4472136 0.89442719]
We can also create pure states by initializing the PureState
class. This is done providing a list of photon number (fock) states, as a list of tuples, and a list of coefficients.
fock_list = [(2, 0), (0, 2)]
coef_list = [1 / np.sqrt(2), -1 / np.sqrt(2)]
PureState(fock_list, coef_list)
0.71 * (2, 0) + -0.71 * (0, 2)
Operations¶
We can do operations with pure states, like summing or computing tensor products:
state_1 = Fock(2, 0) + Fock(0, 2)
state_2 = Fock(1, 1)
state_1 - state_2
0.58 * (2, 0) + -0.58 * (1, 1) + 0.58 * (0, 2)
state_1 * state_2
0.71 * (2, 0, 1, 1) + 0.71 * (0, 2, 1, 1)
Attributes¶
There are a number of attributes we can access, including the number of photons
state_1.photons
2
the number of modes
state_1.modes
2
and the density matrix
state_1.density_matrix
array([[0.5+0.j, 0. +0.j, 0.5+0.j], [0. +0.j, 0. +0.j, 0. +0.j], [0.5+0.j, 0. +0.j, 0.5+0.j]])
Methods¶
We can retrieve the state in the Fock basis:
state_1.state_in_basis()
array([0.70710678+0.j, 0. +0.j, 0.70710678+0.j])
We can apply creation and annihilation operators
state = Fock(1, 0) + Fock(0, 1)
state.creation(mode=1)
0.58 * (1, 1) + 0.82 * (0, 2)
state = Fock(2, 0) + Fock(0, 2)
state.annihilation(mode=0)
(1, 0)
Mixed states¶
Mixed states can be created directly from the density matrix:
mixed_state = MixedState(density_matrix=np.eye(3) / 3, modes=2, photons=2)
mixed_state.density_matrix
array([[0.33333333, 0. , 0. ], [0. , 0.33333333, 0. ], [0. , 0. , 0.33333333]])
or from a mixture of pure states:
mixed_state = MixedState.from_mixture(pure_states=[state_1, state_2], probs=[0.5, 0.5])
mixed_state.density_matrix
array([[0.25+0.j, 0. +0.j, 0.25+0.j], [0. +0.j, 0.5 +0.j, 0. +0.j], [0.25+0.j, 0. +0.j, 0.25+0.j]])