qubiter.StateVec module¶
-
class
qubiter.StateVec.
StateVec
(num_qbits, arr=None)[source]¶ Bases:
object
This class is a wrapper for its main attribute, a complex numpy array self.arr with shape [2]*num_qbits. 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_qbits.
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_qbits
- num_qbits (int) –
-
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_qbits, 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_qbits (int) –
- pd (np.ndarray) – probability distribution of shape (2^num_qbits,) IMP: assumed to be indexed in ZL convention
Returns: Return type: list[tuple[float, float]]
-
static
get_counts_from_obs_vec
(num_qbits, 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_qbits long, followed by ‘ZL’ because ZL convention is assumed. If use_bin_labels=False, state names are ‘0’, ‘1’, ‘2’, etc.
Parameters: - num_qbits (int) –
- obs_vec (np.ndarray) –
- use_bin_labels (bool) –
- omit_zero_counts (bool) –
Returns: Return type: OrderedDict[str, int]
-
static
get_den_mat
(num_qbits, 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_qbits (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_qbits, indexed in ZL convention. Returns: Return type: np.ndarray
-
static
get_emp_state_vec_from_emp_pd
(num_qbits, 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_qbits, 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_qbits (int) –
- emp_pd (np.ndarray) – its shape is (1<<num_qbits,)
Returns: Return type:
-
static
get_empirical_pd_from_counts
(num_qbits, 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_qbits (int) –
- state_name_to_count (OrderedDict[str, int]) –
Returns: emp_pd – its shape is (1<<num_qbits,)
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_qbits)[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_qbits (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_qbits 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>
. LetH = U^\dag D U
, where U is unitary and D is real diagonal matrix. Ifself = U|psi>
, then this reduces to findingmean= <self|D|self>
. So must decompose U into a SEO and evolve, using SEO_simulator, to the stateU|psi>
.Parameters: real_arr (np.ndarray) – a real array of shape=[2]^num_qbits (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_qbits, 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_qbits) chosen according to the probability distribution pd for num_qbits 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_qbits (int) –
- pd (np.ndarray) – probability distribution of shape (2^num_qbits,) 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_qbits, 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_qbits (int) –
- den_mat (np.ndarray) – if dim=2^num_qbits, 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_qbits-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_qbits,) IMP: will be indexed in ZL convention. Return type: np.ndarray
-
static
get_random_st_vec
(num_qbits, 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_qbits and\sum_b^n |A( b^n)|^2 = 1
.Parameters: - num_qbits (int) –
- rand_seed (int) –
Returns: Return type:
-
static
get_standard_basis_st_vec
(spin_dir_list, ZL=True)[source]¶ If ZL = True, returns StateVec for state
...|s2>|s1>|s0>
, wherespin_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 exceptspin_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:
-
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_traditional_st_vec
¶ Internally, self.arr in Qubiter has shape [2]*num_qbits 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_qbits 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
>>> x = np.binary_repr(3, width=4) >>> x '0011' >>> int(x, 2) 3
Returns: Return type: np.array Type: **IMPORTANT
-
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