qubiter.StateVec module

class qubiter.StateVec.StateVec(num_bits, arr=None)[source]

Bases: object

This class is a wrapper for its main attribute, a complex numpy array self.arr with shape [2]*num_bits. The class also provides functions for performing calculations on dictionaries of the objects of this class StateVec. The keys of these dictionaries of state vectors are strings that we call branch_keys, because they name “branches” in class SEO_simulation. This class also provides a function for constructing from such dictionaries of state vectors, a density matrix which is a 2 dim square numpy array of dimension 2^num_bits.

IMPORTANT: See docstring of method get_traditional_st_vec() for explanation of qubit ordering conventions and shape of self.arr

Variables:
  • arr (np.ndarray) – a complex array of shape [2]*num_bits
  • num_bits (int) –
__init__(num_bits, arr=None)[source]

Constructor

Parameters:
  • num_bits (int) –
  • arr (np.ndarray) –
__str__()[source]

Returns str(self.arr)

Returns:
Return type:str
describe_self(print_st_vec=False, do_pp=False, omit_zero_amps=False, show_pp_probs=False, ZL=True, plot_st_vec_pd=False)[source]

Prints a description of self.

Parameters:
  • print_st_vec (bool) – if True, prints the final state vector (which may be huge. For n qubits, it has 2^n components.)
  • do_pp (bool) – pp= pretty print. Only used if print_st_vec=True. For pp=False, it prints final state vector in usual numpy array print style. For pp=True, it prints final state vector as column of (index, array value) pairs.
  • omit_zero_amps (bool) – If print_st_vec=True, pp=True and this parameter is True too, will omit states with zero amplitude
  • show_pp_probs (bool) – If True, will show probability of each standard basis state
  • ZL (bool) – If True, multi-index of ket in ZL (Zero bit Last) convention. If False, multi-index of ket in ZF (Zero bit First) convention.
  • plot_st_vec_pd (bool) – If True, plots state vector’s probability distribution
Returns:

Return type:

None

static describe_st_vec_dict(st_vec_dict, **kwargs)[source]

Calls describe_self() for each branch of st_vec_dict

Parameters:
  • st_vec_dict (dict[str, StateVec]) –
  • kwargs (dict[]) – the keyword arguments of describe_self()
Returns:

Return type:

None

static get_bit_probs(num_bits, pd)[source]

Returns a list whose jth item is, for the jth qubit, the pair (p, 1-p), where p is the probability that the jth qubit is 0, if the state of all other qubits is ignored.

Does not assume that pd is normalized to 1.

Parameters:
  • num_bits (int) –
  • pd (np.ndarray) – probability distribution of shape (2^num_bits,) IMP: assumed to be indexed in ZL convention
Returns:

Return type:

list[tuple[float, float]]

static get_counts_from_obs_vec(num_bits, obs_vec, use_bin_labels=True, omit_zero_counts=True)[source]

This method takes as input an observations vector obs_vec such as returned by another method in this class, namely get_observations_vec(). This method returns an OrderedDict called state_name_to_count that maps the names of states to the number of times they occur in obs_vec. If use_bin_labels=True, state names are a string composed of a binary number that is num_bits long, followed by ‘ZL’ because ZL convention is assumed. If use_bin_labels=False, state names are ‘0’, ‘1’, ‘2’, etc.

Parameters:
  • num_bits (int) –
  • obs_vec (np.ndarray) –
  • use_bin_labels (bool) –
  • omit_zero_counts (bool) –
Returns:

Return type:

OrderedDict[str, int]

static get_den_mat(num_bits, st_vec_dict)[source]

Returns a density matrix (indexed in ZL convention) constructed from st_vec_dict which is a dict from strings to StateVec.

The rows and columns are always labelled 0, 1, 2, .. or binary representation thereof, regardless of whether ZL or ZF convention. To switch between bin to dec representations of labels, see docstring of get_traditional_st_vec().

Parameters:
  • num_bits (int) –
  • st_vec_dict (dict[str, StateVec]) –
Returns:

Return type:

np.ndarray

static get_den_mat_pd(den_mat)[source]

Returns the diagonal of den_mat (so indexed in ZL convention) . den_mat is expected to be a density matrix returned by get_den_mat()

Parameters:den_mat (np.ndarray) – density matrix, shape=(dim, dim) where dim=2^num_bits, indexed in ZL convention.
Returns:
Return type:np.ndarray
static get_emp_state_vec_from_emp_pd(num_bits, emp_pd)[source]

This method takes as input an empirical probability distribution emp_pd and it returns an empirical state vector calculated from emp_pd. This requires reshaping emp_pd to the shape [2]*num_bits, permuting its indices from the ZL to the ZF convention, and then taking the sqrt of the components to get an amplitude instead of a probability. All amplitudes of the output state vector are real though.

Parameters:
  • num_bits (int) –
  • emp_pd (np.ndarray) – its shape is (1<<num_bits,)
Returns:

Return type:

StateVec

static get_empirical_pd_from_counts(num_bits, state_name_to_count)[source]

This method takes as input “the counts dict” (i.e., an OrderedDict called state_name_to_count which is produced by another method in this class, namely get_counts_from_obs_vec()). This method returns an empirical probability distribution emp_pd calculated from the counts dict. emp_pd indices are ints referring to qubit states labelled in the ZL convention.

Parameters:
  • num_bits (int) –
  • state_name_to_count (OrderedDict[str, int]) –
Returns:

emp_pd – its shape is (1<<num_bits,)

Return type:

np.ndarray

static get_entropy(den_mat, method='eigen')[source]

Returns entropy of density matrix den_mat. Uses natural log for entropy.

Parameters:
  • den_mat (np.ndarray) – Density matrix. Eigenvalues must be non-negative and sum to 1
  • method (str) – method used to calculate log of array. Either ‘eigen’ or ‘pade’
Returns:

Return type:

float

static get_ground_st_vec(num_bits)[source]

Returns StateVec for the ground state |0>|0>|0>…|0>, where |0> = [ 1,0]^t and |1> = [0,1]^t, t = transpose

Parameters:num_bits (int) –
Returns:
Return type:StateVec
static get_impurity(den_mat)[source]

Returns abs(trace(den_mat^2) -1). This is zero iff the density matrix den_mat represents a pure state. For example, for a pure state den_mat = |a><a|, den_mat^2 = den_mat = |a><a| so this quantity is indeed zero.

Parameters:den_mat (np.nparray) – density matrix, shape=(dim, dim) where dim=2^num_bits
Returns:
Return type:float
get_mean_value_of_real_diag_mat(real_arr)[source]

In Quantum Mechanics, one often needs to calculate the mean value of a Hermitian operator H, mean= <psi|H|psi>. Let H = U^dag D U, where U is unitary and D is real diagonal matrix. If self = U|psi>, then this reduces to finding mean= <self|D|self>. So must decompose U into a SEO and evolve, using SEO_simulator, to the state U|psi>.

Parameters:real_arr (np.ndarray) – a real array of shape=[2]^num_bits (same shape as self.arr). If flattened, real_arr contains the diagonal of the matrix D. If U is a Kronecker prod of 2-dim unitary matrices, the flattened real_arr can be obtained as Kronecker product of spinors, i.e., shape=( 2, ) arrays.
Returns:
Return type:float
static get_observations_vec(num_bits, pd, num_shots, rand_seed=None)[source]

vec = vector

num_shots (number of shots) is often called number of trials or number of samples.

For num_shots=1, this method returns an int (actually, a 1 X 1 array with an int in it) in range(1<<num_bits) chosen according to the probability distribution pd for num_bits qubits. If the output int were to be expressed in binary notation, its last, rightmost bit would be the measurement of the 0th qubit (because pd is assumed to be in ZL convention).

For num_shots>1, the method returns an np.ndarray of shape ( num_shots,) with the result of doing num_shots repetitions of what was done for num_shots=1.

Does not assume that pd is normalized to 1.

Parameters:
  • num_bits (int) –
  • pd (np.ndarray) – probability distribution of shape (2^num_bits,) IMP: assumed to be indexed in ZL convention
  • num_shots (int) –
  • rand_seed (int) –
Returns:

shape (num_shots,)

Return type:

np.ndarray

static get_partial_tr(num_bits, den_mat, traced_bits_set)[source]

Returns the partial trace of a density matrix den_mat. Traces over qubits in set traced_bits_set. To get full trace, just do np.trace( den_mat)

Parameters:
  • num_bits (int) –
  • den_mat (np.ndarray) – if dim=2^num_bits, this function assumes that den_mat has shape (dim, dim) and that it’s indexed in the ZL convention so qubit 0 corresponds to axis num_bits-1.
  • traced_bits_set (set[int]) – Set of qubits being traced over
Returns:

Return type:

np.ndarray

get_pd()[source]

Returns copy of self.get_traditional_st_vec() with amplitudes replaced by probabilities. pd = probability distribution. So returns one column array indexed in ZL convention like the traditional state vec is. Doesn’t check that the resulting array sums to 1.

Returns:probability distribution of shape (2^num_bits,) IMP: will be indexed in ZL convention
Return type:np.ndarray
static get_random_st_vec(num_bits, rand_seed=None)[source]

Returns StateVec for random state sum_b^n A(b^n)|b^n>, b^n in {0, 1}^n, where n=num_bits and sum_b^n |A( b^n)|^2 = 1

Parameters:
  • num_bits (int) –
  • rand_seed (int) –
Returns:

Return type:

StateVec

static get_standard_basis_st_vec(spin_dir_list, ZL=True)[source]

If ZL = True, returns StateVec for state …|s2>|s1>|s0>, where spin_dir_list=[…,s2, s1, s0], s_j in {0, 1} for all j, |0> = [1, 0]^t and |1> = [0,1]^t, t = transpose. If ZL = False, same except spin_dir_list=reversed([…,s2, s1, s0]).

Parameters:
  • spin_dir_list (list[int]) –
  • ZL (bool) – True(False) if last(first) entry of spin_dir_list refers to qubit 0
Returns:

Return type:

StateVec

static get_style_dict(style)[source]

Given a style string as input, this method returns a dict mapping various strings denoting parameters of the method StateVec.describe_self() to their bool values for the input style.

Parameters:style (str) –
Returns:
Return type:dict[str, bool]
get_total_prob()[source]

Returns total probability of self.

Returns:
Return type:float
get_traditional_st_vec()[source]

IMPORTANT: Internally, self.arr in Qubiter has shape [2]*num_bits and assumes ZF convention because that way a numpy axis and a qubit number are the same thing. However, the traditional way of writing a state vector is as a column array of dimension 1<< num_bits in the ZL convention.

This function returns the traditional view. So it reshapes ( flattens) the array and it reverses the axes (reversing axes takes it from ZF to ZL).

The rows are always labelled 0, 1, 2, 3, … or the binary representation thereof, regardless of whether ZL or ZF convention. One can go from digital to binary labels and vice versa using

Examples

>>> x = np.binary_repr(3, width=4)
>>> x
'0011'
>>> int(x, 2)
3
Returns:
Return type:np.array
static is_zero(st_vec)[source]

Returns True iff an object of this class is None or its parameter ‘arr’ is None

Parameters:st_vec (StateVec|None) –
Returns:
Return type:bool
pp_arr_entries(omit_zero_amps=False, show_pp_probs=False, ZL=True)[source]

pp=pretty print. Prints for each entry of self.arr, a line of the form (i, j, k, …) self.arr[i, j, k, …], with zero bit last ( resp., first) if ZL=True (resp., False).

Parameters:
  • omit_zero_amps (bool) – If True, will not list states with zero amplitude
  • show_pp_probs (bool) – If True, will show probability of each amplitude
  • ZL (bool) – If True, multi-index in ZL (Zero bit Last) convention. If False, multi-index in ZF (Zero bit First) convention.
Returns:

Return type:

None