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:

BSSamples

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 generation

  • count (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 vector

  • mask – an optional mask

Return type:

FockState

Returns:

list of output_state

perceval.utils.statevector.tensorproduct(states)

Computes states[0] * states[1] * …