State and StateVector
StateVector class reference
StateVector
is an important data structure class written in the native package exqalibur
. A StateVector is a
superposed state represented as a (complex) linear combination of BasicState
objects (its components), the
complex coefficients being probability amplitudes.
Constructor
__init__(bs: BasicState or List[int] or str = None)
Initialize a StateVector from a BasicState or data to create a BasicState (list of integers, string reprsentation)
>>> empty_sv = StateVector() # creates an empty state vector
>>> bs = BasicState("|1,0,1,0>")
>>> sv1 = StateVector(bs) # creates a state vector containing only |1,0,1,0> with amplitude 1
>>> sv2 = StateVector([1, 0, 1, 0]) # same
>>> sv3 = StateVector("|1,0,1,0>") # same
>>> assert sv1 == sv2 and sv1 == sv3
Property
n
List the possible values of n (number of photons) in the different components of the state vector
>>> sv = StateVector("|1,0,1,0>") + StateVector("|1,1,1,0>") + StateVector("|1,1,1,1>")
>>> print(sv.n)
{2, 3, 4}
Property
m
Return the mode count in the state vector
>>> sv = StateVector("|1,0>")
>>> sv.m
2
Method
normalize()
Normalize the state vector: amplitudes are normalized to follow the rule
sum(abs(probability_amplitudes)**2) == 1
and components with an amplitude near 0 are erased.
__str__(nsimplify: bool = True)
Stringifies the StateVector
, trying to simplify numerical representations of probability amplitude when
nsimplify
is True
. The string representation is normalized but the StateVector
is left untouched.
>>> sv = StateVector("|1,0>") - StateVector("|0,1>")
>>> print(sv) # calls __str__ with default parameters
sqrt(2)/2*|1,0>-sqrt(2)/2*|0,1>
>>> print(sv.__str__(nsimplify=False))
(0.7071067811865475+0j)*|1,0>+(-0.7071067811865475-0j)*|0,1>
Arithmetic operators
A StateVector
can be built using arithmetic. While only applying arithmetic operations to a state vector, no
automatic normalization is called, allowing the composition of state vectors through multiple Python statements.
>>> sv = StateVector("|1>") + StateVector("|2>")
>>> sv += StateVector("|3>")
>>> print(sv) # All components of sv have the same amplitude
sqrt(3)/3*|1>+sqrt(3)/3*|2>+sqrt(3)/3*|3>
StateVector
can be built with great freedom:
>>> sv = 0.5j * BasicState([1, 1]) - math.sqrt(2) * StateVector("|2,0>") + StateVector([0, 2]) * 0.45
>>> print(sv)
0.319275*I*|1,1>-0.903047*|2,0>+0.287348*|0,2>
Comparison operators
Comparing two StateVector
with operator ==
or !=
normalize them then compare that each
component and each probability amplitude are exactly the same.
Accessors and iterators
After building a StateVector
using arithmetic operations, there are different ways to retrieve
components and amplitudes.
>>> bs01 = BasicState("|0,1>")
>>> bs10 = BasicState("|1,0>")
>>> sv = bs10 - bs01
>>> sv.normalize()
>>> assert bs10 in sv # Ensure sv contains bs10 as a component
>>> print(sv[bs10]) # An amplitude can be retrieved by accessing the StateVector component
(0.7071067811865475+0j)
>>> for i in range(len(sv)): # Indexation. WARNING - the component order is not fixed (commutativity)
>>> print(sv[i], sv[sv[i]])
|1,0> (0.7071067811865475+0j)
|0,1> (-0.7071067811865475-0j)
>>> for component, amplitude in sv: # Iteration on the StateVector
>>> print(component, amplitude)
|1,0> (0.7071067811865475+0j)
|0,1> (-0.7071067811865475-0j)
>>> print(sv.keys()) # Components may also be retrieved as a list
[|1,0>, |0,1>]
Sampling methods
BasicState
components can be sampled from a StateVector
in regard of the probability amplitudes.
>>> sv = math.sqrt(0.75)*StateVector("|1,0>") + math.sqrt(0.25)*StateVector("|2,2>")
>>> print(sv.sample())
|1,0>
>>> print(sv.samples(10))
[|1,0>, |1,0>, |1,0>, |1,0>, |1,0>, |1,0>, |2,2>, |1,0>, |1,0>, |2,2>]
Method
measure(modes: List[int])
Perform a measure on one or multiple modes and collapse the remaining StateVector
. The resulting
states are not normalised by default.
Return a Python dictionary where keys are the possible measures (as BasicState
) and values are tuples containing
(probability, StateVector
).
>>> sv = StateVector("|0,1>") + StateVector("|1,0>")
>>> print(sv.measure([0]))
{|0>: (0.5, |1>), |1>: (0.5, |0>)}
The rest of the module
- class perceval.utils.statevector.BSCount(d=None)
Container that counts basic state events
- class perceval.utils.statevector.BSDistribution(d=None)
Time-Independant probabilistic distribution of Basic States
- sample(count, non_null=True)
Samples basic states from the BSDistribution
- Parameters:
count (
int
) – number of samples to draw- Return type:
- Returns:
a list of \(count\) samples
- static tensor_product(bsd1, bsd2, merge_modes=False, prob_threshold=0)
Compute the tensor product of two BasicState Distribution
- class perceval.utils.statevector.BSSamples(iterable=(), /)
Container that stores samples in a time ordered way
- class perceval.utils.statevector.ProbabilityDistribution
Time-Independent abstract probabilistic distribution of states
- class perceval.utils.statevector.SVDistribution(sv=None)
Time-Independent Probabilistic distribution of StateVectors
- sample(count, non_null=True)
Generate a sample StateVector from the SVDistribution
- Parameters:
non_null (
bool
) – excludes null states from the sample generationcount (
int
) – number of samples to draw
- Return type:
List
[StateVector
]- Returns:
a list of \(count\) samples
- perceval.utils.statevector.allstate_iterator(input_state, mask=None)
Iterator on all possible output states compatible with mask generating StateVector
- Parameters:
input_state (
Union
[FockState
,StateVector
]) – a given input state vectormask – an optional mask
- Return type:
FockState
- Returns:
list of output_state
- perceval.utils.statevector.tensorproduct(states)
Computes states[0] * states[1] * …