def plot_state_paulivec(rho, title=""): """Plot the paulivec representation of a quantum state. Plot a bargraph of the mixed state rho over the pauli matricies Args: rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex numbers title (str): a string that represents the plot title Returns: none: plot is shown with matplotlib to the screen """ num = int(np.log2(len(rho))) labels = list(map(lambda x: x.to_label(), pauli_group(num))) values = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))), pauli_group(num))) numelem = len(values) ind = np.arange(numelem) # the x locations for the groups width = 0.5 # the width of the bars fig, ax = plt.subplots() ax.grid(zorder=0) ax.bar(ind, values, width, color='seagreen') # add some text for labels, title, and axes ticks ax.set_ylabel('Expectation value', fontsize=12) ax.set_xticks(ind) ax.set_yticks([-1, -0.5, 0, 0.5, 1]) ax.set_xticklabels(labels, fontsize=12, rotation=70) ax.set_xlabel('Pauli', fontsize=12) ax.set_ylim([-1, 1]) plt.title(title) plt.show()
def plot_state_paulivec(rho, title=""): """Plot the paulivec representation of a quantum state. Plot a bargraph of the mixed state rho over the pauli matricies Args: rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex numbers title (str): a string that represents the plot title Returns: none: plot is shown with matplotlib to the screen """ num = int(np.log2(len(rho))) labels = list(map(lambda x: x.to_label(), pauli_group(num))) values = list( map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))), pauli_group(num))) numelem = len(values) ind = np.arange(numelem) # the x locations for the groups width = 0.5 # the width of the bars fig, ax = plt.subplots() ax.grid(zorder=0) ax.bar(ind, values, width, color='seagreen') # add some text for labels, title, and axes ticks ax.set_ylabel('Expectation value', fontsize=12) ax.set_xticks(ind) ax.set_yticks([-1, -0.5, 0, 0.5, 1]) ax.set_xticklabels(labels, fontsize=12, rotation=70) ax.set_xlabel('Pauli', fontsize=12) ax.set_ylim([-1, 1]) plt.title(title) plt.show()
def vectorize(density_matrix, method='col'): """Flatten an operator to a vector in a specified basis. Args: density_matrix (ndarray): a density matrix. method (str): the method of vectorization. Allowed values are - 'col' (default) flattens to column-major vector. - 'row' flattens to row-major vector. - 'pauli'flattens in the n-qubit Pauli basis. - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by weight. Returns: ndarray: the resulting vector. Raises: Exception: if input state is not a n-qubit state """ density_matrix = np.array(density_matrix) if method == 'col': return density_matrix.flatten(order='F') elif method == 'row': return density_matrix.flatten(order='C') elif method in ['pauli', 'pauli_weights']: num = int(np.log2(len(density_matrix))) # number of qubits if len(density_matrix) != 2**num: raise Exception('Input state must be n-qubit state') if method == 'pauli_weights': pgroup = pauli_group(num, case=0) else: pgroup = pauli_group(num, case=1) vals = [np.trace(np.dot(p.to_matrix(), density_matrix)) for p in pgroup] return np.array(vals) return None
def test_pauli_group(self): self.log.info("Group in tensor order:") expected = ['III', 'XII', 'YII', 'ZII', 'IXI', 'XXI', 'YXI', 'ZXI', 'IYI', 'XYI', 'YYI', 'ZYI', 'IZI', 'XZI', 'YZI', 'ZZI', 'IIX', 'XIX', 'YIX', 'ZIX', 'IXX', 'XXX', 'YXX', 'ZXX', 'IYX', 'XYX', 'YYX', 'ZYX', 'IZX', 'XZX', 'YZX', 'ZZX', 'IIY', 'XIY', 'YIY', 'ZIY', 'IXY', 'XXY', 'YXY', 'ZXY', 'IYY', 'XYY', 'YYY', 'ZYY', 'IZY', 'XZY', 'YZY', 'ZZY', 'IIZ', 'XIZ', 'YIZ', 'ZIZ', 'IXZ', 'XXZ', 'YXZ', 'ZXZ', 'IYZ', 'XYZ', 'YYZ', 'ZYZ', 'IZZ', 'XZZ', 'YZZ', 'ZZZ'] grp = pauli_group(3, case=1) for j in grp: self.log.info('==== j (tensor order) ====') self.log.info(j.to_label()) self.assertEqual(expected.pop(0), j.to_label()) self.log.info("Group in weight order:") expected = ['III', 'XII', 'YII', 'ZII', 'IXI', 'IYI', 'IZI', 'IIX', 'IIY', 'IIZ', 'XXI', 'YXI', 'ZXI', 'XYI', 'YYI', 'ZYI', 'XZI', 'YZI', 'ZZI', 'XIX', 'YIX', 'ZIX', 'IXX', 'IYX', 'IZX', 'XIY', 'YIY', 'ZIY', 'IXY', 'IYY', 'IZY', 'XIZ', 'YIZ', 'ZIZ', 'IXZ', 'IYZ', 'IZZ', 'XXX', 'YXX', 'ZXX', 'XYX', 'YYX', 'ZYX', 'XZX', 'YZX', 'ZZX', 'XXY', 'YXY', 'ZXY', 'XYY', 'YYY', 'ZYY', 'XZY', 'YZY', 'ZZY', 'XXZ', 'YXZ', 'ZXZ', 'XYZ', 'YYZ', 'ZYZ', 'XZZ', 'YZZ', 'ZZZ'] grp = pauli_group(3) for j in grp: self.log.info('==== j (weight order) ====') self.log.info(j.to_label()) self.assertEqual(expected.pop(0), j.to_label())
def devectorize(vec, method='col'): """Devectorize a vectorized square matrix. Args: vec (ndarray): a vectorized density matrix. basis (str): the method of devectorizaation. Allowed values are - 'col' (default): flattens to column-major vector. - 'row': flattens to row-major vector. - 'pauli': flattens in the n-qubit Pauli basis. - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by weight. Returns: ndarray: the resulting matrix. """ vec = np.array(vec) d = int(np.sqrt(vec.size)) # the dimension of the matrix if len(vec) != d*d: raise Exception('Input is not a vectorized square matrix') if method == 'col': return vec.reshape(d, d, order='F') elif method == 'row': return vec.reshape(d, d, order='C') elif method in ['pauli', 'pauli_weights']: num = int(np.log2(d)) # number of qubits if d != 2 ** num: raise Exception('Input state must be n-qubit state') if method is 'pauli_weights': pgroup = pauli_group(num, case=0) else: pgroup = pauli_group(num, case=1) pbasis = np.array([p.to_matrix() for p in pgroup]) / 2 ** num return np.tensordot(vec, pbasis, axes=1)
def process_data(rho): """ Sort rho data """ result = dict() num = int(np.log2(len(rho))) labels = list(map(lambda x: x.to_label(), pauli_group(num))) values = list( map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))), pauli_group(num))) for position, label in enumerate(labels): result[label] = values[position] return result
def test_pauli(self): v = np.zeros(3) w = np.zeros(3) v[0] = 1 w[1] = 1 v[2] = 1 w[2] = 1 p = Pauli(v, w) self.log.info(p) self.log.info("In label form:") self.log.info(p.to_label()) self.log.info("In matrix form:") self.log.info(p.to_matrix()) q = random_pauli(2) self.log.info(q) r = inverse_pauli(p) self.log.info("In label form:") self.log.info(r.to_label()) self.log.info("Group in tensor order:") grp = pauli_group(3, case=1) for j in grp: self.log.info(j.to_label()) self.log.info("Group in weight order:") grp = pauli_group(3) for j in grp: self.log.info(j.to_label()) self.log.info("sign product:") p1 = Pauli(np.array([0]), np.array([1])) p2 = Pauli(np.array([1]), np.array([1])) p3, sgn = sgn_prod(p1, p2) self.log.info(p1.to_label()) self.log.info(p2.to_label()) self.log.info(p3.to_label()) self.log.info(sgn) self.log.info("sign product reverse:") p3, sgn = sgn_prod(p2, p1) self.log.info(p2.to_label()) self.log.info(p1.to_label()) self.log.info(p3.to_label()) self.log.info(sgn)
def choi_to_rauli(choi, order=1): """ Convert a Choi-matrix to a Pauli-basis superoperator. Note that this function assumes that the Choi-matrix is defined in the standard column-stacking converntion and is normalized to have trace 1. For a channel E this is defined as: choi = (I \otimes E)(bell_state). The resulting 'rauli' R acts on input states as |rho_out>_p = R.|rho_in>_p where |rho> = vectorize(rho, method='pauli') for order=1 and |rho> = vectorize(rho, method='pauli_weights') for order=0. Args: choi (matrix): the input Choi-matrix. order (int): ordering of the Pauli group vector. order=1 (default) is standard lexicographic ordering. Eg: [II, IX, IY, IZ, XI, XX, XY,...] order=0 is ordered by weights. Eg. [II, IX, IY, IZ, XI, XY, XZ, XX, XY,...] Returns: np.array: A superoperator in the Pauli basis. """ # get number of qubits' num_qubits = int(np.log2(np.sqrt(len(choi)))) pgp = pauli_group(num_qubits, case=order) rauli = [] for i in pgp: for j in pgp: pauliop = np.kron(j.to_matrix().T, i.to_matrix()) rauli += [np.trace(np.dot(choi, pauliop))] return np.array(rauli).reshape(4 ** num_qubits, 4 ** num_qubits)
def plot_state_paulivec(rho, title="", filename=None): """Plot the paulivec representation of a quantum state. Plot a bargraph of the mixed state rho over the pauli matrices Args: rho (np.array[[complex]]): array of dimensions 2**n x 2**nn complex numbers title (str): a string that represents the plot title filename (str): the output file to save the plot as. If specified it will save and exit and not open up the plot in a new window. """ num = int(np.log2(len(rho))) labels = list(map(lambda x: x.to_label(), pauli_group(num))) values = list( map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))), pauli_group(num))) numelem = len(values) ind = np.arange(numelem) # the x locations for the groups width = 0.5 # the width of the bars _, ax = plt.subplots() ax.grid(zorder=0) ax.bar(ind, values, width, color='seagreen') # add some text for labels, title, and axes ticks ax.set_ylabel('Expectation value', fontsize=12) ax.set_xticks(ind) ax.set_yticks([-1, -0.5, 0, 0.5, 1]) ax.set_xticklabels(labels, fontsize=12, rotation=70) ax.set_xlabel('Pauli', fontsize=12) ax.set_ylim([-1, 1]) plt.title(title) if filename: plt.savefig(filename) else: plt.show()
def devectorize(vectorized_mat, method='col'): """Devectorize a vectorized square matrix. Args: vectorized_mat (ndarray): a vectorized density matrix. method (str): the method of devectorization. Allowed values are - 'col' (default): flattens to column-major vector. - 'row': flattens to row-major vector. - 'pauli': flattens in the n-qubit Pauli basis. - 'pauli-weights': flattens in the n-qubit Pauli basis ordered by weight. Returns: ndarray: the resulting matrix. Raises: Exception: if input state is not a n-qubit state """ vectorized_mat = np.array(vectorized_mat) dimension = int(np.sqrt(vectorized_mat.size)) if len(vectorized_mat) != dimension * dimension: raise Exception('Input is not a vectorized square matrix') if method == 'col': return vectorized_mat.reshape(dimension, dimension, order='F') elif method == 'row': return vectorized_mat.reshape(dimension, dimension, order='C') elif method in ['pauli', 'pauli_weights']: num_qubits = int(np.log2(dimension)) # number of qubits if dimension != 2 ** num_qubits: raise Exception('Input state must be n-qubit state') if method == 'pauli_weights': pgroup = pauli_group(num_qubits, case=0) else: pgroup = pauli_group(num_qubits, case=1) pbasis = np.array([p.to_matrix() for p in pgroup]) / 2 ** num_qubits return np.tensordot(vectorized_mat, pbasis, axes=1) return None