def _n_body_mapping(h_a): h = h_a[0] a = [] for i in range(0,len(h_a[1:]),2): a.append(h_a[1+i]) for i in range(1,len(h_a[1:]),2)[::-1]: a.append(h_a[1+i]) n = int(len(a)/2) a_lst = [] for i in range(n): a_lst.append(WeightedPauliOperator([[1,a[i][0]]])+WeightedPauliOperator([[-1j,a[i][1]]])) for i in range(n): a_lst.append(WeightedPauliOperator([[1, a[n+i][0]]])+WeightedPauliOperator([[1j, a[n+i][1]]])) product = a_lst[0] for element in a_lst[1:]: product = product*element product = (h/(2**(n*2))) * product return product
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 = WeightedPauliOperator( paulis=[[1.0, Pauli.from_label('IIIZZZ')]]) ref_qterm_b1 = WeightedPauliOperator( paulis=[[1.0, Pauli.from_label('IZZIIZ')]]) ref_qterm_b2 = WeightedPauliOperator( paulis=[[1.0, Pauli.from_label('ZIZIZI')]]) ref_qterm_b3 = WeightedPauliOperator( paulis=[[1.0, Pauli.from_label('ZZIZII')]]) self.assertEqual( qterm_b0, ref_qterm_b0, "\n{} vs \n{}".format(qterm_b0.print_details(), ref_qterm_b0.print_details())) self.assertEqual( qterm_b1, ref_qterm_b1, "\n{} vs \n{}".format(qterm_b1.print_details(), ref_qterm_b1.print_details())) self.assertEqual( qterm_b2, ref_qterm_b2, "\n{} vs \n{}".format(qterm_b2.print_details(), ref_qterm_b2.print_details())) self.assertEqual( qterm_b3, ref_qterm_b3, "\n{} vs \n{}".format(qterm_b3.print_details(), ref_qterm_b3.print_details()))
def test_add(self): """ add test """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, Pauli(pauli_a)] pauli_term_b = [coeff_b, Pauli(pauli_b)] op_a = WeightedPauliOperator(paulis=[pauli_term_a]) op_b = WeightedPauliOperator(paulis=[pauli_term_b]) ori_op_a = op_a.copy() ori_op_b = op_b.copy() new_op = op_a + op_b self.assertEqual(op_a, ori_op_a) self.assertEqual(op_b, ori_op_b) self.assertEqual(1, len(op_a.paulis)) self.assertEqual(2, len(new_op.paulis)) pauli_c = 'IXYZ' coeff_c = 0.25 pauli_term_c = [coeff_c, Pauli(pauli_c)] new_op = new_op + WeightedPauliOperator(paulis=[pauli_term_c]) self.assertEqual(2, len(new_op.paulis)) self.assertEqual(0.75, new_op.paulis[0][0])
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 quantized form mode_number (int): index, it corresponds to the mode for which number operator is required. Returns: WeightedPauliOperator: 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 = WeightedPauliOperator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) if mode_number is None: for i in range(modes): num_operator -= edge_operator_bi(edge_list, i) num_operator += \ WeightedPauliOperator(paulis=[[1.0 * modes, Pauli.from_label('I' * num_qubits)]]) else: num_operator += (WeightedPauliOperator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) - edge_operator_bi(edge_list, mode_number)) num_operator = 0.5 * num_operator return num_operator
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 quantized form Returns: WeightedPauliOperator: the qubit operator """ edge_list = bravyi_kitaev_fast_edge_list(fer_op) num_qubits = edge_list.shape[1] vac_operator = WeightedPauliOperator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) graph = networkx.Graph() graph.add_edges_from(tuple(edge_list.transpose())) stabs = np.asarray(networkx.cycle_basis(graph)) for stab in stabs: a_op = WeightedPauliOperator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) stab = np.asarray(stab) for i in range(np.size(stab)): a_op = a_op * edge_operator_aij(edge_list, stab[i], stab[(i + 1) % np.size(stab)]) * 1j # a_op.scaling_coeff(1j) a_op += WeightedPauliOperator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) vac_operator = vac_operator * a_op * np.sqrt(2) # vac_operator.scaling_coeff() return vac_operator
def test_simplification(self): """ Test Hamiltonians produce same result after simplification by constructor """ q = QuantumRegister(2, name='q') qc = QuantumCircuit(q) qc.rx(10.9891251356965, 0) qc.rx(6.286692023269373, 1) qc.rz(7.848801398269382, 0) qc.rz(9.42477796076938, 1) qc.cx(0, 1) def eval_op(op): from qiskit import execute backend = BasicAer.get_backend('qasm_simulator') evaluation_circuits = op.construct_evaluation_circuit(qc, False) job = execute(evaluation_circuits, backend, shots=1024) return op.evaluate_with_result(job.result(), False) pauli_string = [[1.0, Pauli.from_label('XX')], [-1.0, Pauli.from_label('YY')], [-1.0, Pauli.from_label('ZZ')]] wpo = WeightedPauliOperator(pauli_string) expectation_value, _ = eval_op(wpo) self.assertAlmostEqual(expectation_value, -3.0, places=2) # Half each coefficient value but double up (6 Paulis total) pauli_string = [[0.5, Pauli.from_label('XX')], [-0.5, Pauli.from_label('YY')], [-0.5, Pauli.from_label('ZZ')]] pauli_string *= 2 wpo2 = WeightedPauliOperator(pauli_string) expectation_value, _ = eval_op(wpo2) self.assertAlmostEqual(expectation_value, -3.0, places=2)
def test_iadd(self): """ iadd test """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)] pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)] op_a = WeightedPauliOperator(paulis=[pauli_term_a]) op_b = WeightedPauliOperator(paulis=[pauli_term_b]) ori_op_a = op_a.copy() ori_op_b = op_b.copy() op_a += op_b self.assertNotEqual(op_a, ori_op_a) self.assertEqual(op_b, ori_op_b) self.assertEqual(2, len(op_a.paulis)) pauli_c = 'IXYZ' coeff_c = 0.25 pauli_term_c = [coeff_c, Pauli.from_label(pauli_c)] op_a += WeightedPauliOperator(paulis=[pauli_term_c]) self.assertEqual(2, len(op_a.paulis)) self.assertEqual(0.75, op_a.paulis[0][0])
def test_sub(self): """ sub test """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)] pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)] op_a = WeightedPauliOperator(paulis=[pauli_term_a]) op_b = WeightedPauliOperator(paulis=[pauli_term_b]) ori_op_a = op_a.copy() ori_op_b = op_b.copy() new_op = op_a - op_b self.assertEqual(op_a, ori_op_a) self.assertEqual(op_b, ori_op_b) self.assertEqual(1, len(op_a.paulis)) self.assertEqual(2, len(new_op.paulis)) self.assertEqual(0.5, new_op.paulis[0][0]) self.assertEqual(-0.5, new_op.paulis[1][0]) pauli_c = 'IXYZ' coeff_c = 0.25 pauli_term_c = [coeff_c, Pauli.from_label(pauli_c)] new_op = new_op - WeightedPauliOperator(paulis=[pauli_term_c]) self.assertEqual(2, len(new_op.paulis)) self.assertEqual(0.25, new_op.paulis[0][0])
def test_simplify(self): """ simplify test """ pauli_a = 'IXYZ' pauli_b = 'IXYZ' coeff_a = 0.5 coeff_b = -0.5 pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)] pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)] op_a = WeightedPauliOperator(paulis=[pauli_term_a]) op_b = WeightedPauliOperator(paulis=[pauli_term_b]) new_op = op_a + op_b new_op.simplify() self.assertEqual(0, len(new_op.paulis), "{}".format(new_op.print_details())) self.assertTrue(new_op.is_empty()) paulis = [ Pauli.from_label(x) for x in ['IXYZ', 'XXZY', 'IIZZ', 'XXYY', 'ZZXX', 'YYYY'] ] coeffs = [0.2, 0.6, 0.8, -0.2, -0.6, -0.8] op1 = WeightedPauliOperator.from_list(paulis, coeffs) for i, pauli in enumerate(paulis): tmp_op = WeightedPauliOperator(paulis=[[-coeffs[i], pauli]]) op1 += tmp_op op1.simplify() self.assertEqual(len(paulis) - (i + 1), len(op1.paulis))
def mapping(self, map_type, threshold=0.00000001): self._map_type = map_type n = self._modes # number of fermionic modes / qubits map_type = map_type.lower() if map_type == 'jordan_wigner': a_list = self._jordan_wigner_mode(n) elif map_type == 'parity': a_list = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a_list = self._bravyi_kitaev_mode(n) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError('Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') pauli_list = WeightedPauliOperator(paulis=[]) for h in self._hs: if(h is not None): results = parallel_map(FermionicOperatorNBody._n_body_mapping, [FermionicOperatorNBody._prep_mapping(h[indexes],a_list,indexes) for indexes in list(itertools.product(range(n), repeat=len(h.shape))) if h[indexes] != 0], num_processes=aqua_globals.num_processes) for result in results: pauli_list += result ''' for h in self._hs: if h is not None: indexes_list = np.argwhere(np.abs(h)>threshold) print(h.shape,len(indexes_list)) for indexes in indexes_list: h_a = [h[tuple(indexes)]] for i in indexes: h_a.append(a_list[i]) pauli_list += FermionicOperatorNBody._n_body_mapping(h_a) for h in self._hs: if(h is not None): results = parallel_map(FermionicOperatorNBody._n_body_mapping, [FermionicOperatorNBody._prep_mapping(h[indexes],a_list,indexes) for indexes in np.argwhere(np.abs(h)>threshold)], num_processes=aqua_globals.num_processes) for result in results: pauli_list += result ''' pauli_list.chop(threshold=threshold) if self._ph_trans_shift is not None: pauli_term = [self._ph_trans_shift, Pauli.from_label('I' * self._modes)] pauli_list += WeightedPauliOperator(paulis=[pauli_term]) return pauli_list
def mapping(self, map_type, threshold=0.00000001, idx=[None] * 4): self._map_type = map_type n = self._modes # number of fermionic modes / qubits map_type = map_type.lower() if map_type == 'jordan_wigner': a_list = self._jordan_wigner_mode(n) elif map_type == 'parity': a_list = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a_list = self._bravyi_kitaev_mode(n) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError( 'Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') pauli_list = WeightedPauliOperator(paulis=[]) for m, h in enumerate(self._hs): if (h is not None): if (idx[m] is None): results = parallel_map( FermionicOperatorNBody._n_body_mapping, [ FermionicOperatorNBody._prep_mapping( h[indexes], a_list, indexes) for indexes in list( itertools.product(range(n), repeat=len(h.shape))) if h[indexes] != 0 ], num_processes=aqua_globals.num_processes) else: results = parallel_map( FermionicOperatorNBody._n_body_mapping, [ FermionicOperatorNBody._prep_mapping( h[indexes], a_list, indexes) for indexes in idx[m] if np.abs(h[indexes]) > threshold ], num_processes=aqua_globals.num_processes) for result in results: pauli_list += result pauli_list.chop(threshold=threshold) if self._ph_trans_shift is not None: pauli_term = [ self._ph_trans_shift, Pauli.from_label('I' * self._modes) ] pauli_list += WeightedPauliOperator(paulis=[pauli_term]) return pauli_list
def test_to_opflow(self): """Test for to_opflow() in WeightedPauliOperator""" pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 + 1j coeff_b = -0.5 - 1j pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)] pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)] op_a = WeightedPauliOperator(paulis=[pauli_term_a]) op_b = WeightedPauliOperator(paulis=[pauli_term_b]) legacy_op = op_a + op_b op = coeff_a * (I ^ X ^ Y ^ Z) + coeff_b * (Z ^ Y ^ I ^ X) self.assertEqual(op, legacy_op.to_opflow())
def mapping(self, map_type, threshold=0.00000001): self._map_type = map_type n = self._modes # number of fermionic modes / qubits map_type = map_type.lower() if map_type == 'jordan_wigner': a_list = self._jordan_wigner_mode(n) elif map_type == 'parity': a_list = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a_list = self._bravyi_kitaev_mode(n) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError( 'Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') pauli_list = WeightedPauliOperator(paulis=[]) import time for h in self._hs: t0 = time.time() indexes_list = np.argwhere(np.abs(h) > threshold) t1 = time.time() print("search ", h.shape, t1 - t0) for indexes in indexes_list: t2 = time.time() #print(indexes) h_a = [h[tuple(indexes)]] for i in indexes: h_a.append(a_list[i]) #print(h_a) pauli_list += FermionicOperatorNBody._n_body_mapping(h_a) t3 = time.time() print("pauli ", t3 - t2) pauli_list.chop(threshold=threshold) if self._ph_trans_shift is not None: pauli_term = [ self._ph_trans_shift, Pauli.from_label('I' * self._modes) ] pauli_list += WeightedPauliOperator(paulis=[pauli_term]) return pauli_list
def __init__(self, operator, state_in, iqft, num_time_slices=1, num_ancillae=1, expansion_mode='trotter', expansion_order=1, shallow_circuit_concat=False): """ Constructor. Args: operator (BaseOperator): the hamiltonian Operator object state_in (InitialState): the InitialState pluggable component representing the initial quantum state iqft (IQFT): the Inverse Quantum Fourier Transform pluggable component num_time_slices (int): the number of time slices num_ancillae (int): the number of ancillary qubits to use for the measurement expansion_mode (str): the expansion mode (trotter|suzuki) expansion_order (int): the suzuki expansion order shallow_circuit_concat (bool): indicate whether to use shallow (cheap) mode for circuit concatenation """ self.validate(locals()) super().__init__() self._operator = op_converter.to_weighted_pauli_operator(operator) self._num_ancillae = num_ancillae self._ret = {} self._ret['translation'] = sum( [abs(p[0]) for p in self._operator.reorder_paulis()]) self._ret['stretch'] = 0.5 / self._ret['translation'] # translate the operator self._operator.simplify() translation_op = WeightedPauliOperator([[ self._ret['translation'], Pauli(np.zeros(self._operator.num_qubits), np.zeros(self._operator.num_qubits)) ]]) translation_op.simplify() self._operator += translation_op self._pauli_list = self._operator.reorder_paulis() # stretch the operator for p in self._pauli_list: p[0] = p[0] * self._ret['stretch'] self._phase_estimation_circuit = PhaseEstimationCircuit( operator=self._operator, state_in=state_in, iqft=iqft, num_time_slices=num_time_slices, num_ancillae=num_ancillae, expansion_mode=expansion_mode, expansion_order=expansion_order, shallow_circuit_concat=shallow_circuit_concat, pauli_list=self._pauli_list) self._binary_fractions = [1 / 2**p for p in range(1, num_ancillae + 1)]
def get_operator(weight_matrix): """Generate Hamiltonian for the max-cut problem of a graph. Args: weight_matrix (numpy.ndarray) : adjacency matrix. Returns: WeightedPauliOperator: operator for the Hamiltonian float: 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: x_p = np.zeros(num_nodes, dtype=bool) z_p = np.zeros(num_nodes, dtype=bool) z_p[i] = True z_p[j] = True pauli_list.append( [0.5 * weight_matrix[i, j], Pauli((z_p, x_p))]) shift -= 0.5 * weight_matrix[i, j] return WeightedPauliOperator(paulis=pauli_list), shift
def calc_expectataion(self, pauli_str, sub_circuit): qubit_op = WeightedPauliOperator([[1, Pauli.from_label(pauli_str)]]) sv_mode = False qi = QuantumInstance(backend=Aer.get_backend('qasm_simulator'), shots=1000, seed_simulator=100, seed_transpiler=2) if qi.is_statevector: sv_mode = True # Make sure that the eval quantum/ classical registers in the circuit are named 'q'/'c' qc = qubit_op.construct_evaluation_circuit( statevector_mode=sv_mode, wave_function=sub_circuit, qr=find_regs_by_name(sub_circuit, 'q'), use_simulator_operator_mode=True) result = qi.execute(qc) avg, std = qubit_op.evaluate_with_result( statevector_mode=sv_mode, result=result, use_simulator_operator_mode=True) return avg
def _one_body(edge_list, p, q, h1_pq): # pylint: disable=invalid-name """ Map the term a^\\dagger_p a_q + a^\\dagger_q a_p to qubit operator. Args: edge_list (numpy.ndarray): 2xE matrix, each indicates (from, to) pair p (int): index of the one body term q (int): index of the one body term h1_pq (complex): coefficient of the one body term at (p, q) Return: WeightedPauliOperator: mapped qubit operator """ # Handle off-diagonal terms. if p != q: a_i, b_i = sorted([p, q]) b_a = edge_operator_bi(edge_list, a_i) b_b = edge_operator_bi(edge_list, b_i) a_ab = edge_operator_aij(edge_list, a_i, b_i) qubit_op = a_ab * b_b + b_a * a_ab final_coeff = -1j * 0.5 # Handle diagonal terms. else: b_p = edge_operator_bi(edge_list, p) v = np.zeros(edge_list.shape[1]) w = np.zeros(edge_list.shape[1]) id_pauli = Pauli(v, w) id_op = WeightedPauliOperator(paulis=[[1.0, id_pauli]]) qubit_op = id_op - b_p final_coeff = 0.5 qubit_op = (final_coeff * h1_pq) * qubit_op qubit_op.simplify() return qubit_op
def from_openfermion_qubit_operator_list(cls, of_op_list: List[QubitOperator]): for op in of_op_list: if not isinstance(op, QubitOperator): raise ValueError( 'Found element in list that is not a QubitOperator') num_qubits = np.max( np.max([[pair[0] for pair in tups] for tups in list( QubitOperator.accumulate(of_op_list).terms.keys())])) + 1 op_list_res = [] for op in of_op_list: pauli_list = [] for tup, coeff in op.terms.items(): if not np.isreal(coeff): raise ValueError( 'All coefficients must be real so that resulting operator is Hermitian' ) pauli_list.append([ coeff, Pauli.from_label(tuples_to_string(tup, num_qubits)) ]) op_res = WeightedPauliOperator(paulis=pauli_list) op_list_res.append(op_res) result = cls.from_operator_list(op_list_res) result.name = 'openfermion_qubit_operator_list'.format(of_op_list) return result
def get_ising_qubitops(isng,qubits): h_i = {} j_ij = {} constant = 0 for (key, value) in zip(isng.keys(), isng.values()): if len(key) == 1: h_i[key[0]] = value elif len(key) == 2: j_ij[key] = value elif len(key) == 0: constant = value num_nodes = qubits pauli_list = [] for key, value in j_ij.items(): xp = np.zeros(num_nodes, dtype=np.bool) zp = np.zeros(num_nodes, dtype=np.bool) zp[key[0]] = True zp[key[1]] = True pauli_list.append([value, Pauli(zp, xp)]) for key, value in h_i.items(): xp = np.zeros(num_nodes, dtype=np.bool) zp = np.zeros(num_nodes, dtype=np.bool) zp[key] = True pauli_list.append([value, Pauli(zp, xp)]) return WeightedPauliOperator(paulis=pauli_list), constant
def get_operator(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: tuple(WeightedPauliOperator, 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): x_p = np.zeros(n, dtype=np.bool) z_p = np.zeros(n, dtype=np.bool) z_p[i] = True z_p[j] = True pauli_list.append([2. * values[i] * values[j], Pauli(z_p, x_p)]) return WeightedPauliOperator(paulis=pauli_list), sum(values * values)
def test_str(self): """ str test """ pauli_a = 'IXYZ' pauli_b = 'ZYIX' coeff_a = 0.5 coeff_b = 0.5 pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)] pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)] op_a = WeightedPauliOperator(paulis=[pauli_term_a]) op_b = WeightedPauliOperator(paulis=[pauli_term_b]) op_a += op_b self.assertEqual("Representation: paulis, qubits: 4, size: 2", str(op_a)) op_a = WeightedPauliOperator(paulis=[pauli_term_a], name='ABC') self.assertEqual("ABC: Representation: paulis, qubits: 4, size: 1", str(op_a))
def _setup(self, operator: Optional[BaseOperator]) -> None: self._operator = None self._ret = {} self._pauli_list = None self._phase_estimation_circuit = None if operator: self._operator = op_converter.to_weighted_pauli_operator(operator.copy()) self._ret['translation'] = sum([abs(p[0]) for p in self._operator.reorder_paulis()]) self._ret['stretch'] = 0.5 / self._ret['translation'] # translate the operator self._operator.simplify() translation_op = WeightedPauliOperator([ [ self._ret['translation'], Pauli( np.zeros(self._operator.num_qubits), np.zeros(self._operator.num_qubits) ) ] ]) translation_op.simplify() self._operator += translation_op self._pauli_list = self._operator.reorder_paulis() # stretch the operator for p in self._pauli_list: p[0] = p[0] * self._ret['stretch'] self._phase_estimation_circuit = PhaseEstimationCircuit( operator=self._operator, state_in=self._state_in, iqft=self._iqft, num_time_slices=self._num_time_slices, num_ancillae=self._num_ancillae, expansion_mode=self._expansion_mode, expansion_order=self._expansion_order, shallow_circuit_concat=self._shallow_circuit_concat, pauli_list=self._pauli_list )
def _combine(self, modes: List[int], paulis: dict, coeff: float) -> WeightedPauliOperator: """ Combines the paulis of each mode together in one WeightedPauliOperator. Args: modes: list with the indices of the modes to be combined paulis: dict containing the list of paulis for each mode coeff: coefficient multiplying the term Returns: WeightedPauliOperator acting on the modes given in argument """ m = 0 if m in modes: pauli_list = paulis[m] else: a_z = np.asarray([0] * self._basis[m], dtype=bool) a_x = np.asarray([0] * self._basis[m], dtype=bool) pauli_list = [(1, Pauli((a_z, a_x)))] for m in range(1, self._num_modes): if m in modes: new_list = paulis[m] else: a_z = np.asarray([0] * self._basis[m], dtype=bool) a_x = np.asarray([0] * self._basis[m], dtype=bool) new_list = [(1, Pauli((a_z, a_x)))] pauli_list = self._extend(pauli_list, new_list) new_pauli_list = [] for pauli in pauli_list: new_pauli_list.append([coeff * pauli[0], pauli[1]]) return WeightedPauliOperator(new_pauli_list)
def get_operator(w): """Generate Hamiltonian for the maximum stable set in a graph. Args: w (numpy.ndarray) : adjacency matrix. Returns: tuple(WeightedPauliOperator, 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: x_p = np.zeros(num_nodes, dtype=np.bool) z_p = np.zeros(num_nodes, dtype=np.bool) z_p[i] = True z_p[j] = True pauli_list.append([1.0, Pauli(z_p, x_p)]) shift += 1 for i in range(num_nodes): degree = np.sum(w[i, :]) x_p = np.zeros(num_nodes, dtype=np.bool) z_p = np.zeros(num_nodes, dtype=np.bool) z_p[i] = True pauli_list.append([degree - 1 / 2, Pauli(z_p, x_p)]) return WeightedPauliOperator(paulis=pauli_list), shift - num_nodes / 2
def _setup(self): self._ret['translation'] = sum( [abs(p[0]) for p in self._operator.reorder_paulis()]) self._ret['stretch'] = 0.5 / self._ret['translation'] # translate the operator self._operator.simplify() translation_op = WeightedPauliOperator([[ self._ret['translation'], Pauli(np.zeros(self._operator.num_qubits), np.zeros(self._operator.num_qubits)) ]]) translation_op.simplify() self._operator += translation_op self._pauli_list = self._operator.reorder_paulis() # stretch the operator for p in self._pauli_list: p[0] = p[0] * self._ret['stretch'] if len(self._pauli_list) == 1: slice_pauli_list = self._pauli_list else: if self._expansion_mode == 'trotter': slice_pauli_list = self._pauli_list else: slice_pauli_list = suzuki_expansion_slice_pauli_list( self._pauli_list, 1, self._expansion_order) self._slice_pauli_list = slice_pauli_list
def create_operator(michele, ratio): # Crea gli operatori da Pauli da misurare pesati if michele == 0: op = [] op.append((1/2,Pauli(label = 'XXII'))) op.append((1/2,Pauli(label = 'YYII'))) op.append((1/2,Pauli(label = 'IIXX'))) op.append((1/2,Pauli(label = 'IIYY'))) op.append((ratio/4,Pauli(label = 'ZIIZ'))) op.append((ratio/4,Pauli(label = 'IZZI'))) op.append((ratio/4,Pauli(label = 'ZIII'))) op.append((ratio/4,Pauli(label = 'IZII'))) op.append((ratio/4,Pauli(label = 'IIZI'))) op.append((ratio/4,Pauli(label = 'IIIZ'))) elif michele == 1: op = [] op.append((1/2,Pauli(label = 'IYZY'))) op.append((1/2,Pauli(label = 'IXZX'))) op.append((1/2,Pauli(label = 'YZYI'))) op.append((1/2,Pauli(label = 'XZXI'))) op.append((-ratio/4,Pauli(label = 'IIIZ'))) op.append((-ratio/4,Pauli(label = 'IZII'))) op.append((ratio/4,Pauli(label = 'IZIZ'))) op.append((-ratio/4,Pauli(label = 'IIZI'))) op.append((-ratio/4,Pauli(label = 'ZIII'))) op.append((ratio/4,Pauli(label = 'ZIZI'))) operator = WeightedPauliOperator(op, basis=None, z2_symmetries=[0,1], atol=1e-12, name=None) return operator
def _build_hopping_operator(index, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, z2_symmetries): h_1 = np.zeros((num_orbitals, num_orbitals)) h_2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals)) if len(index) == 2: i, j = index h_1[i, j] = 1.0 h_1[j, i] = -1.0 elif len(index) == 4: i, j, k, m = index h_2[i, j, k, m] = 1.0 h_2[m, k, j, i] = -1.0 dummpy_fer_op = FermionicOperator(h1=h_1, h2=h_2) qubit_op = dummpy_fer_op.mapping(qubit_mapping) if two_qubit_reduction: qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles) if not z2_symmetries.is_empty(): symm_commuting = True for symmetry in z2_symmetries.symmetries: symmetry_op = WeightedPauliOperator(paulis=[[1.0, symmetry]]) symm_commuting = qubit_op.commute_with(symmetry_op) if not symm_commuting: break qubit_op = z2_symmetries.taper(qubit_op) if symm_commuting else None if qubit_op is None: logger.debug('Excitation (%s) is skipped since it is not commuted ' 'with symmetries', ','.join([str(x) for x in index])) return qubit_op, index
def _one_body_mapping( self, h1_ij_aij: Tuple[float, Pauli, Pauli]) -> WeightedPauliOperator: """ Subroutine for one body mapping. Args: h1_ij_aij: value of h1 at index (i,j), pauli at index i, pauli at index j Returns: Operator for those paulis """ h1_ij, a_i, a_j = h1_ij_aij pauli_list = [] for alpha in range(2): for beta in range(2): p_a = a_i[alpha].dot(a_j[beta]) pauli_prod = p_a[:], (-1j)**p_a.phase coeff = h1_ij / 4 * pauli_prod[1] * np.power( -1j, alpha) * np.power(1j, beta) pauli_term = [coeff, pauli_prod[0]] pauli_list.append(pauli_term) op = WeightedPauliOperator(pauli_list) return op
def _two_body_mapping(h2_ijkm_a_ijkm, threshold): """ Subroutine for two body mapping. We use the chemists notation for the two-body term, h2(i,j,k,m) adag_i adag_k a_m a_j. Args: h2_ijkm_aijkm (tuple): value of h2 at index (i,j,k,m), pauli at index i, pauli at index j, pauli at index k, pauli at index m threshold: (float): threshold to remove a pauli Returns: WeightedPauliOperator: Operator for those paulis """ h2_ijkm, a_i, a_j, a_k, a_m = h2_ijkm_a_ijkm 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 = Pauli.sgn_prod(a_i[alpha], a_k[beta]) pauli_prod_2 = Pauli.sgn_prod(pauli_prod_1[0], a_m[gamma]) pauli_prod_3 = Pauli.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 WeightedPauliOperator(paulis=pauli_list)
def _build_single_hopping_operator(index, num_particles, num_orbitals, qubit_mapping, two_qubit_reduction, z2_symmetries): h_1 = np.zeros((num_orbitals, num_orbitals), dtype=complex) h_2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals), dtype=complex) if len(index) == 2: i, j = index h_1[i, j] = 4.0 elif len(index) == 4: i, j, k, m = index h_2[i, j, k, m] = 16.0 fer_op = FermionicOperator(h_1, h_2) qubit_op = fer_op.mapping(qubit_mapping) if qubit_mapping == 'parity' and two_qubit_reduction: qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles) commutativities = [] if not z2_symmetries.is_empty(): for symmetry in z2_symmetries.symmetries: symmetry_op = WeightedPauliOperator(paulis=[[1.0, symmetry]]) commuting = qubit_op.commute_with(symmetry_op) anticommuting = qubit_op.anticommute_with(symmetry_op) if commuting != anticommuting: # only one of them is True if commuting: commutativities.append(True) elif anticommuting: commutativities.append(False) else: raise AquaError("Symmetry {} is nor commute neither anti-commute " "to exciting operator.".format(symmetry.to_label())) return qubit_op, commutativities