def test_zero_coeff(self): """ test addition """ pauli_a = 'IXYZ' pauli_b = 'IXYZ' coeff_a = 0.5 coeff_b = -0.5 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] pauli_term_b = [coeff_b, label_to_pauli(pauli_b)] opA = Operator(paulis=[pauli_term_a]) opB = Operator(paulis=[pauli_term_b]) newOP = opA + opB self.assertEqual(0, len(newOP.paulis), "{}".format(newOP.print_operators())) paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op += Operator(paulis=[pauli_term]) for i in range(6): opA = Operator(paulis=[[-coeffs[i], label_to_pauli(paulis[i])]]) op += opA self.assertEqual(6 - (i + 1), len(op.paulis))
def setUp(self): np.random.seed(0) self.num_qubits = 4 m_size = np.power(2, self.num_qubits) matrix = np.random.rand(m_size, m_size) self.qubitOp = Operator(matrix=matrix)
def test_addition_noninplace(self): """ test addition """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] pauli_term_b = [coeff_b, label_to_pauli(pauli_b)] opA = Operator(paulis=[pauli_term_a]) opB = Operator(paulis=[pauli_term_b]) copy_opA = copy.deepcopy(opA) newOP = opA + opB self.assertEqual(copy_opA, opA) self.assertEqual(2, len(newOP.paulis)) pauli_c = 'IXYZ' coeff_c = 0.25 pauli_term_c = [coeff_c, label_to_pauli(pauli_c)] newOP = newOP + Operator(paulis=[pauli_term_c]) self.assertEqual(2, len(newOP.paulis)) self.assertEqual(0.75, newOP.paulis[0][0])
def _setup_qpe(self): self._operator._check_representation('paulis') self._ret['translation'] = sum( [abs(p[0]) for p in self._operator.paulis]) self._ret['stretch'] = 0.5 / self._ret['translation'] # translate the operator self._operator._simplify_paulis() translation_op = Operator([[ self._ret['translation'], Pauli(np.zeros(self._operator.num_qubits), np.zeros(self._operator.num_qubits)) ]]) translation_op._simplify_paulis() self._operator += translation_op # stretch the operator for p in self._operator._paulis: p[0] = p[0] * self._ret['stretch'] # check for identify paulis to get its coef for applying global phase shift on ancillae later num_identities = 0 for p in self._operator.paulis: if np.all(p[1].v == 0) and np.all(p[1].w == 0): num_identities += 1 if num_identities > 1: raise RuntimeError( 'Multiple identity pauli terms are present.') self._ancilla_phase_coef = p[0].real if isinstance( p[0], complex) else p[0] self._construct_qpe_evolution() logger.info('QPE circuit qasm length is roughly {}.'.format( len(self._circuit.qasm().split('\n'))))
def test_chop_complex_only_2(self): paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [ 0.2 + -1j * 0.8, 0.6 + -1j * 0.6, 0.8 + -1j * 0.2, -0.2 + -1j * 0.8, -0.6 - -1j * 0.6, -0.8 - -1j * 0.2 ] op = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op += Operator(paulis=[pauli_term]) op1 = copy.deepcopy(op) op1.chop(threshold=0.4) self.assertEqual(len(op1.paulis), 6, "\n{}".format(op1.print_operators())) op2 = copy.deepcopy(op) op2.chop(threshold=0.7) self.assertEqual(len(op2.paulis), 4, "\n{}".format(op2.print_operators())) op3 = copy.deepcopy(op) op3.chop(threshold=0.9) self.assertEqual(len(op3.paulis), 0, "\n{}".format(op3.print_operators()))
def from_params(self, params): if EnergyInput.PROP_KEY_QUBITOP not in params: raise AlgorithmError("Qubit operator is required.") qparams = params[EnergyInput.PROP_KEY_QUBITOP] self._qubit_op = Operator.load_from_dict(qparams) if EnergyInput.PROP_KEY_AUXOPS in params: auxparams = params[EnergyInput.PROP_KEY_AUXOPS] self._aux_ops = [Operator.load_from_dict(auxparams[i]) for i in range(len(auxparams))]
def test_equal_operator(self): paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op1 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op1 += Operator(paulis=[pauli_term]) paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op2 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op2 += Operator(paulis=[pauli_term]) paulis = ['IXYY', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op3 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op3 += Operator(paulis=[pauli_term]) paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [-0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op4 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op4 += Operator(paulis=[pauli_term]) self.assertEqual(op1, op2) self.assertNotEqual(op1, op3) self.assertNotEqual(op1, op4) self.assertNotEqual(op3, op4)
def test_create_from_paulis_0(self): """ test with single paulis """ num_qubits = 4 for pauli_label in itertools.product('IXYZ', repeat=num_qubits): coeff = np.random.random(1)[0] pauli_term = [coeff, label_to_pauli(pauli_label)] op = Operator(paulis=[pauli_term]) op.convert('paulis', 'matrix') op.convert('paulis', 'grouped_paulis') depth = 1 var_form = get_variational_form_instance('RYRZ') var_form.init_args(op.num_qubits, depth) circuit = var_form.construct_circuit( np.array(np.random.randn(var_form.num_parameters))) execute_config = {'shots': 1, 'skip_transpiler': False} matrix_mode = op.eval('matrix', circuit, 'local_statevector_simulator', execute_config)[0] non_matrix_mode = op.eval('paulis', circuit, 'local_statevector_simulator', execute_config)[0]
def get_partition_qubitops(values): """Construct the Hamiltonian for a given Partition instance. Given a list of numbers for the Number Partitioning problem, we construct the Hamiltonian described as a list of Pauli gates. Args: values (numpy.ndarray): array of values. Returns: operator.Operator, float: operator for the Hamiltonian and a constant shift for the obj function. """ n = len(values) # The Hamiltonian is: # \sum_{i,j=1,\dots,n} ij z_iz_j + \sum_{i=1,\dots,n} i^2 pauli_list = [] for i in range(n): for j in range(i): wp = np.zeros(n) vp = np.zeros(n) vp[i] = 1 vp[j] = 1 pauli_list.append((2 * values[i] * values[j], Pauli(vp, wp))) return Operator(paulis=pauli_list), sum(values * values)
def _two_body_mapping(h2_ijkm, a_i, a_j, a_k, a_m, threshold): """ Subroutine for two body mapping. Args: h1_ijkm (complex): value of h2 at index (i,j,k,m) a_i (Pauli): pauli at index i a_j (Pauli): pauli at index j a_k (Pauli): pauli at index k a_m (Pauli): pauli at index m threshold: (float): threshold to remove a pauli Returns: Operator: Operator for those paulis """ pauli_list = [] for alpha in range(2): for beta in range(2): for gamma in range(2): for delta in range(2): pauli_prod_1 = sgn_prod(a_i[alpha], a_k[beta]) pauli_prod_2 = sgn_prod(pauli_prod_1[0], a_m[gamma]) pauli_prod_3 = sgn_prod(pauli_prod_2[0], a_j[delta]) phase1 = pauli_prod_1[1] * pauli_prod_2[ 1] * pauli_prod_3[1] phase2 = np.power(-1j, alpha + beta) * np.power( 1j, gamma + delta) pauli_term = [ h2_ijkm / 16 * phase1 * phase2, pauli_prod_3[0] ] if np.absolute(pauli_term[0]) > threshold: pauli_list.append(pauli_term) return Operator(paulis=pauli_list)
def get_stableset_qubitops(w): """Generate Hamiltonian for the maximum stableset in a graph. Args: w (numpy.ndarray) : adjacency matrix. Returns: operator.Operator, float: operator for the Hamiltonian and a constant shift for the obj function. """ num_nodes = len(w) pauli_list = [] shift = 0 for i in range(num_nodes): for j in range(i + 1, num_nodes): if (w[i, j] != 0): wp = np.zeros(num_nodes) vp = np.zeros(num_nodes) vp[i] = 1 vp[j] = 1 pauli_list.append((1.0, Pauli(vp, wp))) shift += 1 for i in range(num_nodes): degree = sum(w[i, :]) wp = np.zeros(num_nodes) vp = np.zeros(num_nodes) vp[i] = 1 pauli_list.append((degree - 1 / 2, Pauli(vp, wp))) return Operator(paulis=pauli_list), shift - num_nodes / 2
def test_multiplication(self): """ test multiplication """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] pauli_term_b = [coeff_b, label_to_pauli(pauli_b)] opA = Operator(paulis=[pauli_term_a]) opB = Operator(paulis=[pauli_term_b]) newOP = opA * opB # print(newOP.print_operators()) self.assertEqual(1, len(newOP.paulis)) self.assertEqual(-0.25, newOP.paulis[0][0]) self.assertEqual('ZZYY', newOP.paulis[0][1].to_label())
def _compute_energy(self): self._operator._check_representation('paulis') self._ret['translation'] = sum( [abs(p[0]) for p in self._operator.paulis]) self._ret['stretch'] = 0.5 / self._ret['translation'] # translate the operator self._operator._simplify_paulis() translation_op = Operator([[ self._ret['translation'], Pauli(np.zeros(self._operator.num_qubits), np.zeros(self._operator.num_qubits)) ]]) translation_op._simplify_paulis() self._operator += translation_op # stretch the operator for p in self._operator._paulis: p[0] = p[0] * self._ret['stretch'] # check for identify paulis to get its coef for applying global phase shift on ancilla later num_identities = 0 for p in self._operator.paulis: if np.all(p[1].v == 0) and np.all(p[1].w == 0): num_identities += 1 if num_identities > 1: raise RuntimeError( 'Multiple identity pauli terms are present.') self._ancilla_phase_coef = p[0].real if isinstance( p[0], complex) else p[0] self._ret['phase'] = self._estimate_phase_iteratively() self._ret['top_measurement_decimal'] = sum([ t[0] * t[1] for t in zip([1 / 2**p for p in range(1, self._num_iterations + 1)], [int(n) for n in self._ret['top_measurement_label']]) ]) self._ret['energy'] = self._ret['phase'] / self._ret[ 'stretch'] - self._ret['translation']
def test_addition_inplace(self): """ test addition """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] pauli_term_b = [coeff_b, label_to_pauli(pauli_b)] opA = Operator(paulis=[pauli_term_a]) opB = Operator(paulis=[pauli_term_b]) opA += opB self.assertEqual(2, len(opA.paulis)) pauli_c = 'IXYZ' coeff_c = 0.25 pauli_term_c = [coeff_c, label_to_pauli(pauli_c)] opA += Operator(paulis=[pauli_term_c]) self.assertEqual(2, len(opA.paulis)) self.assertEqual(0.75, opA.paulis[0][0])
def __init__(self, cost_operator, p): self.cost_operator = cost_operator self.p = p self.num_parameters = 2 * p self.parameter_bounds = [(0, np.pi)] * p + [(0, 2 * np.pi)] * p self.preferred_init_points = [0] * p * 2 # prepare the mixer operator v = np.zeros(self.cost_operator.num_qubits) ws = np.eye(self.cost_operator.num_qubits) self.mixer_operator = reduce(lambda x, y: x + y, [ Operator([[1, Pauli(v, ws[i, :])]]) for i in range(self.cost_operator.num_qubits) ])
def test_zero_elimination(self): pauli_a = 'IXYZ' coeff_a = 0.0 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] opA = Operator(paulis=[pauli_term_a]) self.assertEqual(1, len(opA.paulis), "{}".format(opA.print_operators())) opA.zeros_coeff_elimination() self.assertEqual(0, len(opA.paulis), "{}".format(opA.print_operators()))
def _construct_qpe_evolution(self): """Implement the Quantum Phase Estimation algorithm""" a = QuantumRegister(self._num_ancillae, name='a') c = ClassicalRegister(self._num_ancillae, name='c') q = QuantumRegister(self._operator.num_qubits, name='q') qc = QuantumCircuit(a, q, c) # initialize state_in qc.data += self._state_in.construct_circuit('circuit', q).data # Put all ancillae in uniform superposition qc.u2(0, np.pi, a) if self._use_basis_gates else qc.h(a) # phase kickbacks via dynamics pauli_list = self._operator.reorder_paulis( grouping=self._paulis_grouping) if len(pauli_list) == 1: slice_pauli_list = pauli_list else: if self._expansion_mode == 'trotter': slice_pauli_list = pauli_list elif self._expansion_mode == 'suzuki': slice_pauli_list = Operator._suzuki_expansion_slice_pauli_list( pauli_list, 1, self._expansion_order) else: raise ValueError('Unrecognized expansion mode {}.'.format( self._expansion_mode)) for i in range(self._num_ancillae): qc.data += self._operator.construct_evolution_circuit( slice_pauli_list, -2 * np.pi, self._num_time_slices, q, a, ctl_idx=i, use_basis_gates=self._use_basis_gates).data # global phase shift for the ancilla due to the identity pauli term qc.u1(2 * np.pi * self._ancilla_phase_coef * (2**i), a[i]) # inverse qft on ancillae self._iqft.construct_circuit('circuit', a, qc) # measuring ancillae qc.measure(a, c) self._circuit = qc
def test_create_from_matrix(self): """ test with matrix initialization """ for num_qubits in range(1, 6): m_size = np.power(2, num_qubits) matrix = np.random.rand(m_size, m_size) op = Operator(matrix=matrix) op.convert('matrix', 'paulis') op.convert('matrix', 'grouped_paulis') depth = 1 var_form = get_variational_form_instance('RYRZ') var_form.init_args(op.num_qubits, depth) circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters))) execute_config = {'shots': 1, 'skip_transpiler': False} matrix_mode = op.eval('matrix', circuit, 'local_statevector_simulator', execute_config)[0] non_matrix_mode = op.eval('paulis', circuit, 'local_statevector_simulator', execute_config)[0]
def get_graphpartition_qubitops(weight_matrix): """Generate Hamiltonian for the graph partitioning Args: weight_matrix (numpy.ndarray) : adjacency matrix. Returns: operator.Operator, float: operator for the Hamiltonian and a constant shift for the obj function. Goals: 1 separate the vertices into two set of the same size 2 make sure the number of edges between the two set is minimized. Hamiltonian: H = H_A + H_B H_A = sum\_{(i,j)\in E}{(1-ZiZj)/2} H_B = (sum_{i}{Zi})^2 = sum_{i}{Zi^2}+sum_{i!=j}{ZiZj} H_A is for achieving goal 2 and H_B is for achieving goal 1. """ num_nodes = len(weight_matrix) pauli_list = [] shift = 0 for i in range(num_nodes): for j in range(i): if (weight_matrix[i, j] != 0): wp = np.zeros(num_nodes) vp = np.zeros(num_nodes) vp[i] = 1 vp[j] = 1 pauli_list.append([-0.5, Pauli(vp, wp)]) shift += 0.5 for i in range(num_nodes): for j in range(num_nodes): if i != j: wp = np.zeros(num_nodes) vp = np.zeros(num_nodes) vp[i] = 1 vp[j] = 1 pauli_list.append([1, Pauli(vp, wp)]) else: shift += 1 return Operator(paulis=pauli_list), shift
def _estimate_phase_iteratively(self): """Iteratively construct the different order of controlled evolution circuit to carry out phase estimation""" pauli_list = self._operator.reorder_paulis( grouping=self._paulis_grouping) if len(pauli_list) == 1: slice_pauli_list = pauli_list else: if self._expansion_mode == 'trotter': slice_pauli_list = pauli_list else: slice_pauli_list = Operator._suzuki_expansion_slice_pauli_list( pauli_list, 1, self._expansion_order) self._ret['top_measurement_label'] = '' omega_coef = 0 # k runs from the number of iterations back to 1 for k in range(self._num_iterations, 0, -1): omega_coef /= 2 qc = self._construct_kth_evolution(slice_pauli_list, k, -2 * np.pi * omega_coef) measurements = self.execute(qc).get_counts(qc) if '0' not in measurements: if '1' in measurements: x = 1 else: raise RuntimeError( 'Unexpected measurement {}.'.format(measurements)) else: if '1' not in measurements: x = 0 else: x = 1 if measurements['1'] > measurements['0'] else 0 self._ret['top_measurement_label'] = '{}{}'.format( x, self._ret['top_measurement_label']) omega_coef = omega_coef + x / 2 logger.info( 'Reverse iteration {} of {} with measured bit {}'.format( k, self._num_iterations, x)) return omega_coef
def setUp(self): np.random.seed(50) pauli_dict = { 'paulis': [{ "coeff": { "imag": 0.0, "real": -1.052373245772859 }, "label": "II" }, { "coeff": { "imag": 0.0, "real": 0.39793742484318045 }, "label": "ZI" }, { "coeff": { "imag": 0.0, "real": -0.39793742484318045 }, "label": "IZ" }, { "coeff": { "imag": 0.0, "real": -0.01128010425623538 }, "label": "ZZ" }, { "coeff": { "imag": 0.0, "real": 0.18093119978423156 }, "label": "XX" }] } qubitOp = Operator.load_from_dict(pauli_dict) self.algo_input = get_input_instance('EnergyInput') self.algo_input.qubit_op = qubitOp
def _one_body_mapping(h1_ij, a_i, a_j, threshold): """ Subroutine for one body mapping. Args: h1_ij (complex): value of h1 at index (i,j) a_i (Pauli): pauli at index i a_j (Pauli): pauli at index j threshold: (float): threshold to remove a pauli Returns: Operator: Operator for those paulis """ pauli_list = [] for alpha in range(2): for beta in range(2): pauli_prod = sgn_prod(a_i[alpha], a_j[beta]) coeff = h1_ij / 4 * pauli_prod[1] * np.power( -1j, alpha) * np.power(1j, beta) pauli_term = [coeff, pauli_prod[0]] if np.absolute(pauli_term[0]) > threshold: pauli_list.append(pauli_term) return Operator(paulis=pauli_list)
def get_maxcut_qubitops(weight_matrix): """Generate Hamiltonian for the maximum stableset in a graph. Args: weight_matrix (numpy.ndarray) : adjacency matrix. Returns: operator.Operator, float: operator for the Hamiltonian and a constant shift for the obj function. """ num_nodes = weight_matrix.shape[0] pauli_list = [] shift = 0 for i in range(num_nodes): for j in range(i): if (weight_matrix[i,j] != 0): wp = np.zeros(num_nodes) vp = np.zeros(num_nodes) vp[i] = 1 vp[j] = 1 pauli_list.append([0.5 * weight_matrix[i, j], Pauli(vp, wp)]) shift -= 0.5 * weight_matrix[i, j] return Operator(paulis=pauli_list), shift
# ============================================================================= import unittest from parameterized import parameterized from qiskit_acqua import get_algorithm_instance, get_initial_state_instance, get_iqft_instance, Operator from qiskit_acqua.utils import decimal_to_binary import numpy as np from test.common import QISKitAcquaTestCase from scipy.linalg import expm X = np.array([[0, 1], [1, 0]]) Y = np.array([[0, -1j], [1j, 0]]) Z = np.array([[1, 0], [0, -1]]) I = np.array([[1, 0], [0, 1]]) h1 = X + Y + Z + I qubitOp_simple = Operator(matrix=h1) pauli_dict = { 'paulis': [{ "coeff": { "imag": 0.0, "real": -1.052373245772859 }, "label": "II" }, { "coeff": { "imag": 0.0, "real": 0.39793742484318045 }, "label": "ZI" }, {
"label": "IZ" }, { "coeff": { "imag": 0.0, "real": -0.01128010425623538 }, "label": "ZZ" }, { "coeff": { "imag": 0.0, "real": 0.18093119978423156 }, "label": "XX" }] } qubitOp_h2_with_2_qubit_reduction = Operator.load_from_dict(pauli_dict) class TestIQPE(QISKitAcquaTestCase): """QPE tests.""" @parameterized.expand([ [qubitOp_h2_with_2_qubit_reduction], ]) def test_qpe(self, qubitOp): self.algorithm = 'QPE' self.log.debug('Testing QPE') self.qubitOp = qubitOp exact_eigensolver = get_algorithm_instance('ExactEigensolver') exact_eigensolver.init_args(self.qubitOp, k=1)
class TestOperator(QISKitAcquaTestCase): """Operator tests.""" def setUp(self): np.random.seed(0) self.num_qubits = 4 m_size = np.power(2, self.num_qubits) matrix = np.random.rand(m_size, m_size) self.qubitOp = Operator(matrix=matrix) def test_real_eval(self): depth = 1 var_form = get_variational_form_instance('RYRZ') var_form.init_args(self.qubitOp.num_qubits, depth) circuit = var_form.construct_circuit( np.array(np.random.randn(var_form.num_parameters))) # self.qubitOp.coloring = None execute_config_ref = {'shots': 1, 'skip_transpiler': False} execute_config = {'shots': 10000, 'skip_transpiler': False} reference = self.qubitOp.eval('matrix', circuit, 'local_statevector_simulator', execute_config_ref)[0] reference = reference.real paulis_mode = self.qubitOp.eval('paulis', circuit, 'local_qasm_simulator', execute_config) grouped_paulis_mode = self.qubitOp.eval('grouped_paulis', circuit, 'local_qasm_simulator', execute_config) paulis_mode_p_3sigma = paulis_mode[0] + 3 * paulis_mode[1] paulis_mode_m_3sigma = paulis_mode[0] - 3 * paulis_mode[1] grouped_paulis_mode_p_3sigma = grouped_paulis_mode[ 0] + 3 * grouped_paulis_mode[1] grouped_paulis_mode_m_3sigma = grouped_paulis_mode[ 0] - 3 * grouped_paulis_mode[1] self.assertLessEqual(reference, paulis_mode_p_3sigma.real) self.assertGreaterEqual(reference, paulis_mode_m_3sigma.real) self.assertLessEqual(reference, grouped_paulis_mode_p_3sigma.real) self.assertGreaterEqual(reference, grouped_paulis_mode_m_3sigma.real) execute_config = {'shots': 10000, 'skip_transpiler': True} paulis_mode = self.qubitOp.eval('paulis', circuit, 'local_qasm_simulator', execute_config) grouped_paulis_mode = self.qubitOp.eval('grouped_paulis', circuit, 'local_qasm_simulator', execute_config) paulis_mode_p_3sigma = paulis_mode[0] + 3 * paulis_mode[1] paulis_mode_m_3sigma = paulis_mode[0] - 3 * paulis_mode[1] grouped_paulis_mode_p_3sigma = grouped_paulis_mode[ 0] + 3 * grouped_paulis_mode[1] grouped_paulis_mode_m_3sigma = grouped_paulis_mode[ 0] - 3 * grouped_paulis_mode[1] self.assertLessEqual(reference, paulis_mode_p_3sigma.real, "With skip_transpiler on") self.assertGreaterEqual(reference, paulis_mode_m_3sigma.real, "With skip_transpiler on") self.assertLessEqual(reference, grouped_paulis_mode_p_3sigma.real, "With skip_transpiler on") self.assertGreaterEqual(reference, grouped_paulis_mode_m_3sigma.real, "With skip_transpiler on") def test_exact_eval(self): depth = 1 var_form = get_variational_form_instance('RYRZ') var_form.init_args(self.qubitOp.num_qubits, depth) circuit = var_form.construct_circuit( np.array(np.random.randn(var_form.num_parameters))) execute_config = {'shots': 1, 'skip_transpiler': False} matrix_mode = self.qubitOp.eval('matrix', circuit, 'local_statevector_simulator', execute_config)[0] non_matrix_mode = self.qubitOp.eval('paulis', circuit, 'local_statevector_simulator', execute_config)[0] diff = abs(matrix_mode - non_matrix_mode) self.assertLess( diff, 0.01, "Values: ({} vs {})".format(matrix_mode, non_matrix_mode)) execute_config = {'shots': 1, 'skip_transpiler': True} non_matrix_mode = self.qubitOp.eval('paulis', circuit, 'local_statevector_simulator', execute_config)[0] diff = abs(matrix_mode - non_matrix_mode) self.assertLess( diff, 0.01, "With skip_transpiler on, Values: ({} vs {})".format( matrix_mode, non_matrix_mode)) def test_create_from_paulis_0(self): """ test with single paulis """ num_qubits = 4 for pauli_label in itertools.product('IXYZ', repeat=num_qubits): coeff = np.random.random(1)[0] pauli_term = [coeff, label_to_pauli(pauli_label)] op = Operator(paulis=[pauli_term]) op.convert('paulis', 'matrix') op.convert('paulis', 'grouped_paulis') depth = 1 var_form = get_variational_form_instance('RYRZ') var_form.init_args(op.num_qubits, depth) circuit = var_form.construct_circuit( np.array(np.random.randn(var_form.num_parameters))) execute_config = {'shots': 1, 'skip_transpiler': False} matrix_mode = op.eval('matrix', circuit, 'local_statevector_simulator', execute_config)[0] non_matrix_mode = op.eval('paulis', circuit, 'local_statevector_simulator', execute_config)[0] def test_create_from_matrix(self): """ test with matrix initialization """ for num_qubits in range(1, 6): m_size = np.power(2, num_qubits) matrix = np.random.rand(m_size, m_size) op = Operator(matrix=matrix) op.convert('matrix', 'paulis') op.convert('matrix', 'grouped_paulis') depth = 1 var_form = get_variational_form_instance('RYRZ') var_form.init_args(op.num_qubits, depth) circuit = var_form.construct_circuit( np.array(np.random.randn(var_form.num_parameters))) execute_config = {'shots': 1, 'skip_transpiler': False} matrix_mode = op.eval('matrix', circuit, 'local_statevector_simulator', execute_config)[0] non_matrix_mode = op.eval('paulis', circuit, 'local_statevector_simulator', execute_config)[0] def test_multiplication(self): """ test multiplication """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] pauli_term_b = [coeff_b, label_to_pauli(pauli_b)] opA = Operator(paulis=[pauli_term_a]) opB = Operator(paulis=[pauli_term_b]) newOP = opA * opB # print(newOP.print_operators()) self.assertEqual(1, len(newOP.paulis)) self.assertEqual(-0.25, newOP.paulis[0][0]) self.assertEqual('ZZYY', newOP.paulis[0][1].to_label()) def test_addition(self): """ test addition """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] pauli_term_b = [coeff_b, label_to_pauli(pauli_b)] opA = Operator(paulis=[pauli_term_a]) opB = Operator(paulis=[pauli_term_b]) newOP = opA + opB self.assertEqual(2, len(newOP.paulis)) pauli_c = 'IXYZ' coeff_c = 0.25 pauli_term_c = [coeff_c, label_to_pauli(pauli_c)] newOP += Operator(paulis=[pauli_term_c]) self.assertEqual(2, len(newOP.paulis)) self.assertEqual(0.75, newOP.paulis[0][0]) def test_zero_coeff(self): """ test addition """ pauli_a = 'IXYZ' pauli_b = 'IXYZ' coeff_a = 0.5 coeff_b = -0.5 pauli_term_a = [coeff_a, label_to_pauli(pauli_a)] pauli_term_b = [coeff_b, label_to_pauli(pauli_b)] opA = Operator(paulis=[pauli_term_a]) opB = Operator(paulis=[pauli_term_b]) newOP = opA + opB self.assertEqual(0, len(newOP.paulis), "{}".format(newOP.print_operators())) paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op += Operator(paulis=[pauli_term]) for i in range(6): opA = Operator(paulis=[[-coeffs[i], label_to_pauli(paulis[i])]]) op += opA self.assertEqual(6 - (i + 1), len(op.paulis)) def test_dia_matrix(self): """ test conversion to dia_matrix """ num_qubits = 4 pauli_term = [] for pauli_label in itertools.product('IZ', repeat=num_qubits): coeff = np.random.random(1)[0] pauli_term.append([coeff, label_to_pauli(pauli_label)]) op = Operator(paulis=pauli_term) op.convert('paulis', 'matrix') op.convert('paulis', 'grouped_paulis') op._to_dia_matrix('paulis') self.assertEqual(op.matrix.ndim, 1) num_qubits = 4 pauli_term = [] for pauli_label in itertools.product('YZ', repeat=num_qubits): coeff = np.random.random(1)[0] pauli_term.append([coeff, label_to_pauli(pauli_label)]) op = Operator(paulis=pauli_term) op.convert('paulis', 'matrix') op.convert('paulis', 'grouped_paulis') op._to_dia_matrix('paulis') self.assertEqual(op.matrix.ndim, 2) def test_equal_operator(self): paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op1 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op1 += Operator(paulis=[pauli_term]) paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op2 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op2 += Operator(paulis=[pauli_term]) paulis = ['IXYY', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op3 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op3 += Operator(paulis=[pauli_term]) paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [-0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op4 = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op4 += Operator(paulis=[pauli_term]) self.assertEqual(op1, op2) self.assertNotEqual(op1, op3) self.assertNotEqual(op1, op4) self.assertNotEqual(op3, op4) def test_chop_real_only(self): paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op += Operator(paulis=[pauli_term]) op1 = copy.deepcopy(op) op1.chop(threshold=0.4) self.assertEqual(len(op1.paulis), 4, "\n{}".format(op1.print_operators())) gt_op1 = Operator(paulis=[]) for i in range(1, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op1 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op1 += Operator(paulis=[pauli_term]) self.assertEqual(op1, gt_op1) op2 = copy.deepcopy(op) op2.chop(threshold=0.7) self.assertEqual(len(op2.paulis), 2, "\n{}".format(op2.print_operators())) gt_op2 = Operator(paulis=[]) for i in range(2, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op2 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op2 += Operator(paulis=[pauli_term]) self.assertEqual(op2, gt_op2) op3 = copy.deepcopy(op) op3.chop(threshold=0.9) self.assertEqual(len(op3.paulis), 0, "\n{}".format(op3.print_operators())) gt_op3 = Operator(paulis=[]) for i in range(3, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op3 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op3 += Operator(paulis=[pauli_term]) self.assertEqual(op3, gt_op3) def test_chop_complex_only_1(self): paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [ 0.2 + -1j * 0.2, 0.6 + -1j * 0.6, 0.8 + -1j * 0.8, -0.2 + -1j * 0.2, -0.6 - -1j * 0.6, -0.8 - -1j * 0.8 ] op = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op += Operator(paulis=[pauli_term]) op1 = copy.deepcopy(op) op1.chop(threshold=0.4) self.assertEqual(len(op1.paulis), 4, "\n{}".format(op1.print_operators())) gt_op1 = Operator(paulis=[]) for i in range(1, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op1 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op1 += Operator(paulis=[pauli_term]) self.assertEqual(op1, gt_op1) op2 = copy.deepcopy(op) op2.chop(threshold=0.7) self.assertEqual(len(op2.paulis), 2, "\n{}".format(op2.print_operators())) gt_op2 = Operator(paulis=[]) for i in range(2, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op2 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op2 += Operator(paulis=[pauli_term]) self.assertEqual(op2, gt_op2) op3 = copy.deepcopy(op) op3.chop(threshold=0.9) self.assertEqual(len(op3.paulis), 0, "\n{}".format(op3.print_operators())) gt_op3 = Operator(paulis=[]) for i in range(3, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op3 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op3 += Operator(paulis=[pauli_term]) self.assertEqual(op3, gt_op3) def test_chop_complex_only_2(self): paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [ 0.2 + -1j * 0.8, 0.6 + -1j * 0.6, 0.8 + -1j * 0.2, -0.2 + -1j * 0.8, -0.6 - -1j * 0.6, -0.8 - -1j * 0.2 ] op = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op += Operator(paulis=[pauli_term]) op1 = copy.deepcopy(op) op1.chop(threshold=0.4) self.assertEqual(len(op1.paulis), 6, "\n{}".format(op1.print_operators())) op2 = copy.deepcopy(op) op2.chop(threshold=0.7) self.assertEqual(len(op2.paulis), 4, "\n{}".format(op2.print_operators())) op3 = copy.deepcopy(op) op3.chop(threshold=0.9) self.assertEqual(len(op3.paulis), 0, "\n{}".format(op3.print_operators())) def test_representations(self): self.assertEqual(len(self.qubitOp.representations), 1) self.assertEqual(self.qubitOp.representations, ['matrix']) self.qubitOp.convert("matrix", "paulis") self.assertEqual(len(self.qubitOp.representations), 2) self.assertEqual(self.qubitOp.representations, ['paulis', 'matrix']) self.qubitOp.convert("matrix", "grouped_paulis") self.assertEqual(len(self.qubitOp.representations), 3) self.assertEqual(self.qubitOp.representations, ['paulis', 'grouped_paulis', 'matrix']) def test_num_qubits(self): op = Operator(paulis=[]) self.assertEqual(op.num_qubits, 0) self.assertEqual(self.qubitOp.num_qubits, self.num_qubits) def test_is_empty(self): op = Operator(paulis=[]) self.assertTrue(op.is_empty()) self.assertFalse(self.qubitOp.is_empty())
def mapping(self, map_type, threshold=0.00000001, num_workers=4): """ Using multiprocess to speedup the mapping, the improvement can be observed when h2 is a non-sparse matrix. Args: map_type (str): case-insensitive mapping type. "jordan_wigner", "parity", "bravyi_kitaev" threshold (float): threshold for Pauli simplification num_workers (int): number of processes used to map. Returns: Operator: create an Operator object in Paulis form. Raises: ACQUAChemistryError: if the `map_type` can not be recognized. """ """ #################################################################### ############ DEFINING MAPPED FERMIONIC OPERATORS ############## #################################################################### """ n = self._h1.shape[0] # number of fermionic modes / qubits map_type = map_type.lower() if map_type == 'jordan_wigner': a = self._jordan_wigner_mode(n) elif map_type == 'parity': a = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a = self._bravyi_kitaev_mode(n) else: raise ACQUAChemistryError( 'Please specify the supported modes: jordan_wigner, parity, bravyi_kitaev' ) """ #################################################################### ############ BUILDING THE MAPPED HAMILTONIAN ################ #################################################################### """ max_workers = min(num_workers, multiprocessing.cpu_count()) pauli_list = Operator(paulis=[]) with concurrent.futures.ProcessPoolExecutor( max_workers=max_workers) as executor: ####################### One-body ############################# futures = [ executor.submit(FermionicOperator._one_body_mapping, self._h1[i, j], a[i], a[j], threshold) for i, j in itertools.product(range(n), repeat=2) if self._h1[i, j] != 0 ] for future in concurrent.futures.as_completed(futures): result = future.result() pauli_list += result pauli_list.chop(threshold=threshold) ####################### Two-body ############################# futures = [ executor.submit(FermionicOperator._two_body_mapping, self._h2[i, j, k, m], a[i], a[j], a[k], a[m], threshold) for i, j, k, m in itertools.product(range(n), repeat=4) if self._h2[i, j, k, m] != 0 ] for future in concurrent.futures.as_completed(futures): result = future.result() pauli_list += result pauli_list.chop(threshold=threshold) if self._ph_trans_shift is not None: pauli_list += Operator(paulis=[[ self._ph_trans_shift, label_to_pauli('I' * self._h1.shape[0]) ]]) return pauli_list
def test_chop_complex_only_1(self): paulis = ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] coeffs = [ 0.2 + -1j * 0.2, 0.6 + -1j * 0.6, 0.8 + -1j * 0.8, -0.2 + -1j * 0.2, -0.6 - -1j * 0.6, -0.8 - -1j * 0.8 ] op = Operator(paulis=[]) for coeff, pauli in zip(coeffs, paulis): pauli_term = [coeff, label_to_pauli(pauli)] op += Operator(paulis=[pauli_term]) op1 = copy.deepcopy(op) op1.chop(threshold=0.4) self.assertEqual(len(op1.paulis), 4, "\n{}".format(op1.print_operators())) gt_op1 = Operator(paulis=[]) for i in range(1, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op1 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op1 += Operator(paulis=[pauli_term]) self.assertEqual(op1, gt_op1) op2 = copy.deepcopy(op) op2.chop(threshold=0.7) self.assertEqual(len(op2.paulis), 2, "\n{}".format(op2.print_operators())) gt_op2 = Operator(paulis=[]) for i in range(2, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op2 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op2 += Operator(paulis=[pauli_term]) self.assertEqual(op2, gt_op2) op3 = copy.deepcopy(op) op3.chop(threshold=0.9) self.assertEqual(len(op3.paulis), 0, "\n{}".format(op3.print_operators())) gt_op3 = Operator(paulis=[]) for i in range(3, 3): pauli_term = [coeffs[i], label_to_pauli(paulis[i])] gt_op3 += Operator(paulis=[pauli_term]) pauli_term = [coeffs[i + 3], label_to_pauli(paulis[i + 3])] gt_op3 += Operator(paulis=[pauli_term]) self.assertEqual(op3, gt_op3)
def test_num_qubits(self): op = Operator(paulis=[]) self.assertEqual(op.num_qubits, 0) self.assertEqual(self.qubitOp.num_qubits, self.num_qubits)
def test_is_empty(self): op = Operator(paulis=[]) self.assertTrue(op.is_empty()) self.assertFalse(self.qubitOp.is_empty())