def vacuum_operator(fer_op): """Use the stabilizers to find the vacuum state in bravyi_kitaev_fast. Args: fer_op (FermionicOperator): the fermionic operator in the second quanitzed form Returns: Operator: the qubit operator """ edge_list = bravyi_kitaev_fast_edge_list(fer_op) num_qubits = edge_list.shape[1] vac_operator = Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) g = networkx.Graph() g.add_edges_from(tuple(edge_list.transpose())) stabs = np.asarray(networkx.cycle_basis(g)) for stab in stabs: a = Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) stab = np.asarray(stab) for i in range(np.size(stab)): a = a * edge_operator_aij(edge_list, stab[i], stab[(i + 1) % np.size(stab)]) a.scaling_coeff(1j) a += Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) vac_operator = vac_operator * a vac_operator.scaling_coeff(np.sqrt(2)) return vac_operator
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('matrix', 'grouped_paulis') op._to_dia_matrix('grouped_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._to_dia_matrix('matrix') 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 vacuum_operator(fer_op): """Use the stabilizers to find the vacuum state in BKSF. This operator can be used to generate the vaccum state for BKSF mapping. Upon having this operator, operate it on `orignal` vaccum state |000...>, and resulted state is the vacuum state for bksf mapping. Args: fer_op (FermionicOperator): the fermionic operator in the second quanitzed form Returns: Operator: the qubit operator """ edge_list = bksf_edge_list(fer_op) num_qubits = edge_list.shape[1] vac_operator = Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) g = networkx.Graph() g.add_edges_from(tuple(edge_list.transpose())) stabs = np.asarray(networkx.cycle_basis(g)) for stab in stabs: a = Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) stab = np.asarray(stab) for i in range(np.size(stab)): a = a * edge_operator_aij(edge_list, stab[i], stab[(i + 1) % np.size(stab)]) a.scaling_coeff(1j) a += Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) vac_operator = vac_operator * a vac_operator.scaling_coeff(np.sqrt(2)) return vac_operator
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 newOP.zeros_coeff_elimination() 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 op.zeros_coeff_elimination() self.assertEqual(6 - (i + 1), len(op.paulis))
def number_operator(fer_op, mode_number=None): """Find the number operator in BKSF representation. This operator can be used to examine the number of particle in a given eigenstate. If `mode_number` is None, it checks how many particles in the eigenstate. If `mode_number` is not None, it will only check whether or not that particle at `mode_number` in the eigenstate. Args: fer_op (FermionicOperator): the fermionic operator in the second quanitzed form mode_number (int): index, it corresponds to the mode for which number operator is required. Returns: Operator: the qubit operator """ modes = fer_op.h1.modes edge_list = bksf_edge_list(fer_op) num_qubits = edge_list.shape[1] num_operator = Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) if mode_number is None: for i in range(modes): num_operator -= edge_operator_bi(edge_list, i) num_operator += Operator( paulis=[[1.0 * modes, label_to_pauli('I' * num_qubits)]]) else: num_operator += ( Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) - edge_operator_bi(edge_list, mode_number)) num_operator.scaling_coeff(0.5) return num_operator
def test_bksf_edge_op_bi(self): """Test bksf mapping, edge operator bi""" edge_matrix = np.triu(np.ones((4, 4))) edge_list = np.array( np.nonzero(np.triu(edge_matrix) - np.diag(np.diag(edge_matrix)))) qterm_b0 = edge_operator_bi(edge_list, 0) qterm_b1 = edge_operator_bi(edge_list, 1) qterm_b2 = edge_operator_bi(edge_list, 2) qterm_b3 = edge_operator_bi(edge_list, 3) ref_qterm_b0 = Operator(paulis=[[1.0, label_to_pauli('ZZZIII')]]) ref_qterm_b1 = Operator(paulis=[[1.0, label_to_pauli('ZIIZZI')]]) ref_qterm_b2 = Operator(paulis=[[1.0, label_to_pauli('IZIZIZ')]]) ref_qterm_b3 = Operator(paulis=[[1.0, label_to_pauli('IIZIZZ')]]) self.assertEqual( qterm_b0, ref_qterm_b0, "\n{} vs \n{}".format(qterm_b0.print_operators(), ref_qterm_b0.print_operators())) self.assertEqual( qterm_b1, ref_qterm_b1, "\n{} vs \n{}".format(qterm_b1.print_operators(), ref_qterm_b1.print_operators())) self.assertEqual( qterm_b2, ref_qterm_b2, "\n{} vs \n{}".format(qterm_b2.print_operators(), ref_qterm_b2.print_operators())) self.assertEqual( qterm_b3, ref_qterm_b3, "\n{} vs \n{}".format(qterm_b3.print_operators(), ref_qterm_b3.print_operators()))
def number_operator(fer_op, mode_number=None): """Find the qubit operator for the number operator in bravyi_kitaev_fast representation Args: fer_op (FermionicOperator): the fermionic operator in the second quanitzed form mode_number (int): index, it corresponds to the mode for which number operator is required. Returns: Operator: the qubit operator """ modes = fer_op.h1.modes edge_list = bravyi_kitaev_fast_edge_list(fer_op) num_qubits = edge_list.shape[1] num_operator = Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) if mode_number is None: for i in range(modes): num_operator -= edge_operator_bi(edge_list, i) num_operator += Operator( paulis=[[1.0 * modes, label_to_pauli('I' * num_qubits)]]) else: num_operator += ( Operator(paulis=[[1.0, label_to_pauli('I' * num_qubits)]]) - edge_operator_bi(edge_list, mode_number)) num_operator.scaling_coeff(0.5) return num_operator
def test_subtraction_matrix(self): """ test subtraction in the matrix mode """ pauli_a = 'IX' pauli_b = 'ZY' 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.to_matrix() opB.to_matrix() opA -= opB opA.to_paulis() self.assertEqual(2, len(opA.paulis)) self.assertEqual(0.5, opA.paulis[0][0]) self.assertEqual(-0.5, opA.paulis[1][0]) pauli_c = 'IX' coeff_c = 0.25 pauli_term_c = [coeff_c, label_to_pauli(pauli_c)] op_c = Operator(paulis=[pauli_term_c]) op_c.to_matrix() opA.to_matrix() opA -= op_c opA.to_paulis() self.assertEqual(2, len(opA.paulis)) self.assertEqual(0.25, opA.paulis[0][0])
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 test_str(self): """ test str """ 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("Representation: paulis, qubits: 4, size: 2", str(opA))
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_group_paulis_2(self): """ Test with normal grouping approach """ num_qubits = 4 pauli_term = [] for pauli_label in itertools.product('IXYZ', repeat=num_qubits): coeff = np.random.random(1)[0] pauli_term.append([coeff, label_to_pauli(''.join(pauli_label))]) op = Operator(paulis=pauli_term) op.coloring = None paulis = copy.deepcopy(op.paulis) op.convert("paulis", "grouped_paulis") flattened_grouped_paulis = [ pauli for group in op.grouped_paulis for pauli in group[1:] ] for gp in flattened_grouped_paulis: passed = False for p in paulis: if p[1] == gp[1]: passed = p[0] == gp[0] break self.assertTrue( passed, "non-existed paulis in grouped_paulis: {}".format( gp[1].to_label()))
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_label_to_pauli(self): label = 'ZXYI' p = label_to_pauli(label) v = np.asarray([1, 0, 1, 0]) w = np.asarray([0, 1, 1, 0]) p2 = Pauli(v, w) self.assertEqual(p, p2)
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_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 test_scaling_coeff(self): """ test scale """ 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)) opA.scaling_coeff(0.7) self.assertEqual(2, len(opA.paulis)) self.assertEqual(0.35, opA.paulis[0][0])
def Hamiltonian_from_file(file_name): """Compute the pauli_list from a file.""" with open(file_name, 'r+') as file: ham_array = file.readlines() ham_array = [x.strip() for x in ham_array] pauli_list = [] for i in range(len(ham_array)//2): pauli = label_to_pauli(ham_array[2*i]) Numb = float(ham_array[2*i+1]) pauli_list.append([Numb, pauli]) return pauli_list
def test_negation_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]) self.assertNotEqual(op1, op2) self.assertEqual(op1, -op2) self.assertEqual(-op1, op2) op1.scaling_coeff(-1.0) self.assertEqual(op1, op2)
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 test_load_from_file(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]) op.save_to_file('temp_op.json') load_op = Operator.load_from_file('temp_op.json') self.assertTrue(os.path.exists('temp_op.json')) self.assertEqual(op, load_op) os.remove('temp_op.json')
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 Hamiltonian_from_file(file_name): """Creates a matrix operator out of a file with a list of Paulis. Args: file_name (str): a text file containing a list of Paulis and coefficients. Returns: list: A matrix representing pauli_list """ with open(file_name, 'r+') as file: ham_array = file.readlines() ham_array = [x.strip() for x in ham_array] pauli_list = [] for i in range(len(ham_array) // 2): pauli = label_to_pauli(ham_array[2 * i]) Numb = float(ham_array[2 * i + 1]) pauli_list.append([Numb, pauli]) return pauli_list
def test_sumbit_multiple_circutis(self): """ test with single paulis """ num_qubits = 4 pauli_term = [] for pauli_label in itertools.product('IXYZ', repeat=num_qubits): coeff = np.random.random(1)[0] pauli_term.append([coeff, label_to_pauli(pauli_label)]) op = Operator(paulis=pauli_term) 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} non_matrix_mode = op.eval('paulis', circuit, 'local_statevector_simulator', execute_config)[0] matrix_mode = op.eval('matrix', circuit, 'local_statevector_simulator', execute_config)[0] self.assertAlmostEqual(matrix_mode, non_matrix_mode, 6)
def construct_circuit(self, x, qr=None, inverse=False): """ Construct the second order expansion based on given data. Args: x (numpy.ndarray): 1-D to-be-transformed data. qr (QauntumRegister): the QuantumRegister object for the circuit, if None, generate new registers with name q. inverse (bool): whether or not inverse the circuit Returns: QuantumCircuit: a quantum circuit transform data x. """ if not isinstance(x, np.ndarray): raise TypeError("x must be numpy array.") if x.ndim != 1: raise ValueError("x must be 1-D array.") if x.shape[0] != self._num_qubits: raise ValueError("number of qubits and data dimension must be the same.") if qr is None: qc = self._construct_circuit_with_template(x) else: qc = QuantumCircuit(qr) for _ in range(self._depth): for i in range(self._num_qubits): qc.u2(0, pi, qr[i]) for pauli in self._pauli_strings: coeff = self._data_map_func(self._extract_data_for_rotation(pauli, x)) p = label_to_pauli(pauli) qc += Operator.construct_evolution_circuit([[coeff, p]], 1, 1, qr) if inverse: qc.data = [gate.inverse() for gate in reversed(qc.data)] return qc
def test_bksf_edge_op_aij(self): """Test bksf mapping, edge operator aij""" edge_matrix = np.triu(np.ones((4, 4))) edge_list = np.array( np.nonzero(np.triu(edge_matrix) - np.diag(np.diag(edge_matrix)))) qterm_a01 = edge_operator_aij(edge_list, 0, 1) qterm_a02 = edge_operator_aij(edge_list, 0, 2) qterm_a03 = edge_operator_aij(edge_list, 0, 3) qterm_a12 = edge_operator_aij(edge_list, 1, 2) qterm_a13 = edge_operator_aij(edge_list, 1, 3) qterm_a23 = edge_operator_aij(edge_list, 2, 3) ref_qterm_a01 = Operator(paulis=[[1.0, label_to_pauli('XIIIII')]]) ref_qterm_a02 = Operator(paulis=[[1.0, label_to_pauli('ZXIIII')]]) ref_qterm_a03 = Operator(paulis=[[1.0, label_to_pauli('ZZXIII')]]) ref_qterm_a12 = Operator(paulis=[[1.0, label_to_pauli('ZZIXII')]]) ref_qterm_a13 = Operator(paulis=[[1.0, label_to_pauli('ZIZZXI')]]) ref_qterm_a23 = Operator(paulis=[[1.0, label_to_pauli('IZZZZX')]]) self.assertEqual( qterm_a01, ref_qterm_a01, "\n{} vs \n{}".format(qterm_a01.print_operators(), ref_qterm_a01.print_operators())) self.assertEqual( qterm_a02, ref_qterm_a02, "\n{} vs \n{}".format(qterm_a02.print_operators(), ref_qterm_a02.print_operators())) self.assertEqual( qterm_a03, ref_qterm_a03, "\n{} vs \n{}".format(qterm_a03.print_operators(), ref_qterm_a03.print_operators())) self.assertEqual( qterm_a12, ref_qterm_a12, "\n{} vs \n{}".format(qterm_a12.print_operators(), ref_qterm_a12.print_operators())) self.assertEqual( qterm_a13, ref_qterm_a13, "\n{} vs \n{}".format(qterm_a13.print_operators(), ref_qterm_a13.print_operators())) self.assertEqual( qterm_a23, ref_qterm_a23, "\n{} vs \n{}".format(qterm_a23.print_operators(), ref_qterm_a23.print_operators()))
b.name() for b in IBMQ.backends(operational=True) ] except KeyError as ex: print( 'Could not find the REMOTE q_device "{}" - available remote q_devices:\n\t{}' .format(q_device_name, remote_backends_names)) exit(1) print('Using "{}" q_device...\n'.format(q_device.name())) # Ignore warnings due to chopping of small imaginary part of the energy #import warnings #warnings.filterwarnings('ignore') # Load the Hamiltonian into Qiskit-friendly format: pauli_list = [[label_to_hamiltonian_coeff[label], label_to_pauli(label)] for label in label_to_hamiltonian_coeff] # Calculate Exact Energy classically, to compare with quantum solution: # H = make_Hamiltonian(pauli_list) classical_energy = np.amin(la.eigh(H)[0]) print( 'The exact ground state energy (the smallest eigenvalue of the Hamiltonian) is: {:.4f}' .format(classical_energy)) # Load the ansatz function from the plug-in ansatz_method = get_first_callable(custom_ansatz) ansatz_function = getattr( custom_ansatz, ansatz_method ) # ansatz_method is a string/name, ansatz_function is an imported callable
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