def test_subtraction_noninplace(self): """ test subtraction """ 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)) 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 - Operator(paulis=[pauli_term_c]) self.assertEqual(2, len(new_op.paulis)) self.assertEqual(0.25, new_op.paulis[0][0])
def _setup(self): self._operator.to_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'] 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._slice_pauli_list = slice_pauli_list
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) 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 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 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 _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 __init__(self, operator, state_in, iqft, num_time_slices=1, num_ancillae=1, paulis_grouping='random', expansion_mode='trotter', expansion_order=1, shallow_circuit_concat=False): """ Constructor. Args: operator (Operator): 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 paulis_grouping (str): the pauli term grouping mode 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._num_ancillae = num_ancillae self._ret = {} self._operator = copy.deepcopy(operator) self._operator.to_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'] self._phase_estimation_component = PhaseEstimation( self._operator, state_in, iqft, num_time_slices=num_time_slices, num_ancillae=num_ancillae, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order, shallow_circuit_concat=shallow_circuit_concat) self._binary_fractions = [1 / 2**p for p in range(1, num_ancillae + 1)]
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 = get_aer_backend('statevector_simulator') quantum_instance = QuantumInstance(backend, shots=1, pass_manager=PassManager()) # self.log.debug('state_out:\n\n') ret = eoh.run(quantum_instance) self.log.debug('Evaluation result: {}'.format(ret))
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 = {'shots': 1} backend = Aer.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 from_params(cls, params): if EnergyInput.PROP_KEY_QUBITOP not in params: raise AquaError("Qubit operator is required.") qparams = params[EnergyInput.PROP_KEY_QUBITOP] qubit_op = Operator.load_from_dict(qparams) if EnergyInput.PROP_KEY_AUXOPS in params: auxparams = params[EnergyInput.PROP_KEY_AUXOPS] aux_ops = [Operator.load_from_dict(auxparams[i]) for i in range(len(auxparams))] return cls(qubit_op, aux_ops)
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, Pauli.from_label('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, 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) a += Operator(paulis=[[1.0, Pauli.from_label('I' * num_qubits)]]) vac_operator = vac_operator * a vac_operator.scaling_coeff(np.sqrt(2)) return vac_operator
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 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 _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') # initialize state_in qc = self._state_in.construct_circuit('circuit', q) # Put all ancillae in uniform superposition qc.add(a) qc.u2(0, np.pi, a) # phase kickbacks via eoh 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_evolutions = Operator.construct_evolution_circuit( slice_pauli_list, -2 * np.pi, self._num_time_slices, q, a, ctl_idx=i, shallow_slicing=self._shallow_circuit_concat) if self._shallow_circuit_concat: qc.data += qc_evolutions.data else: qc += qc_evolutions # 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.add(c) qc.barrier(a) qc.measure(a, c) self._circuit = qc
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_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_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 test_str(self): """ test str """ 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("Representation: paulis, qubits: 4, size: 2", str(op_a))
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 _build_hopping_operator(self, index): 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 two_d_zeros = np.zeros((self._num_orbitals, self._num_orbitals)) four_d_zeros = np.zeros((self._num_orbitals, self._num_orbitals, self._num_orbitals, self._num_orbitals)) dummpy_fer_op = FermionicOperator(h1=two_d_zeros, h2=four_d_zeros) h1 = two_d_zeros.copy() h2 = four_d_zeros.copy() 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.h1 = h1 dummpy_fer_op.h2 = h2 qubit_op = dummpy_fer_op.mapping(self._qubit_mapping) qubit_op = qubit_op.two_qubit_reduced_operator( self._num_particles) if self._two_qubit_reduction else qubit_op if self._qubit_tapering: for symmetry in self._symmetries: symmetry_op = Operator(paulis=[[1.0, symmetry]]) symm_commuting = check_commutativity(symmetry_op, qubit_op) if not symm_commuting: break if self._qubit_tapering: if symm_commuting: qubit_op = Operator.qubit_tapering(qubit_op, self._cliffords, self._sq_list, self._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 _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 _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 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 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 _construct_kth_evolution(self, slice_pauli_list, k, omega): """Construct the kth iteration Quantum Phase Estimation circuit""" a = QuantumRegister(1, name='a') c = ClassicalRegister(1, name='c') q = QuantumRegister(self._operator.num_qubits, name='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( 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]) qc.add_register(c) qc.barrier(a) qc.measure(a, c) return qc
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, 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]) new_op = op_a * op_b # print(new_op.print_operators()) self.assertEqual(1, len(new_op.paulis)) self.assertEqual(-0.25, new_op.paulis[0][0]) self.assertEqual('ZZYY', new_op.paulis[0][1].to_label())
def get_portfolio_qubitops(mu, sigma, q, budget, penalty): # get problem dimension n = len(mu) e = np.ones(n) E = np.matmul(np.asmatrix(e).T, np.asmatrix(e)) # map problem to Ising model offset = - np.dot(mu, e)/2 + penalty*budget**2 - budget*n*penalty + n**2*penalty/4 + q/4*np.dot(e, np.dot(sigma, e)) mu_z = mu/2 + budget*penalty*e - n*penalty/2*e - q/2*np.dot(sigma, e) sigma_z = penalty/4*E + q/4*sigma # construct operator pauli_list = [] for i in range(n): i_ = i # i_ = n-i-1 if np.abs(mu_z[i_]) > 1e-6: xp = np.zeros(n, dtype=np.bool) zp = np.zeros(n, dtype=np.bool) zp[i_] = True pauli_list.append([mu_z[i_], Pauli(zp, xp)]) for j in range(i): j_ = j # j_ = n-j-1 if np.abs(sigma_z[i_, j_]) > 1e-6: xp = np.zeros(n, dtype=np.bool) zp = np.zeros(n, dtype=np.bool) zp[i_] = True zp[j_] = True pauli_list.append([2*sigma_z[i_, j_], Pauli(zp, xp)]) offset += sigma_z[i_, i_] return Operator(paulis=pauli_list), offset
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 = get_aer_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)