def iplot_blochsphere(rho, options=None): """ Create a bloch sphere representation. Graphical representation of the input array, using as much bloch spheres as qubit are required. Args: rho (array): Density matrix options (dict): Representation settings containing - width (integer): graph horizontal size - height (integer): graph vertical size """ # HTML html_template = Template(""" <p> <div id="content_$divNumber" style="position: absolute; z-index: 1;"> <div id="bloch_$divNumber"></div> </div> </p> """) # JavaScript javascript_template = Template(""" <script> requirejs.config({ paths: { qVisualization: "https://qvisualization.mybluemix.net/q-visualizations" } }); data = $data; dataValues = []; for (var i = 0; i < data.length; i++) { // Coordinates var x = data[i][0]; var y = data[i][1]; var z = data[i][2]; var point = {'x': x, 'y': y, 'z': z}; dataValues.push(point); } require(["qVisualization"], function(qVisualizations) { // Plot figure qVisualizations.plotState("bloch_$divNumber", "bloch", dataValues, $options); }); </script> """) if not options: options = {} # Process data and execute num = int(np.log2(len(rho))) bloch_data = [] for i in range(num): pauli_singles = [Pauli.pauli_single(num, i, 'X'), Pauli.pauli_single(num, i, 'Y'), Pauli.pauli_single(num, i, 'Z')] bloch_state = list(map(lambda x: np.real(np.trace(np.dot(x.to_matrix(), rho))), pauli_singles)) bloch_data.append(bloch_state) div_number = str(time.time()) div_number = re.sub('[.]', '', div_number) html = html_template.substitute({ 'divNumber': div_number }) javascript = javascript_template.substitute({ 'data': bloch_data, 'divNumber': div_number, 'options': options }) display(HTML(html + javascript))
def travelling_salesperson_pauli(G, lagrange=None, time_window=None, weight="weight"): num_nodes = G.number_of_nodes() num_qubits = num_nodes**2 zero = np.zeros(num_qubits, dtype=np.bool) pauli_list = [] shift = 0 if lagrange is None: if G.number_of_edges() > 0: lagrange = G.size( weight=weight) * G.number_of_nodes() / G.number_of_edges() else: lagrange = 100000 for i in range(num_nodes): for j in range(num_nodes): if i == j: continue for p in range(num_nodes): q = (p + 1) % num_nodes shift += G[i][j][weight] / 4 z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + p] = True pauli_list.append([-G[i][j][weight] / 4, Pauli(z_p, zero)]) z_p = np.zeros(num_qubits, dtype=np.bool) z_p[j * num_nodes + q] = True pauli_list.append([-G[i][j][weight] / 4, Pauli(z_p, zero)]) z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + p] = True z_p[j * num_nodes + q] = True pauli_list.append([G[i][j][weight] / 4, Pauli(z_p, zero)]) for i in range(num_nodes): for p in range(num_nodes): z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + p] = True pauli_list.append([lagrange, Pauli(z_p, zero)]) shift += -lagrange for p in range(num_nodes): for i in range(num_nodes): for j in range(i): shift += lagrange / 2 z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + p] = True pauli_list.append([-lagrange / 2, Pauli(z_p, zero)]) z_p = np.zeros(num_qubits, dtype=np.bool) z_p[j * num_nodes + p] = True pauli_list.append([-lagrange / 2, Pauli(z_p, zero)]) z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + p] = True z_p[j * num_nodes + p] = True pauli_list.append([lagrange / 2, Pauli(z_p, zero)]) for i in range(num_nodes): for p in range(num_nodes): for q in range(p): shift += lagrange / 2 z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + p] = True pauli_list.append([-lagrange / 2, Pauli(z_p, zero)]) z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + q] = True pauli_list.append([-lagrange / 2, Pauli(z_p, zero)]) z_p = np.zeros(num_qubits, dtype=np.bool) z_p[i * num_nodes + p] = True z_p[i * num_nodes + q] = True pauli_list.append([lagrange / 2, Pauli(z_p, zero)]) shift += 2 * lagrange * num_nodes return WeightedPauliOperator(paulis=pauli_list), shift
def _expand_dim(self, num_qubits: int) -> "PauliSumOp": return PauliSumOp( self.primitive.tensor( # type:ignore SparsePauliOp(Pauli(label="I" * num_qubits))), coeff=self.coeff, )
def get_operator(rho: np.ndarray, n: int, q: int) -> WeightedPauliOperator: """Converts an instance of portfolio optimization into a list of Paulis. Args: rho: an asset-to-asset similarity matrix, such as the covariance matrix. n: the number of assets. q: the number of clusters of assets to output. Returns: operator for the Hamiltonian """ # N = (n + 1) * n # number of qubits N = n**2 + n A = np.max(np.abs(rho)) * 1000 # A parameter of cost function # Determine the weights w instance_vec = rho.reshape(n**2) # quadratic term Q q0 = np.zeros([N, 1]) Q1 = np.zeros([N, N]) Q2 = np.zeros([N, N]) Q3 = np.zeros([N, N]) for x in range(n**2, n**2 + n): q0[x] = 1 Q0 = A * np.dot(q0, q0.T) for ii in range(0, n): v0 = np.zeros([N, 1]) for jj in range(n * ii, n * (ii + 1)): v0[jj] = 1 Q1 = Q1 + np.dot(v0, v0.T) Q1 = A * Q1 for jj in range(0, n): v0 = np.zeros([N, 1]) v0[n * jj + jj] = 1 v0[n**2 + jj] = -1 Q2 = Q2 + np.dot(v0, v0.T) Q2 = A * Q2 for ii in range(0, n): for jj in range(0, n): Q3[ii * n + jj, n**2 + jj] = -0.5 Q3[n**2 + jj, ii * n + jj] = -0.5 Q3 = A * Q3 Q = Q0 + Q1 + Q2 + Q3 # linear term c: c0 = np.zeros(N) c1 = np.zeros(N) c2 = np.zeros(N) c3 = np.zeros(N) for x in range(n**2): c0[x] = instance_vec[x] for x in range(n**2, n**2 + n): c1[x] = -2 * A * q for x in range(n**2): c2[x] = -2 * A for x in range(n**2): c3[x] = A g = c0 + c1 + c2 + c3 # constant term r c = A * (q**2 + n) # 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 WeightedPauliOperator(paulis=pauli_list)
def test_simple1(self): """ simple1 test """ # Compares the output in terms of Paulis. paulis = [(-249.5, Pauli(z=[True, False, False, False, False, False], x=[False, False, False, False, False, False])), (-249.60000000000002, Pauli(z=[False, True, False, False, False, False], x=[False, False, False, False, False, False])), (-249.60000000000002, Pauli(z=[False, False, True, False, False, False], x=[False, False, False, False, False, False])), (-249.5, Pauli(z=[False, False, False, True, False, False], x=[False, False, False, False, False, False])), (500.0, Pauli(z=[False, False, False, False, True, False], x=[False, False, False, False, False, False])), (500.0, Pauli(z=[False, False, False, False, False, True], x=[False, False, False, False, False, False])), (500.0, Pauli(z=[True, True, False, False, False, False], x=[False, False, False, False, False, False])), (500.0, Pauli(z=[False, False, True, True, False, False], x=[False, False, False, False, False, False])), (-750.0, Pauli(z=[True, False, False, False, True, False], x=[False, False, False, False, False, False])), (-250.0, Pauli(z=[False, False, True, False, True, False], x=[False, False, False, False, False, False])), (-250.0, Pauli(z=[False, True, False, False, False, True], x=[False, False, False, False, False, False])), (-750.0, Pauli(z=[False, False, False, True, False, True], x=[False, False, False, False, False, False])), (500.0, Pauli(z=[False, False, False, False, True, True], x=[False, False, False, False, False, False])), (3498.2, Pauli(z=[False, False, False, False, False, False], x=[False, False, False, False, False, False]))] for pauli_a, pauli_b in zip(self.qubit_op._paulis, paulis): cost_a, binary_a = pauli_a cost_b, binary_b = pauli_b # Note that the construction is a bit iffy, e.g., I can get: # Items are not equal to 7 significant digits: # ACTUAL: -250.5 # DESIRED: -249.5 # even when the ordering is the same. Obviously, when the ordering changes, # the test will become invalid. np.testing.assert_approx_equal(np.real(cost_a), cost_b, 2) self.assertEqual(binary_a, binary_b)
from math import fsum, isclose from test.optimization import QiskitOptimizationTestCase import networkx as nx import numpy as np from docplex.mp.model import Model from qiskit.quantum_info import Pauli from qiskit.aqua import AquaError, aqua_globals from qiskit.aqua.algorithms import NumPyMinimumEigensolver from qiskit.optimization.ising import docplex, tsp from qiskit.aqua.operators import WeightedPauliOperator # Reference operators and offsets for maxcut and tsp. QUBIT_OP_MAXCUT = WeightedPauliOperator( paulis=[[0.5, Pauli(z=[True, True, False, False], x=[False, False, False, False])], [0.5, Pauli(z=[True, False, True, False], x=[False, False, False, False])], [0.5, Pauli(z=[False, True, True, False], x=[False, False, False, False])], [0.5, Pauli(z=[True, False, False, True], x=[False, False, False, False])], [0.5, Pauli(z=[False, False, True, True], x=[False, False, False, False])]]) OFFSET_MAXCUT = -2.5 QUBIT_OP_TSP = WeightedPauliOperator( paulis=[[-100057.0, Pauli(z=[True, False, False, False, False, False, False, False, False], x=[False, False, False, False, False, False, False, False, False])], [-100071.0, Pauli(z=[False, False, False, False, True, False, False, False, False], x=[False, False, False, False, False, False, False, False, False])], [14.5, Pauli(z=[True, False, False, False, True, False, False, False, False], x=[False, False, False, False, False, False, False, False, False])], [-100057.0, Pauli(z=[False, True, False, False, False, False, False, False, False], x=[False, False, False, False, False, False, False, False, False])], [-100071.0, Pauli(z=[False, False, False, False, False, True, False, False, False],
def destabilizer(self, row): """Return the destabilizer as a Pauli object""" nq = self._num_qubits z = self._table[row, 0:nq] x = self._table[row, nq:2 * nq] return Pauli(z=z, x=x)
def _conversion(basis, matrix): pauli = Pauli.from_label(''.join(basis)) trace_value = np.sum(matrix.dot(pauli.to_spmatrix()).diagonal()) return trace_value, pauli
def test_ndarray_bool(self): """Test creation from np.bool.""" x = np.asarray([1, 0]).astype(np.bool) z = np.asarray([1, 0]).astype(np.bool) pauli = Pauli(x=x, z=z) self.check(pauli)
def get_operator(weight_matrix, K): # pylint: disable=invalid-name r""" Generate Hamiltonian for the clique Args: weight_matrix (numpy.ndarray) : adjacency matrix. K (numpy.ndarray): K Returns: tuple(WeightedPauliOperator, float): operator for the Hamiltonian and a constant shift for the obj function. Goals: can we find a complete graph of size K? Hamiltonian: suppose Xv denotes whether v should appear in the clique (Xv=1 or 0) H = Ha + Hb Ha = (K-sum_{v}{Xv})^2 Hb = K(K−1)/2 - sum_{(u,v)\in E}{XuXv} Besides, Xv = (Zv+1)/2 By replacing Xv with Zv and simplifying it, we get what we want below. Note: in practice, we use H = A*Ha + Bb, where A is a large constant such as 1000. A is like a huge penality over the violation of Ha, which forces Ha to be 0, i.e., you have exact K vertices selected. Under this assumption, Hb = 0 starts to make sense, it means the subgraph constitutes a clique or complete graph. Note the lowest possible value of Hb is 0. Without the above assumption, Hb may be negative (say you select all). In this case, one needs to use Hb^2 in the hamiltonian to minimize the difference. """ # pylint: disable=invalid-name num_nodes = len(weight_matrix) pauli_list = [] shift = 0 Y = K - 0.5*num_nodes # Y = K-sum_{v}{1/2} A = 1000 # Ha part: shift += A*Y*Y 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([A*0.25, Pauli(zp, xp)]) else: shift += A*0.25 for i in range(num_nodes): xp = np.zeros(num_nodes, dtype=np.bool) zp = np.zeros(num_nodes, dtype=np.bool) zp[i] = True pauli_list.append([-A*Y, Pauli(zp, xp)]) shift += 0.5*K*(K-1) 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.25, Pauli(zp, xp)]) zp2 = np.zeros(num_nodes, dtype=np.bool) zp2[i] = True pauli_list.append([-0.25, Pauli(zp2, xp)]) zp3 = np.zeros(num_nodes, dtype=np.bool) zp3[j] = True pauli_list.append([-0.25, Pauli(zp3, xp)]) shift += -0.25 return WeightedPauliOperator(paulis=pauli_list), shift
# Immutable convenience objects def make_immutable(obj): """ Delete the __setattr__ property to make the object mostly immutable. """ # TODO figure out how to get correct error message # def throw_immutability_exception(self, *args): # raise OpflowError('Operator convenience globals are immutable.') obj.__setattr__ = None return obj # 1-Qubit Paulis X = make_immutable(PauliOp(Pauli('X'))) Y = make_immutable(PauliOp(Pauli('Y'))) Z = make_immutable(PauliOp(Pauli('Z'))) I = make_immutable(PauliOp(Pauli('I'))) # Clifford+T, and some other common non-parameterized gates CX = make_immutable(CircuitOp(CXGate())) S = make_immutable(CircuitOp(SGate())) H = make_immutable(CircuitOp(HGate())) T = make_immutable(CircuitOp(TGate())) Swap = make_immutable(CircuitOp(SwapGate())) CZ = make_immutable(CircuitOp(CZGate())) # 1-Qubit Paulis Zero = make_immutable(DictStateFn('0')) One = make_immutable(DictStateFn('1'))
def product_pauli_z(q1, q2, coeff, n): eye = np.eye((n)) return Operator( [[coeff, Pauli(eye[q1], np.zeros(n)) * Pauli(eye[q2], np.zeros(n))]])
def pauli_z(q, coeff, n): eye = np.eye((n)) return Operator([[coeff, Pauli(eye[q], np.zeros(n))]])
def pauli_x(q, coeff, n): eye = np.eye((n)) # the i^th row of the identity matrix is # the correct parameter for \sigma_i return Operator([[coeff, Pauli(np.zeros(n), eye[q])]])
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", "bksf" 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: QiskitChemistryError: if the `map_type` can not be recognized. """ """ #################################################################### ############ DEFINING MAPPED FERMIONIC OPERATORS ############## #################################################################### """ self._map_type = map_type n = self._modes # 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) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError( 'Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') """ #################################################################### ############ 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 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 futures: result = future.result() 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 += Operator(paulis=[pauli_term]) return pauli_list
def test_sgn_prod(self): """Test sgn prod.""" p1 = Pauli(np.array([False]), np.array([True])) p2 = Pauli(np.array([True]), np.array([True])) self.log.info("sign product:") p3, sgn = Pauli.sgn_prod(p1, p2) self.log.info("p1: %s", p1.to_label()) self.log.info("p2: %s", p2.to_label()) self.log.info("p3: %s", p3.to_label()) self.log.info("sgn_prod(p1, p2): %s", str(sgn)) self.assertEqual(p1.to_label(), 'X') self.assertEqual(p2.to_label(), 'Y') self.assertEqual(p3.to_label(), 'Z') self.assertEqual(sgn, 1j) self.log.info("sign product reverse:") p3, sgn = Pauli.sgn_prod(p2, p1) # pylint: disable=arguments-out-of-order self.log.info("p2: %s", p2.to_label()) self.log.info("p1: %s", p1.to_label()) self.log.info("p3: %s", p3.to_label()) self.log.info("sgn_prod(p2, p1): %s", str(sgn)) self.assertEqual(p1.to_label(), 'X') self.assertEqual(p2.to_label(), 'Y') self.assertEqual(p3.to_label(), 'Z') self.assertEqual(sgn, -1j)
InequalityToEquality, QuadraticProgramToIsing, IsingToQuadraticProgram, IntegerToBinary, LinearEqualityToPenalty, ) from qiskit.optimization.algorithms import MinimumEigenOptimizer, CplexOptimizer, ADMMOptimizer from qiskit.optimization.algorithms.admm_optimizer import ADMMParameters from qiskit.quantum_info import Pauli logger = logging.getLogger(__name__) QUBIT_OP_MAXIMIZE_SAMPLE = WeightedPauliOperator( paulis=[ [(-199999.5 + 0j), Pauli(z=[True, False, False, False], x=[False, False, False, False])], [(-399999.5 + 0j), Pauli(z=[False, True, False, False], x=[False, False, False, False])], [(-599999.5 + 0j), Pauli(z=[False, False, True, False], x=[False, False, False, False])], [(-799999.5 + 0j), Pauli(z=[False, False, False, True], x=[False, False, False, False])], [(100000 + 0j), Pauli(z=[True, True, False, False], x=[False, False, False, False])], [(150000 + 0j), Pauli(z=[True, False, True, False], x=[False, False, False, False])], [(300000 + 0j), Pauli(z=[False, True, True, False], x=[False, False, False, False])], [(200000 + 0j), Pauli(z=[True, False, False, True], x=[False, False, False, False])], [(400000 + 0j), Pauli(z=[False, True, False, True], x=[False, False, False, False])], [(600000 + 0j), Pauli(z=[False, False, True, True], x=[False, False, False, False])], ] ) OFFSET_MAXIMIZE_SAMPLE = 1149998 class TestConverters(QiskitOptimizationTestCase):
def test_ndarray_int(self): """Test creation from np.int.""" x = np.asarray([2, 0]).astype(np.int) z = np.asarray([2, 0]).astype(np.int) pauli = Pauli(x=x, z=z) self.check(pauli)
def stabilizer(self, qubit): """Return the qubit stabilizer as a Pauli object""" nq = self._num_qubits z = self._table[nq + qubit, 0:nq] x = self._table[nq + qubit, nq:2 * nq] return Pauli(z=z, x=x)
def test_list(self): """Test creation from lists.""" pauli = Pauli(x=[1, 0], z=[1, 0]) self.check(pauli)
def mapping(self, map_type, threshold=0.00000001): """Map fermionic operator to qubit operator. 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", "bksf" threshold (float): threshold for Pauli simplification Returns: Operator: create an Operator object in Paulis form. Raises: QiskitChemistryError: if the `map_type` can not be recognized. """ """ #################################################################### ############ DEFINING MAPPED FERMIONIC OPERATORS ############## #################################################################### """ self._map_type = map_type n = self._modes # 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) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError( 'Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') """ #################################################################### ############ BUILDING THE MAPPED HAMILTONIAN ################ #################################################################### """ pauli_list = Operator(paulis=[]) if logger.isEnabledFor(logging.DEBUG): logger.debug("Mapping one-body terms to Qubit Hamiltonian:") TextProgressBar(output_handler=sys.stderr) results = parallel_map( FermionicOperator._one_body_mapping, [(self._h1[i, j], a[i], a[j]) for i, j in itertools.product(range(n), repeat=2) if self._h1[i, j] != 0], task_args=(threshold, ), num_processes=aqua_globals.num_processes) for result in results: pauli_list += result pauli_list.chop(threshold=threshold) if logger.isEnabledFor(logging.DEBUG): logger.debug("Mapping two-body terms to Qubit Hamiltonian:") TextProgressBar(output_handler=sys.stderr) results = parallel_map( FermionicOperator._two_body_mapping, [(self._h2[i, j, k, m], a[i], a[j], a[k], a[m]) for i, j, k, m in itertools.product(range(n), repeat=4) if self._h2[i, j, k, m] != 0], task_args=(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 += Operator(paulis=[pauli_term]) return pauli_list
def test_tuple(self): """Test creation from tuples.""" pauli = Pauli(x=(1, 0), z=(1, 0)) self.check(pauli)
def test_consistency_with_pauli(self, label): """Test consistency with pauli""" actual = SpinOp(label).to_matrix() desired = Pauli(label).to_matrix() / (2**(len(label) - label.count("I"))) np.testing.assert_array_almost_equal(actual, desired)
def test_mix(self): """Test creation from tuples and list.""" pauli = Pauli(x=(1, 0), z=[1, 0]) self.check(pauli)
def _bravyi_kitaev_mode(self, n): """ Bravyi-Kitaev mode. Args: n (int): number of modes Returns: numpy.ndarray: Array of mode indexes """ def parity_set(j, n): """Computes the parity set of the j-th orbital in n modes. Args: j (int) : the orbital index n (int) : the total number of modes Returns: numpy.ndarray: Array of mode indexes """ indexes = np.array([]) if n % 2 != 0: return indexes if j < n / 2: indexes = np.append(indexes, parity_set(j, n / 2)) else: indexes = np.append( indexes, np.append(parity_set(j - n / 2, n / 2) + n / 2, n / 2 - 1)) return indexes def update_set(j, n): """Computes the update set of the j-th orbital in n modes. Args: j (int) : the orbital index n (int) : the total number of modes Returns: numpy.ndarray: Array of mode indexes """ indexes = np.array([]) if n % 2 != 0: return indexes if j < n / 2: indexes = np.append(indexes, np.append(n - 1, update_set(j, n / 2))) else: indexes = np.append(indexes, update_set(j - n / 2, n / 2) + n / 2) return indexes def flip_set(j, n): """Computes the flip set of the j-th orbital in n modes. Args: j (int) : the orbital index n (int) : the total number of modes Returns: numpy.ndarray: Array of mode indexes """ indexes = np.array([]) if n % 2 != 0: return indexes if j < n / 2: indexes = np.append(indexes, flip_set(j, n / 2)) elif j >= n / 2 and j < n - 1: # pylint: disable=chained-comparison indexes = np.append(indexes, flip_set(j - n / 2, n / 2) + n / 2) else: indexes = np.append( np.append(indexes, flip_set(j - n / 2, n / 2) + n / 2), n / 2 - 1) return indexes a_list = [] # FIND BINARY SUPERSET SIZE bin_sup = 1 # pylint: disable=comparison-with-callable while n > np.power(2, bin_sup): bin_sup += 1 # DEFINE INDEX SETS FOR EVERY FERMIONIC MODE update_sets = [] update_pauli = [] parity_sets = [] parity_pauli = [] flip_sets = [] remainder_sets = [] remainder_pauli = [] for j in range(n): update_sets.append(update_set(j, np.power(2, bin_sup))) update_sets[j] = update_sets[j][update_sets[j] < n] parity_sets.append(parity_set(j, np.power(2, bin_sup))) parity_sets[j] = parity_sets[j][parity_sets[j] < n] flip_sets.append(flip_set(j, np.power(2, bin_sup))) flip_sets[j] = flip_sets[j][flip_sets[j] < n] remainder_sets.append(np.setdiff1d(parity_sets[j], flip_sets[j])) update_pauli.append( Pauli(np.zeros(n, dtype=np.bool), np.zeros(n, dtype=np.bool))) parity_pauli.append( Pauli(np.zeros(n, dtype=np.bool), np.zeros(n, dtype=np.bool))) remainder_pauli.append( Pauli(np.zeros(n, dtype=np.bool), np.zeros(n, dtype=np.bool))) for k in range(n): if np.in1d(k, update_sets[j]): update_pauli[j].update_x(True, k) if np.in1d(k, parity_sets[j]): parity_pauli[j].update_z(True, k) if np.in1d(k, remainder_sets[j]): remainder_pauli[j].update_z(True, k) x_j = Pauli(np.zeros(n, dtype=np.bool), np.zeros(n, dtype=np.bool)) x_j.update_x(True, j) y_j = Pauli(np.zeros(n, dtype=np.bool), np.zeros(n, dtype=np.bool)) y_j.update_z(True, j) y_j.update_x(True, j) a_list.append((update_pauli[j] * x_j * parity_pauli[j], update_pauli[j] * y_j * remainder_pauli[j])) return a_list
class TestPauli(QiskitTestCase): """Tests for Pauli class.""" def setUp(self): """Setup.""" z = np.asarray([1, 0, 1, 0]).astype(np.bool) x = np.asarray([1, 1, 0, 0]).astype(np.bool) self.ref_p = Pauli(z, x) self.ref_label = 'IZXY' self.ref_matrix = np.array( [[ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ]]) def test_create_from_label(self): """Test creation from pauli label.""" label = 'IZXY' pauli = Pauli(label=label) self.assertEqual(pauli, self.ref_p) self.assertEqual(pauli.to_label(), self.ref_label) self.assertEqual(len(pauli), 4) def test_create_from_z_x(self): """Test creation for boolean vector.""" self.assertEqual(self.ref_p.to_label(), 'IZXY') self.assertEqual(len(self.ref_p), 4) def test_repr(self): """Test __repr__.""" p = repr(self.ref_p) self.assertEqual( p, "Pauli(z=[True, False, True, False], x=[True, True, False, False])" ) def test_random_pauli(self): """Test random pauli creation.""" length = 4 q = Pauli.random(length, seed=42) self.log.info(q) self.assertEqual(q.numberofqubits, length) self.assertEqual(len(q.z), length) self.assertEqual(len(q.x), length) self.assertEqual(len(q.to_label()), length) self.assertEqual(len(q.to_matrix()), 2**length) def test_mul(self): """Test multiplication.""" p1 = self.ref_p p2 = Pauli.from_label('ZXXI') p3 = p1 * p2 self.assertEqual(len(p3), 4) self.assertEqual(p3.to_label(), 'ZYIY') def test_imul(self): """Test in-place multiplication.""" p1 = self.ref_p p2 = Pauli.from_label('ZXXI') p3 = deepcopy(p2) p2 *= p1 self.assertTrue(p2 != p3) self.assertEqual(p2.to_label(), 'ZYIY') def test_equality_equal(self): """Test equality operator: equal Paulis.""" p1 = self.ref_p p2 = deepcopy(p1) self.assertTrue(p1 == p2) self.assertEqual(p1.to_label(), self.ref_label) self.assertEqual(p2.to_label(), self.ref_label) def test_equality_different(self): """Test equality operator: different Paulis.""" p1 = self.ref_p p2 = deepcopy(p1) p2.update_z(True, 1) self.assertFalse(p1 == p2) self.assertEqual(p1.to_label(), self.ref_label) self.assertEqual(p2.to_label(), 'IZYY') def test_inequality_equal(self): """Test inequality operator: equal Paulis.""" p1 = self.ref_p p2 = deepcopy(p1) self.assertFalse(p1 != p2) def test_inequality_different(self): """Test inequality operator: different Paulis.""" p1 = self.ref_p p2 = deepcopy(p1) p2.update_x(False, 1) self.assertTrue(p1 != p2) self.assertEqual(p2.to_label(), 'IZIY') def test_update_z(self): """Test update_z method.""" updated_z = np.asarray([0, 0, 0, 0]).astype(np.bool) self.ref_p.update_z(updated_z) np.testing.assert_equal(self.ref_p.z, np.asarray([False, False, False, False])) self.assertEqual(self.ref_p.to_label(), 'IIXX') def test_update_z_2(self): """Test update_z method, update partial z.""" updated_z = np.asarray([0, 1]).astype(np.bool) self.ref_p.update_z(updated_z, [0, 1]) np.testing.assert_equal(self.ref_p.z, np.asarray([False, True, True, False])) self.assertEqual(self.ref_p.to_label(), 'IZYX') def test_update_x(self): """Test update_x method.""" updated_x = np.asarray([0, 1, 0, 1]).astype(np.bool) self.ref_p.update_x(updated_x) np.testing.assert_equal(self.ref_p.x, np.asarray([False, True, False, True])) self.assertEqual(self.ref_p.to_label(), 'XZXZ') def test_update_x_2(self): """Test update_x method, update partial x.""" updated_x = np.asarray([0, 1]).astype(np.bool) self.ref_p.update_x(updated_x, [1, 2]) np.testing.assert_equal(self.ref_p.x, np.asarray([True, False, True, False])) self.assertEqual(self.ref_p.to_label(), 'IYIY') def test_to_matrix(self): """Test pauli to matrix.""" np.testing.assert_allclose(self.ref_p.to_matrix(), self.ref_matrix) def test_delete_qubit(self): """Test deleting single qubit.""" p1 = self.ref_p p2 = deepcopy(p1) p2.delete_qubits(0) self.assertTrue(p1 != p2) self.assertEqual(len(p2), 3) self.assertEqual(p2.to_label(), 'IZX') def test_delete_qubits(self): """Test deleting multiple qubits.""" p1 = self.ref_p p2 = deepcopy(p1) p2.delete_qubits([0, 2]) self.assertTrue(p1 != p2) self.assertEqual(len(p2), 2) self.assertEqual(p2.to_label(), 'IX') def test_append_pauli_labels(self): """Test appending paulis via labels.""" p1 = self.ref_p p2 = deepcopy(p1) p2.append_paulis(pauli_labels=['Z', 'Y', 'I']) self.assertTrue(p1 != p2) self.assertEqual(len(p2), 7) self.assertEqual(p2.to_label(), 'IYZ' + self.ref_label) def test_append_paulis(self): """Test appending paulis via pauli object.""" p1 = self.ref_p p2 = deepcopy(p1) p2.append_paulis(paulis=p1) self.assertTrue(p1 != p2) self.assertEqual(len(p2), 8) self.assertEqual(p2.to_label(), self.ref_label + self.ref_label) def test_insert_pauli_labels_1(self): """Test inserting paulis via labels.""" p2 = deepcopy(self.ref_p) p2.insert_paulis(indices=[1, 2], pauli_labels=['Y', 'I']) self.assertTrue(self.ref_p != p2) self.assertEqual(len(p2), 6) self.assertEqual(p2.to_label(), 'IZIXYY') def test_insert_pauli_labels_2(self): """Test inserting paulis via labels.""" p2 = deepcopy(self.ref_p) p2.insert_paulis(indices=[3, 2], pauli_labels=['Y', 'I']) self.assertTrue(self.ref_p != p2) self.assertEqual(len(p2), 6) self.assertEqual(p2.to_label(), 'IYZIXY') def test_insert_paulis(self): """Test inserting paulis via pauli object.""" p1 = deepcopy(self.ref_p) new_p = Pauli.from_label('XY') p1.insert_paulis(indices=[0], paulis=new_p) self.assertTrue(p1 != self.ref_p) self.assertEqual(len(p1), 6) self.assertEqual(p1.to_label(), self.ref_label + 'XY') def test_kron(self): """Test kron production.""" p1 = deepcopy(self.ref_p) p2 = self.ref_p p2.kron(p1) self.assertTrue(p1 != p2) self.assertEqual(len(p2), 8) self.assertEqual(p2.to_label(), self.ref_label + self.ref_label) def test_pauli_single(self): """Test pauli single.""" num_qubits = 5 pz = Pauli.pauli_single(num_qubits, 2, 'Z') self.assertTrue(pz.to_label(), 'IIIZI') py = Pauli.pauli_single(num_qubits, 4, 'Y') self.assertTrue(py.to_label(), 'IYIII') px = Pauli.pauli_single(num_qubits, 3, 'X') self.assertTrue(px.to_label(), 'IIXII') def test_pauli_group(self): """Test pauli group.""" self.log.info("Group in tensor order:") expected = [ 'III', 'XII', 'YII', 'ZII', 'IXI', 'XXI', 'YXI', 'ZXI', 'IYI', 'XYI', 'YYI', 'ZYI', 'IZI', 'XZI', 'YZI', 'ZZI', 'IIX', 'XIX', 'YIX', 'ZIX', 'IXX', 'XXX', 'YXX', 'ZXX', 'IYX', 'XYX', 'YYX', 'ZYX', 'IZX', 'XZX', 'YZX', 'ZZX', 'IIY', 'XIY', 'YIY', 'ZIY', 'IXY', 'XXY', 'YXY', 'ZXY', 'IYY', 'XYY', 'YYY', 'ZYY', 'IZY', 'XZY', 'YZY', 'ZZY', 'IIZ', 'XIZ', 'YIZ', 'ZIZ', 'IXZ', 'XXZ', 'YXZ', 'ZXZ', 'IYZ', 'XYZ', 'YYZ', 'ZYZ', 'IZZ', 'XZZ', 'YZZ', 'ZZZ' ] grp = pauli_group(3, case='tensor') for j in grp: self.log.info('==== j (tensor order) ====') self.log.info(j.to_label()) self.assertEqual(expected.pop(0)[::-1], j.to_label()) self.log.info("Group in weight order:") expected = [ 'III', 'XII', 'YII', 'ZII', 'IXI', 'IYI', 'IZI', 'IIX', 'IIY', 'IIZ', 'XXI', 'YXI', 'ZXI', 'XYI', 'YYI', 'ZYI', 'XZI', 'YZI', 'ZZI', 'XIX', 'YIX', 'ZIX', 'IXX', 'IYX', 'IZX', 'XIY', 'YIY', 'ZIY', 'IXY', 'IYY', 'IZY', 'XIZ', 'YIZ', 'ZIZ', 'IXZ', 'IYZ', 'IZZ', 'XXX', 'YXX', 'ZXX', 'XYX', 'YYX', 'ZYX', 'XZX', 'YZX', 'ZZX', 'XXY', 'YXY', 'ZXY', 'XYY', 'YYY', 'ZYY', 'XZY', 'YZY', 'ZZY', 'XXZ', 'YXZ', 'ZXZ', 'XYZ', 'YYZ', 'ZYZ', 'XZZ', 'YZZ', 'ZZZ' ] grp = pauli_group(3, case='weight') for j in grp: self.log.info('==== j (weight order) ====') self.log.info(j.to_label()) self.assertEqual(expected.pop(0)[::-1], j.to_label()) def test_sgn_prod(self): """Test sgn prod.""" p1 = Pauli(np.array([False]), np.array([True])) p2 = Pauli(np.array([True]), np.array([True])) self.log.info("sign product:") p3, sgn = Pauli.sgn_prod(p1, p2) self.log.info("p1: %s", p1.to_label()) self.log.info("p2: %s", p2.to_label()) self.log.info("p3: %s", p3.to_label()) self.log.info("sgn_prod(p1, p2): %s", str(sgn)) self.assertEqual(p1.to_label(), 'X') self.assertEqual(p2.to_label(), 'Y') self.assertEqual(p3.to_label(), 'Z') self.assertEqual(sgn, 1j) self.log.info("sign product reverse:") p3, sgn = Pauli.sgn_prod(p2, p1) # pylint: disable=arguments-out-of-order self.log.info("p2: %s", p2.to_label()) self.log.info("p1: %s", p1.to_label()) self.log.info("p3: %s", p3.to_label()) self.log.info("sgn_prod(p2, p1): %s", str(sgn)) self.assertEqual(p1.to_label(), 'X') self.assertEqual(p2.to_label(), 'Y') self.assertEqual(p3.to_label(), 'Z') self.assertEqual(sgn, -1j)
def _expand_dim(self, num_qubits: int) -> 'PauliOp': return PauliOp(Pauli('I'*num_qubits).expand(self.primitive), coeff=self.coeff)
def setUp(self): """Setup.""" z = np.asarray([1, 0, 1, 0]).astype(np.bool) x = np.asarray([1, 1, 0, 0]).astype(np.bool) self.ref_p = Pauli(z, x) self.ref_label = 'IZXY' self.ref_matrix = np.array( [[ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 1.j, 0. + 0.j, 0. + 0.j ], [ 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 1.j, 0. + 0.j, 0. + 0.j, 0. + 0.j ]])
def get_operator( mdl: Model, auto_penalty: bool = True, default_penalty: float = 1e5) -> Tuple[WeightedPauliOperator, float]: """Generate Ising Hamiltonian from a model of DOcplex. Args: mdl: A model of DOcplex for a optimization problem. auto_penalty: If true, the penalty coefficient is automatically defined by "_auto_define_penalty()". default_penalty: The default value of the penalty coefficient for the constraints. This value is used if "auto_penalty" is False. Returns: Operator for the Hamiltonian and a constant shift for the obj function. """ _validate_input_model(mdl) # set the penalty coefficient by _auto_define_penalty() or manually. if auto_penalty: penalty = _auto_define_penalty(mdl, default_penalty) else: penalty = default_penalty # set a sign corresponding to a maximized or minimized problem. # sign == 1 is for minimized problem. sign == -1 is for maximized problem. sign = 1 if mdl.is_maximized(): sign = -1 # assign variables of the model to qubits. q_d = {} index = 0 for i in mdl.iter_variables(): if i in q_d: continue q_d[i] = index index += 1 # initialize Hamiltonian. num_nodes = len(q_d) pauli_list = [] shift = 0 zero = np.zeros(num_nodes, dtype=np.bool) # convert a constant part of the object function into Hamiltonian. shift += mdl.get_objective_expr().get_constant() * sign # convert linear parts of the object function into Hamiltonian. l_itr = mdl.get_objective_expr().iter_terms() for j in l_itr: z_p = np.zeros(num_nodes, dtype=np.bool) index = q_d[j[0]] weight = j[1] * sign / 2 z_p[index] = True pauli_list.append([-weight, Pauli(z_p, zero)]) shift += weight # convert quadratic parts of the object function into Hamiltonian. q_itr = mdl.get_objective_expr().iter_quads() for i in q_itr: index1 = q_d[i[0][0]] index2 = q_d[i[0][1]] weight = i[1] * sign / 4 if index1 == index2: shift += weight else: z_p = np.zeros(num_nodes, dtype=np.bool) z_p[index1] = True z_p[index2] = True pauli_list.append([weight, Pauli(z_p, zero)]) z_p = np.zeros(num_nodes, dtype=np.bool) z_p[index1] = True pauli_list.append([-weight, Pauli(z_p, zero)]) z_p = np.zeros(num_nodes, dtype=np.bool) z_p[index2] = True pauli_list.append([-weight, Pauli(z_p, zero)]) shift += weight # convert constraints into penalty terms. for constraint in mdl.iter_constraints(): constant = constraint.cplex_num_rhs() # constant parts of penalty*(Constant-func)**2: penalty*(Constant**2) shift += penalty * constant**2 # linear parts of penalty*(Constant-func)**2: penalty*(-2*Constant*func) for __l in constraint.iter_net_linear_coefs(): z_p = np.zeros(num_nodes, dtype=np.bool) index = q_d[__l[0]] weight = __l[1] z_p[index] = True pauli_list.append([penalty * constant * weight, Pauli(z_p, zero)]) shift += -penalty * constant * weight # quadratic parts of penalty*(Constant-func)**2: penalty*(func**2) for __l in constraint.iter_net_linear_coefs(): for l_2 in constraint.iter_net_linear_coefs(): index1 = q_d[__l[0]] index2 = q_d[l_2[0]] weight1 = __l[1] weight2 = l_2[1] penalty_weight1_weight2 = penalty * weight1 * weight2 / 4 if index1 == index2: shift += penalty_weight1_weight2 else: z_p = np.zeros(num_nodes, dtype=np.bool) z_p[index1] = True z_p[index2] = True pauli_list.append( [penalty_weight1_weight2, Pauli(z_p, zero)]) z_p = np.zeros(num_nodes, dtype=np.bool) z_p[index1] = True pauli_list.append([-penalty_weight1_weight2, Pauli(z_p, zero)]) z_p = np.zeros(num_nodes, dtype=np.bool) z_p[index2] = True pauli_list.append([-penalty_weight1_weight2, Pauli(z_p, zero)]) shift += penalty_weight1_weight2 # Remove paulis whose coefficients are zeros. qubit_op = WeightedPauliOperator(paulis=pauli_list) return qubit_op, shift
from test.aqua.common import QiskitAquaTestCase import networkx as nx import numpy as np from docplex.mp.model import Model from qiskit.quantum_info import Pauli from qiskit.aqua import AquaError, aqua_globals from qiskit.aqua.algorithms import ExactEigensolver from qiskit.optimization.ising import docplex, tsp from qiskit.aqua.operators import WeightedPauliOperator # Reference operators and offsets for maxcut and tsp. QUBIT_OP_MAXCUT = WeightedPauliOperator(paulis=[ [0.5, Pauli(z=[True, True, False, False], x=[False, False, False, False])], [0.5, Pauli(z=[True, False, True, False], x=[False, False, False, False])], [0.5, Pauli(z=[False, True, True, False], x=[False, False, False, False])], [0.5, Pauli(z=[True, False, False, True], x=[False, False, False, False])], [0.5, Pauli(z=[False, False, True, True], x=[False, False, False, False])] ]) OFFSET_MAXCUT = -2.5 QUBIT_OP_TSP = WeightedPauliOperator(paulis=[ [ -100057.0, Pauli( z=[True, False, False, False, False, False, False, False, False],