def test_create_from_paulis_0(self): """Test with single paulis.""" num_qubits = 3 for pauli_label in itertools.product('IXYZ', repeat=num_qubits): coeff = np.random.random(1)[0] pauli_term = [coeff, Pauli.from_label(pauli_label)] op = Operator(paulis=[pauli_term]) depth = 1 var_form = RYRZ(op.num_qubits, depth) circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters))) run_config = {'shots': 1} backend = BasicAer.get_backend('statevector_simulator') non_matrix_mode = op.eval('paulis', circuit, backend, run_config=run_config)[0] matrix_mode = op.eval('matrix', circuit, backend, run_config=run_config)[0] self.assertAlmostEqual(matrix_mode, non_matrix_mode, 6)
def test_create_from_matrix(self): """Test with matrix initialization.""" for num_qubits in range(1, 3): m_size = np.power(2, num_qubits) matrix = np.random.rand(m_size, m_size) op = Operator(matrix=matrix) depth = 1 var_form = RYRZ(op.num_qubits, depth) circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters))) backend = BasicAer.get_backend('statevector_simulator') run_config = {'shots': 1} non_matrix_mode = op.eval('paulis', circuit, backend, run_config=run_config)[0] matrix_mode = op.eval('matrix', circuit, backend, run_config=run_config)[0] self.assertAlmostEqual(matrix_mode, non_matrix_mode, 6)
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, Pauli.from_label(pauli_a)] pauli_term_b = [coeff_b, Pauli.from_label(pauli_b)] op_a = Operator(paulis=[pauli_term_a]) op_b = Operator(paulis=[pauli_term_b]) op_a += op_b self.assertEqual(2, len(op_a.paulis)) op_a.scaling_coeff(0.7) self.assertEqual(2, len(op_a.paulis)) self.assertEqual(0.35, op_a.paulis[0][0])
def _build_hopping_operator(index, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, qubit_tapering, symmetries, cliffords, sq_list, tapering_values): def check_commutativity(op_1, op_2): com = op_1 * op_2 - op_2 * op_1 com.zeros_coeff_elimination() return True if com.is_empty() else False h1 = np.zeros((num_orbitals, num_orbitals)) h2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals)) if len(index) == 2: i, j = index h1[i, j] = 1.0 h1[j, i] = -1.0 elif len(index) == 4: i, j, k, m = index h2[i, j, k, m] = 1.0 h2[m, k, j, i] = -1.0 dummpy_fer_op = FermionicOperator(h1=h1, h2=h2) qubit_op = dummpy_fer_op.mapping(qubit_mapping) qubit_op = qubit_op.two_qubit_reduced_operator(num_particles) \ if two_qubit_reduction else qubit_op if qubit_tapering: for symmetry in symmetries: symmetry_op = Operator(paulis=[[1.0, symmetry]]) symm_commuting = check_commutativity(symmetry_op, qubit_op) if not symm_commuting: break if qubit_tapering: if symm_commuting: qubit_op = Operator.qubit_tapering(qubit_op, cliffords, sq_list, tapering_values) else: qubit_op = None if qubit_op is None: logger.debug('Excitation ({}) is skipped since it is not commuted ' 'with symmetries'.format(','.join( [str(x) for x in index]))) return qubit_op
def init_params(cls, params, matrix): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary matrix: two dimensional array which represents the operator """ if matrix is None: raise AquaError("Operator instance is required.") if not isinstance(matrix, np.ndarray): matrix = np.array(matrix) eigs_params = params.get(Pluggable.SECTION_KEY_EIGS) args = {k: v for k, v in eigs_params.items() if k != 'name'} num_ancillae = eigs_params['num_ancillae'] negative_evals = eigs_params['negative_evals'] # Adding an additional flag qubit for negative eigenvalues if negative_evals: num_ancillae += 1 args['num_ancillae'] = num_ancillae args['operator'] = Operator(matrix=matrix) # Set up iqft, we need to add num qubits to params which is our num_ancillae bits here iqft_params = params.get(Pluggable.SECTION_KEY_IQFT) iqft_params['num_qubits'] = num_ancillae args['iqft'] = get_pluggable_class( PluggableType.IQFT, iqft_params['name']).init_params(params) # For converting the encoding of the negative eigenvalues, we need two # additional instances for QFT and IQFT if negative_evals: ne_params = params qft_num_qubits = iqft_params['num_qubits'] ne_qft_params = params.get(Pluggable.SECTION_KEY_QFT) ne_qft_params['num_qubits'] = qft_num_qubits - 1 ne_iqft_params = params.get(Pluggable.SECTION_KEY_IQFT) ne_iqft_params['num_qubits'] = qft_num_qubits - 1 ne_params['qft'] = ne_qft_params ne_params['iqft'] = ne_iqft_params args['ne_qfts'] = [ get_pluggable_class( PluggableType.QFT, ne_qft_params['name']).init_params(ne_params), get_pluggable_class( PluggableType.IQFT, ne_iqft_params['name']).init_params(ne_params) ] else: args['ne_qfts'] = [None, None] return cls(**args)
def test_submit_multiple_circuits(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, Pauli.from_label(pauli_label)]) op = Operator(paulis=pauli_term) depth = 1 var_form = RYRZ(op.num_qubits, depth) circuit = var_form.construct_circuit(np.array(np.random.randn(var_form.num_parameters))) run_config = RunConfig(shots=1) backend = BasicAer.get_backend('statevector_simulator') non_matrix_mode = op.eval('paulis', circuit, backend, run_config=run_config)[0] matrix_mode = op.eval('matrix', circuit, backend, run_config=run_config)[0] self.assertAlmostEqual(matrix_mode, non_matrix_mode, 6)
def get_exact_cover_qubitops(list_of_subsets): """Construct the Hamiltonian for the exact solver problem Args: list_of_subsets: list of lists (i.e., subsets) Returns: operator.Operator, float: operator for the Hamiltonian and a constant shift for the obj function. Assumption: the union of the subsets contains all the elements to cover The Hamiltonian is: sum_{each element e}{(1-sum_{every subset_i that contains e}{Xi})^2}, where Xi (Xi=1 or 0) means whether should include the subset i. """ n = len(list_of_subsets) U = [] for sub in list_of_subsets: U.extend(sub) U = np.unique(U) # U is the universe shift = 0 pauli_list = [] for e in U: cond = [True if e in sub else False for sub in list_of_subsets] indices_has_e = np.arange(n)[cond] num_has_e = len(indices_has_e) Y = 1 - 0.5 * num_has_e shift += Y * Y for i in indices_has_e: for j in indices_has_e: if i != j: wp = np.zeros(n) vp = np.zeros(n) vp[i] = 1 vp[j] = 1 pauli_list.append([0.25, Pauli(vp, wp)]) else: shift += 0.25 for i in indices_has_e: wp = np.zeros(n) vp = np.zeros(n) vp[i] = 1 pauli_list.append([-Y, Pauli(vp, wp)]) return Operator(paulis=pauli_list), shift
def get_vertexcover_qubitops(weight_matrix): """Generate Hamiltonian for the vertex cover 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 color some vertices as red such that every edge is connected to some red vertex 2 minimize the vertices to be colored as red Hamiltonian: H = A * H_A + H_B H_A = sum\_{(i,j)\in E}{(1-Xi)(1-Xj)} H_B = sum_{i}{Zi} H_A is to achieve goal 1 while H_b is to achieve goal 2. H_A is hard constraint so we place a huge penality on it. A=5. Note Xi = (Zi+1)/2 """ n = len(weight_matrix) pauli_list = [] shift = 0 A = 5 for i in range(n): for j in range(i): if (weight_matrix[i, j] != 0): wp = np.zeros(n) vp = np.zeros(n) vp[i] = 1 vp[j] = 1 pauli_list.append([A*0.25, Pauli(vp, wp)]) vp2 = np.zeros(n) vp2[i] = 1 pauli_list.append([-A*0.25, Pauli(vp2, wp)]) vp3 = np.zeros(n) vp3[j] = 1 pauli_list.append([-A*0.25, Pauli(vp3, wp)]) shift += A*0.25 for i in range(n): wp = np.zeros(n) vp = np.zeros(n) vp[i] = 1 pauli_list.append([0.5, Pauli(vp, wp)]) shift += 0.5 return Operator(paulis=pauli_list), shift
def stabilizers(fer_op): edge_list = bravyi_kitaev_fast_edge_list(fer_op) num_qubits = edge_list.shape[1] # vac_operator = Operator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) g = networkx.Graph() g.add_edges_from(tuple(edge_list.transpose())) stabs = np.asarray(networkx.cycle_basis(g)) stabilizers = [] for stab in stabs: a = Operator(paulis=[[1.0, Pauli.from_label('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) stabilizers.append(a) return stabilizers
def test_addition_paulis_inplace(self): """Test addition.""" 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 = Operator(paulis=[pauli_term_a]) op_b = Operator(paulis=[pauli_term_b]) op_a += 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 += Operator(paulis=[pauli_term_c]) self.assertEqual(2, len(op_a.paulis)) self.assertEqual(0.75, op_a.paulis[0][0])
def test_group_paulis_1(self): """ Test with color 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, Pauli.from_label(''.join(pauli_label))]) op = Operator(paulis=pauli_term) paulis = copy.deepcopy(op.paulis) op.to_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 get_set_packing_qubitops(list_of_subsets): """Construct the Hamiltonian for the set packing Args: list_of_subsets: list of lists (i.e., subsets) Returns: operator.Operator, float: operator for the Hamiltonian and a constant shift for the obj function. find the maximal number of subsets which are disjoint pairwise. Hamiltonian: H = A Ha + B Hb Ha = sum_{Si and Sj overlaps}{XiXj} Hb = -sum_{i}{Xi} Ha is to ensure the disjoint condition, while Hb is to achieve the maximal number. Ha is hard constraint that must be satisified. Therefore A >> B. In the following, we set A=10 and B = 1 Note Xi = (Zi + 1)/2 """ shift = 0 pauli_list = [] A = 10 n = len(list_of_subsets) for i in range(n): for j in range(i): if set(list_of_subsets[i]) & set(list_of_subsets[j]): wp = np.zeros(n) vp = np.zeros(n) vp[i] = 1 vp[j] = 1 pauli_list.append([A * 0.25, Pauli(vp, wp)]) vp2 = np.zeros(n) vp2[i] = 1 pauli_list.append([A * 0.25, Pauli(vp2, wp)]) vp3 = np.zeros(n) vp3[j] = 1 pauli_list.append([A * 0.25, Pauli(vp3, wp)]) shift += A * 0.25 for i in range(n): wp = np.zeros(n) vp = np.zeros(n) vp[i] = 1 pauli_list.append([-0.5, Pauli(vp, wp)]) shift += -0.5 return Operator(paulis=pauli_list), shift
def test_subtraction_inplace(self): """ test subtraction in place """ 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 = Operator(paulis=[pauli_term_a]) op_b = Operator(paulis=[pauli_term_b]) op_a -= 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 -= Operator(paulis=[pauli_term_c]) self.assertEqual(2, len(op_a.paulis)) self.assertEqual(0.25, op_a.paulis[0][0])
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, Pauli.from_label(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 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, 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 += Operator( paulis=[[1.0 * modes, Pauli.from_label('I' * num_qubits)]]) else: num_operator += ( Operator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) - edge_operator_bi(edge_list, mode_number)) num_operator.scaling_coeff(0.5) return num_operator
def setUp(self): super().setUp() np.random.seed(50) pauli_dict = { 'paulis': [{"coeff": {"imag": 0.0, "real": -1.052373245772859}, "label": "II"}, {"coeff": {"imag": 0.0, "real": 0.39793742484318045}, "label": "IZ"}, {"coeff": {"imag": 0.0, "real": -0.39793742484318045}, "label": "ZI"}, {"coeff": {"imag": 0.0, "real": -0.01128010425623538}, "label": "ZZ"}, {"coeff": {"imag": 0.0, "real": 0.18093119978423156}, "label": "XX"} ] } qubit_op = Operator.load_from_dict(pauli_dict) self.algo_input = EnergyInput(qubit_op)
def test_tapered_op(self): # set_qiskit_chemistry_logging(logging.DEBUG) tapered_ops = [] for coeff in itertools.product([1, -1], repeat=len(self.sq_list)): tapered_op = Operator.qubit_tapering(self.qubit_op, self.cliffords, self.sq_list, list(coeff)) tapered_ops.append((list(coeff), tapered_op)) smallest_idx = 0 # Prior knowledge of which tapered_op has ground state the_tapered_op = tapered_ops[smallest_idx][1] the_coeff = tapered_ops[smallest_idx][0] optimizer = SLSQP(maxiter=1000) init_state = HartreeFock( num_qubits=the_tapered_op.num_qubits, num_orbitals=self.core._molecule_info['num_orbitals'], qubit_mapping=self.core._qubit_mapping, two_qubit_reduction=self.core._two_qubit_reduction, num_particles=self.core._molecule_info['num_particles'], sq_list=self.sq_list) var_form = UCCSD( num_qubits=the_tapered_op.num_qubits, depth=1, num_orbitals=self.core._molecule_info['num_orbitals'], num_particles=self.core._molecule_info['num_particles'], active_occupied=None, active_unoccupied=None, initial_state=init_state, qubit_mapping=self.core._qubit_mapping, two_qubit_reduction=self.core._two_qubit_reduction, num_time_slices=1, cliffords=self.cliffords, sq_list=self.sq_list, tapering_values=the_coeff, symmetries=self.symmetries) algo = VQE(the_tapered_op, var_form, optimizer, 'matrix') backend = BasicAer.get_backend('statevector_simulator') quantum_instance = QuantumInstance(backend=backend) algo_result = algo.run(quantum_instance) lines, result = self.core.process_algorithm_result(algo_result) self.assertAlmostEqual(result['energy'], self.reference_energy, places=6)
def test_addition_paulis_noninplace(self): """ test addition """ 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 = Operator(paulis=[pauli_term_a]) op_b = Operator(paulis=[pauli_term_b]) copy_op_a = copy.deepcopy(op_a) new_op = op_a + op_b self.assertEqual(copy_op_a, op_a) self.assertEqual(2, len(new_op.paulis)) pauli_c = 'IXYZ' coeff_c = 0.25 pauli_term_c = [coeff_c, Pauli.from_label(pauli_c)] new_op = new_op + Operator(paulis=[pauli_term_c]) self.assertEqual(2, len(new_op.paulis)) self.assertEqual(0.75, new_op.paulis[0][0])
def test_zero_elimination(self): pauli_a = 'IXYZ' coeff_a = 0.0 pauli_term_a = [coeff_a, Pauli.from_label(pauli_a)] op_a = Operator(paulis=[pauli_term_a]) self.assertEqual(1, len(op_a.paulis), "{}".format(op_a.print_operators())) op_a.zeros_coeff_elimination() self.assertEqual(0, len(op_a.paulis), "{}".format(op_a.print_operators()))
def __init__(self, cost_operator, p, initial_state=None): self._cost_operator = cost_operator self._p = p self._initial_state = initial_state 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_eoh(self): SIZE = 2 temp = np.random.random((2 ** SIZE, 2 ** SIZE)) h1 = temp + temp.T qubit_op = Operator(matrix=h1) temp = np.random.random((2 ** SIZE, 2 ** SIZE)) h1 = temp + temp.T evo_op = Operator(matrix=h1) state_in = Custom(SIZE, state='random') evo_time = 1 num_time_slices = 100 eoh = EOH(qubit_op, state_in, evo_op, 'paulis', evo_time, num_time_slices) backend = BasicAer.get_backend('statevector_simulator') quantum_instance = QuantumInstance(backend, shots=1, max_credits=10, pass_manager=PassManager()) # self.log.debug('state_out:\n\n') ret = eoh.run(quantum_instance) self.log.debug('Evaluation result: {}'.format(ret))
def construct_circuit(self, k=None, omega=0, measurement=False): """Construct the kth iteration Quantum Phase Estimation circuit. For details of parameters, please see Fig. 2 in https://arxiv.org/pdf/quant-ph/0610214.pdf. Args: k (int): the iteration idx. omega (float): the feedback angle. measurement (bool): Boolean flag to indicate if measurement should be included in the circuit. Returns: QuantumCircuit: the quantum circuit per iteration """ k = self._num_iterations if k is None else k a = QuantumRegister(1, name='a') q = QuantumRegister(self._operator.num_qubits, name='q') self._ancillary_register = a self._state_register = q qc = QuantumCircuit(q) qc += self._state_in.construct_circuit('circuit', q) # hadamard on a[0] qc.add_register(a) qc.u2(0, np.pi, a[0]) # controlled-U qc_evolutions = Operator.construct_evolution_circuit( self._slice_pauli_list, -2 * np.pi, self._num_time_slices, q, a, unitary_power=2**(k - 1), shallow_slicing=self._shallow_circuit_concat) if self._shallow_circuit_concat: qc.data += qc_evolutions.data else: qc += qc_evolutions # global phase due to identity pauli qc.u1(2 * np.pi * self._ancilla_phase_coef * (2**(k - 1)), a[0]) # rz on a[0] qc.u1(omega, a[0]) # hadamard on a[0] qc.u2(0, np.pi, a[0]) if measurement: c = ClassicalRegister(1, name='c') qc.add_register(c) # qc.barrier(self._ancillary_register) qc.measure(self._ancillary_register, c) return qc
def main(): # may change graph. But be sure to also change the num_qubits to the appropriate number of nodes in the graph graph = [(2, 0), (2, 1)] num_qubits = 3 # number of unique nodes in the graph # algorithm properties p = 2 # number of time steps beta = np.random.uniform(0, np.pi*2, p) gamma = np.random.uniform(0, np.pi*2, p) # n_iter = 10 # number of iterations of the optimization procedure # mixing hamiltonian. May pauli X each qubit (change their color for maxcut) mixing_hamiltonian = reduce(lambda x, y: x + y, [pauli_x(i, 1, num_qubits) for i in range(num_qubits)]) # identity operation. As a utility to get the correct cost hamiltonian id_pauli = Pauli(np.zeros(num_qubits), np.zeros(num_qubits)) id_operation = Operator([[1, id_pauli]]) # cost Hamiltonian: summation of pauli z products. To maximize the number of adjacent different nodes cost_hamiltonian = reduce(lambda x, y: x + y, [id_operation - product_pauli_z(i, j, 1, n_q=num_qubits) for i, j in graph]) # circuit initial state vector. All states in equal superposition init_state_vect = [1 for i in range(2**num_qubits)] init_state = Custom(num_qubits, state_vector=init_state_vect) # initialize quantum circuit qr = QuantumRegister(num_qubits) init_circ = init_state.construct_circuit('circuit', qr) # find optimal beta and gamma evaluate = partial(neg_evaluate_circuit, qr=qr, p=p, m_H=mixing_hamiltonian, c_H=cost_hamiltonian, init_circ=init_circ) result = minimize(evaluate, np.concatenate([gamma, beta]), method='L-BFGS-B') print(result) # now use the result of the gathered angles to find the answer circuit = create_circuit(qr, result['x'][:p], result['x'][p:], p, m_H=mixing_hamiltonian, c_H=cost_hamiltonian, init_circ=init_circ) backend = BasicAer.get_backend('statevector_simulator') job = execute(circuit, backend) state = np.asarray(job.result().get_statevector(circuit)) print(np.absolute(state)) print(np.angle(state))
def get_graph_partition_qubitops(weight_matrix): r"""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: xp = np.zeros(num_nodes, dtype=np.bool) zp = np.zeros(num_nodes, dtype=np.bool) zp[i] = True zp[j] = True pauli_list.append([-0.5, Pauli(zp, xp)]) shift += 0.5 for i in range(num_nodes): for j in range(num_nodes): if i != j: xp = np.zeros(num_nodes, dtype=np.bool) zp = np.zeros(num_nodes, dtype=np.bool) zp[i] = True zp[j] = True pauli_list.append([1, Pauli(zp, xp)]) else: shift += 1 return Operator(paulis=pauli_list), shift
def get_vehiclerouting_qubitops(instance, n, K): """Converts an instnance of a vehicle routing problem into a list of Paulis. Args: instance (numpy.ndarray) : a customers-to-customers distance matrix. n (integer) : the number of customers. K (integer) : the number of vehicles available. Returns: operator.Operator: operator for the Hamiltonian. """ N = (n - 1) * n (Q, g, c) = get_vehiclerouting_matrices(instance, n, K) # Defining the new matrices in the Z-basis Iv = np.ones(N) Qz = (Q / 4) gz = (-g / 2 - np.dot(Iv, Q / 4) - np.dot(Q / 4, Iv)) cz = (c + np.dot(g / 2, Iv) + np.dot(Iv, np.dot(Q / 4, Iv))) cz = cz + np.trace(Qz) Qz = Qz - np.diag(np.diag(Qz)) # Getting the Hamiltonian in the form of a list of Pauli terms pauli_list = [] for i in range(N): if gz[i] != 0: wp = np.zeros(N) vp = np.zeros(N) vp[i] = 1 pauli_list.append((gz[i], Pauli(vp, wp))) for i in range(N): for j in range(i): if Qz[i, j] != 0: wp = np.zeros(N) vp = np.zeros(N) vp[i] = 1 vp[j] = 1 pauli_list.append((2 * Qz[i, j], Pauli(vp, wp))) pauli_list.append((cz, Pauli(np.zeros(N), np.zeros(N)))) return Operator(paulis=pauli_list)
def getPauliMatrix(matrix): rows = matrix.shape[0] paulis = [] for row_pos in range(rows): for col_pos in range(matrix.shape[1]): temp = {} temp["imag"] = 0.0 temp["real"] = matrix[row_pos, col_pos] label_pauli = ["I" for _ in range(rows)] if row_pos != col_pos: label_pauli[row_pos] = 'Z' label_pauli[col_pos] = 'Z' label_pauli = "".join(label_pauli) paulis.append({"coeff": temp, "label": label_pauli}) paulis_dict = {"paulis": paulis} for i in paulis_dict["paulis"]: print(i) pauli_matrix = Operator.load_from_dict(paulis_dict) return pauli_matrix
def edge_operator_aij(edge_list, i, j): """Calculate the edge operator A_ij. The definitions used here are consistent with arXiv:quant-ph/0003137 Args: edge_list (numpy.ndarray): a 2xE matrix, where E is total number of edge and each pair denotes (from, to) i (int): specifying the edge operator A j (int): specifying the edge operator A Returns: Operator: qubit operator """ v = np.zeros(edge_list.shape[1]) w = np.zeros(edge_list.shape[1]) position_ij = -1 qubit_position_i = np.asarray(np.where(edge_list == i)) for edge_index in range(edge_list.shape[1]): if set((i, j)) == set(edge_list[:, edge_index]): position_ij = edge_index break w[position_ij] = 1 for edge_index in range(qubit_position_i.shape[1]): ii, jj = qubit_position_i[:, edge_index] ii = 1 if ii == 0 else 0 # int(not(ii)) if edge_list[ii][jj] < j: v[jj] = 1 qubit_position_j = np.asarray(np.where(edge_list == j)) for edge_index in range(qubit_position_j.shape[1]): ii, jj = qubit_position_j[:, edge_index] ii = 1 if ii == 0 else 0 # int(not(ii)) if edge_list[ii][jj] < i: v[jj] = 1 qubit_op = Operator(paulis=[[1.0, Pauli(v, w)]]) return qubit_op
def edge_operator_bi(edge_list, i): """Calculate the edge operator B_i. The definitions used here are consistent with arXiv:quant-ph/0003137 Args: edge_list (numpy.ndarray): a 2xE matrix, where E is total number of edge and each pair denotes (from, to) i (int): index for specifying the edge operator B. Returns: Operator: qubit operator """ qubit_position_matrix = np.asarray(np.where(edge_list == i)) qubit_position = qubit_position_matrix[1] v = np.zeros(edge_list.shape[1]) w = np.zeros(edge_list.shape[1]) v[qubit_position] = 1 qubit_op = Operator(paulis=[[1.0, Pauli(v, w)]]) return qubit_op
def get_ising_opt_qubitops(model, variables): num_variables = len(list(model.linear)) var_to_int = dict(zip(list(model.linear), range(num_variables))) linear, quadratic, offset = model.to_ising() pauli_list = [] xs = np.zeros(num_variables, dtype=np.bool) for (i, j), weight in quadratic.items(): zs = np.zeros(num_variables, dtype=np.bool) zs[var_to_int[i]] = True zs[var_to_int[j]] = True pauli_list.append([weight, Pauli(zs, xs)]) for (i, weight) in linear.items(): zs = np.zeros(num_variables, dtype=np.bool) zs[var_to_int[i]] = True pauli_list.append([weight, Pauli(zs, xs)]) return Operator(paulis=pauli_list), offset
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, Pauli.from_label(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')