diff --git a/qiskit/aqua/operators/list_ops/summed_op.py b/qiskit/aqua/operators/list_ops/summed_op.py index d516a82368..d8bacf07ef 100644 --- a/qiskit/aqua/operators/list_ops/summed_op.py +++ b/qiskit/aqua/operators/list_ops/summed_op.py @@ -14,7 +14,6 @@ """ SummedOp Class """ -from functools import reduce from typing import List, Union, cast import numpy as np @@ -72,9 +71,6 @@ def add(self, other: OperatorBase) -> OperatorBase: Returns: A ``SummedOp`` equivalent to the sum of self and other. """ - if self == other: - return self.mul(2.0) - self_new_ops = self.oplist if self.coeff == 1 \ else [op.mul(self.coeff) for op in self.oplist] if isinstance(other, SummedOp): @@ -84,10 +80,10 @@ def add(self, other: OperatorBase) -> OperatorBase: other_new_ops = [other] return SummedOp(self_new_ops + other_new_ops) - def simplify(self) -> 'SummedOp': + def collapse_summands(self) -> 'SummedOp': """Return Operator by simplifying duplicate operators. - E.g., ``SummedOp([2 * X ^ Y, X ^ Y]).simplify() -> SummedOp([3 * X ^ Y])``. + E.g., ``SummedOp([2 * X ^ Y, X ^ Y]).collapse_summands() -> SummedOp([3 * X ^ Y])``. Returns: A simplified ``SummedOp`` equivalent to self. @@ -113,11 +109,23 @@ def simplify(self) -> 'SummedOp': coeffs.append(self.coeff) return SummedOp([op * coeff for op, coeff in zip(oplist, coeffs)]) # type: ignore - # Try collapsing list or trees of Sums. # TODO be smarter about the fact that any two ops in oplist could be evaluated for sum. def reduce(self) -> OperatorBase: - reduced_ops = [op.reduce() for op in self.oplist] - reduced_ops = reduce(lambda x, y: x.add(y), reduced_ops) * self.coeff + """Try collapsing list or trees of sums. + + Tries to sum up duplicate operators and reduces the operators + in the sum. + + Returns: + A collapsed version of self, if possible. + """ + # reduce constituents + reduced_ops = sum(op.reduce() for op in self.oplist) * self.coeff + + # group duplicate operators + if isinstance(reduced_ops, SummedOp): + reduced_ops = reduced_ops.collapse_summands() + if isinstance(reduced_ops, SummedOp) and len(reduced_ops.oplist) == 1: return reduced_ops.oplist[0] else: @@ -142,3 +150,49 @@ def to_legacy_op(self, massive: bool = False) -> LegacyBaseOperator: coeff = cast(float, self.coeff) return self.combo_fn(legacy_ops) * coeff + + def equals(self, other: OperatorBase) -> bool: + """Check if other is equal to self. + + Note: + This is not a mathematical check for equality. + If ``self`` and ``other`` implement the same operation but differ + in the representation (e.g. different type of summands) + ``equals`` will evaluate to ``False``. + + Args: + other: The other operator to check for equality. + + Returns: + True, if other and self are equal, otherwise False. + + Examples: + >>> from qiskit.aqua.operators import X, Z + >>> 2 * X == X + X + True + >>> X + Z == Z + X + True + """ + self_reduced, other_reduced = self.reduce(), other.reduce() + if not isinstance(other_reduced, type(self_reduced)): + return False + + # check if reduced op is still a SummedOp + if not isinstance(self_reduced, SummedOp): + return self_reduced == other_reduced + + self_reduced = cast(SummedOp, self_reduced) + other_reduced = cast(SummedOp, other_reduced) + if len(self_reduced.oplist) != len(other_reduced.oplist): + return False + + # absorb coeffs into the operators + if self_reduced.coeff != 1: + self_reduced = SummedOp( + [op * self_reduced.coeff for op in self_reduced.oplist]) # type: ignore + if other_reduced.coeff != 1: + other_reduced = SummedOp( + [op * other_reduced.coeff for op in other_reduced.oplist]) # type: ignore + + # compare independent of order + return set(self_reduced) == set(other_reduced) diff --git a/qiskit/aqua/operators/primitive_ops/pauli_op.py b/qiskit/aqua/operators/primitive_ops/pauli_op.py index 48d8e21a35..b629331cb7 100644 --- a/qiskit/aqua/operators/primitive_ops/pauli_op.py +++ b/qiskit/aqua/operators/primitive_ops/pauli_op.py @@ -231,10 +231,6 @@ def exp_i(self) -> OperatorBase: from ..evolutions.evolved_op import EvolvedOp return EvolvedOp(self) - def __hash__(self) -> int: - # Need this to be able to easily construct AbelianGraphs - return hash(str(self)) - def commutes(self, other_op: OperatorBase) -> bool: """ Returns whether self commutes with other_op. diff --git a/qiskit/aqua/operators/primitive_ops/primitive_op.py b/qiskit/aqua/operators/primitive_ops/primitive_op.py index fa7d5dc61c..08fe9451c2 100644 --- a/qiskit/aqua/operators/primitive_ops/primitive_op.py +++ b/qiskit/aqua/operators/primitive_ops/primitive_op.py @@ -198,6 +198,9 @@ def log_i(self, massive: bool = False) -> OperatorBase: def __str__(self) -> str: raise NotImplementedError + def __hash__(self) -> int: + return hash(repr(self)) + def __repr__(self) -> str: return "{}({}, coeff={})".format(type(self).__name__, repr(self.primitive), self.coeff) diff --git a/qiskit/optimization/converters/ising_to_quadratic_program.py b/qiskit/optimization/converters/ising_to_quadratic_program.py index 3f56b96f75..2f90171a81 100644 --- a/qiskit/optimization/converters/ising_to_quadratic_program.py +++ b/qiskit/optimization/converters/ising_to_quadratic_program.py @@ -15,12 +15,12 @@ """The converter from a ```Operator``` to ``QuadraticProgram``.""" -from typing import Optional +from typing import Optional, Union import copy import numpy as np -from qiskit.aqua.operators.legacy import WeightedPauliOperator +from qiskit.aqua.operators import OperatorBase, WeightedPauliOperator, SummedOp, ListOp from ..problems.quadratic_program import QuadraticProgram from ..exceptions import QiskitOptimizationError @@ -44,7 +44,8 @@ def __init__(self, linear: bool = False) -> None: self._qp = None # type: Optional[QuadraticProgram] self._linear = linear - def encode(self, qubit_op: WeightedPauliOperator, offset: float = 0.0) -> QuadraticProgram: + def encode(self, qubit_op: Union[OperatorBase, WeightedPauliOperator], offset: float = 0.0 + ) -> QuadraticProgram: """Convert a qubit operator and a shift value into a quadratic program Args: @@ -58,8 +59,18 @@ def encode(self, qubit_op: WeightedPauliOperator, offset: float = 0.0) -> Quadra Raises: QiskitOptimizationError: If there are Pauli Xs in any Pauli term QiskitOptimizationError: If there are more than 2 Pauli Zs in any Pauli term + NotImplementedError: If the input operator is a ListOp """ # Set properties + if isinstance(qubit_op, WeightedPauliOperator): + qubit_op = qubit_op.to_opflow() + + # No support for ListOp yet, this can be added in future + # pylint: disable=unidiomatic-typecheck + if type(qubit_op) == ListOp: + raise NotImplementedError('Conversion of a ListOp is not supported, convert each ' + 'operator in the ListOp separately.') + self._qubit_op = qubit_op self._offset = copy.deepcopy(offset) self._num_qubits = qubit_op.num_qubits @@ -134,24 +145,31 @@ def _create_qubo_matrix(self): # The other elements in the QUBO matrix is for quadratic terms of the qubit operator self._qubo_matrix = np.zeros((self._num_qubits, self._num_qubits)) - for pauli in self._qubit_op.paulis: + if not isinstance(self._qubit_op, SummedOp): + oplist = [self._qubit_op.to_pauli_op()] + else: + oplist = self._qubit_op.to_pauli_op().oplist + + for pauli_op in oplist: + pauli = pauli_op.primitive + coeff = pauli_op.coeff # Count the number of Pauli Zs in a Pauli term - lst_z = pauli[1].z.tolist() + lst_z = pauli.z.tolist() z_index = [i for i, z in enumerate(lst_z) if z is True] num_z = len(z_index) # Add its weight of the Pauli term to the corresponding element of QUBO matrix if num_z == 1: - self._qubo_matrix[z_index[0], z_index[0]] = pauli[0].real + self._qubo_matrix[z_index[0], z_index[0]] = coeff.real elif num_z == 2: - self._qubo_matrix[z_index[0], z_index[1]] = pauli[0].real + self._qubo_matrix[z_index[0], z_index[1]] = coeff.real else: raise QiskitOptimizationError( - 'There are more than 2 Pauli Zs in the Pauli term {}'.format(pauli[1].z) + 'There are more than 2 Pauli Zs in the Pauli term {}'.format(pauli.z) ) # If there are Pauli Xs in the Pauli term, raise an error - lst_x = pauli[1].x.tolist() + lst_x = pauli.x.tolist() x_index = [i for i, x in enumerate(lst_x) if x is True] if len(x_index) > 0: - raise QiskitOptimizationError('Pauli Xs exist in the Pauli {}'.format(pauli[1].x)) + raise QiskitOptimizationError('Pauli Xs exist in the Pauli {}'.format(pauli.x)) diff --git a/qiskit/optimization/converters/quadratic_program_to_ising.py b/qiskit/optimization/converters/quadratic_program_to_ising.py index d937bd6085..4a573e2171 100644 --- a/qiskit/optimization/converters/quadratic_program_to_ising.py +++ b/qiskit/optimization/converters/quadratic_program_to_ising.py @@ -20,7 +20,7 @@ import numpy as np from qiskit.quantum_info import Pauli -from qiskit.aqua.operators import WeightedPauliOperator +from qiskit.aqua.operators import OperatorBase, PauliOp, I from ..problems.quadratic_program import QuadraticProgram from ..exceptions import QiskitOptimizationError @@ -33,7 +33,7 @@ def __init__(self) -> None: """Initialize the internal data structure.""" self._src = None # type: Optional[QuadraticProgram] - def encode(self, op: QuadraticProgram) -> Tuple[WeightedPauliOperator, float]: + def encode(self, op: QuadraticProgram) -> Tuple[OperatorBase, float]: """Convert a problem into a qubit operator Args: @@ -114,6 +114,13 @@ def encode(self, op: QuadraticProgram) -> Tuple[WeightedPauliOperator, float]: shift += weight # Remove paulis whose coefficients are zeros. - qubit_op = WeightedPauliOperator(paulis=pauli_list) + qubit_op = sum(PauliOp(pauli, coeff=coeff) for coeff, pauli in pauli_list) + + # qubit_op could be the integer 0, in this case return an identity operator of + # appropriate size + if isinstance(qubit_op, OperatorBase): + qubit_op = qubit_op.reduce() + else: + qubit_op = I ^ num_nodes return qubit_op, shift diff --git a/releasenotes/notes/summed-op-compare-3df17046849af9a8.yaml b/releasenotes/notes/summed-op-compare-3df17046849af9a8.yaml new file mode 100644 index 0000000000..5fc579a7f5 --- /dev/null +++ b/releasenotes/notes/summed-op-compare-3df17046849af9a8.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + The ``SummedOp`` does a mathematically more correct check for equality, where + expressions such as ``X + X == 2*X`` and ``X + Z == Z + X`` evaluate to ``True``. diff --git a/test/aqua/operators/test_op_construction.py b/test/aqua/operators/test_op_construction.py index 231e1c1a3c..ff4f3dcad1 100644 --- a/test/aqua/operators/test_op_construction.py +++ b/test/aqua/operators/test_op_construction.py @@ -14,23 +14,26 @@ """ Test Operator construction, including OpPrimitives and singletons. """ + import unittest from test.aqua import QiskitAquaTestCase import itertools import numpy as np +from ddt import ddt, data from qiskit.circuit import QuantumCircuit, QuantumRegister, Instruction from qiskit.extensions.exceptions import ExtensionError from qiskit.quantum_info.operators import Operator, Pauli -from qiskit.circuit.library import CZGate +from qiskit.circuit.library import CZGate, ZGate from qiskit.aqua.operators import ( - X, Y, Z, I, CX, T, H, PrimitiveOp, SummedOp, PauliOp, Minus, CircuitOp + X, Y, Z, I, CX, T, H, PrimitiveOp, SummedOp, PauliOp, Minus, CircuitOp, MatrixOp ) # pylint: disable=invalid-name +@ddt class TestOpConstruction(QiskitAquaTestCase): """Operator Construction tests.""" @@ -235,7 +238,7 @@ def test_circuit_permute(self): c_op_id = c_op_perm.permute(perm) self.assertEqual(c_op, c_op_id) - def test_summed_op(self): + def test_summed_op_reduce(self): """Test SummedOp""" sum_op = (X ^ X * 2) + (Y ^ Y) # type: SummedOp with self.subTest('SummedOp test 1'): @@ -250,7 +253,7 @@ def test_summed_op(self): self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY', 'YY']) self.assertListEqual([op.coeff for op in sum_op], [2, 1, 1]) - sum_op = sum_op.simplify() + sum_op = sum_op.collapse_summands() with self.subTest('SummedOp test 2-b'): self.assertEqual(sum_op.coeff, 1) self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) @@ -263,7 +266,7 @@ def test_summed_op(self): self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY', 'YY', 'XX']) self.assertListEqual([op.coeff for op in sum_op], [2, 1, 1, 2]) - sum_op = sum_op.simplify() + sum_op = sum_op.reduce() with self.subTest('SummedOp test 3-b'): self.assertEqual(sum_op.coeff, 1) self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) @@ -275,7 +278,7 @@ def test_summed_op(self): self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) self.assertListEqual([op.coeff for op in sum_op], [2, 1]) - sum_op = sum_op.simplify() + sum_op = sum_op.collapse_summands() with self.subTest('SummedOp test 4-b'): self.assertEqual(sum_op.coeff, 1) self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) @@ -288,7 +291,7 @@ def test_summed_op(self): self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY', 'YY']) self.assertListEqual([op.coeff for op in sum_op], [4, 2, 1]) - sum_op = sum_op.simplify() + sum_op = sum_op.collapse_summands() with self.subTest('SummedOp test 5-b'): self.assertEqual(sum_op.coeff, 1) self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) @@ -301,7 +304,7 @@ def test_summed_op(self): self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY', 'XX', 'YY']) self.assertListEqual([op.coeff for op in sum_op], [4, 2, 2, 1]) - sum_op = sum_op.simplify() + sum_op = sum_op.collapse_summands() with self.subTest('SummedOp test 6-b'): self.assertEqual(sum_op.coeff, 1) self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) @@ -310,11 +313,11 @@ def test_summed_op(self): sum_op = SummedOp([X ^ X * 2, Y ^ Y], 2) sum_op += sum_op with self.subTest('SummedOp test 7-a'): - self.assertEqual(sum_op.coeff, 4) - self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) - self.assertListEqual([op.coeff for op in sum_op], [2, 1]) + self.assertEqual(sum_op.coeff, 1) + self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY', 'XX', 'YY']) + self.assertListEqual([op.coeff for op in sum_op], [4, 2, 4, 2]) - sum_op = sum_op.simplify() + sum_op = sum_op.collapse_summands() with self.subTest('SummedOp test 7-b'): self.assertEqual(sum_op.coeff, 1) self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY']) @@ -326,12 +329,28 @@ def test_summed_op(self): self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY', 'XX', 'ZZ']) self.assertListEqual([op.coeff for op in sum_op], [4, 2, 6, 3]) - sum_op = sum_op.simplify() + sum_op = sum_op.collapse_summands() with self.subTest('SummedOp test 8-b'): self.assertEqual(sum_op.coeff, 1) self.assertListEqual([str(op.primitive) for op in sum_op], ['XX', 'YY', 'ZZ']) self.assertListEqual([op.coeff for op in sum_op], [10, 2, 3]) + def test_summed_op_equals(self): + """Test corner cases of SummedOp's equals function.""" + with self.subTest('multiplicative factor'): + self.assertEqual(2 * X, X + X) + + with self.subTest('commutative'): + self.assertEqual(X + Z, Z + X) + + with self.subTest('circuit and paulis'): + z = CircuitOp(ZGate()) + self.assertEqual(Z + z, z + Z) + + with self.subTest('matrix op and paulis'): + z = MatrixOp([[1, 0], [0, -1]]) + self.assertEqual(Z + z, z + Z) + def test_circuit_compose_register_independent(self): """Test that CircuitOp uses combines circuits independent of the register. @@ -344,13 +363,14 @@ def test_circuit_compose_register_independent(self): self.assertEqual(composed.num_qubits, 2) - def test_pauli_op_hashing(self): + @data(Z, CircuitOp(ZGate()), MatrixOp([[1, 0], [0, -1]])) + def test_op_hashing(self, op): """Regression test against faulty set comparison. Set comparisons rely on a hash table which requires identical objects to have identical - hashes. Thus, the PauliOp.__hash__ should support this requirement. + hashes. Thus, the PrimitiveOp.__hash__ should support this requirement. """ - self.assertEqual(set([2*Z]), set([2*Z])) + self.assertEqual(set([2 * op]), set([2 * op])) if __name__ == '__main__': diff --git a/test/optimization/test_converters.py b/test/optimization/test_converters.py index aedcd19ee9..4cf01ad572 100644 --- a/test/optimization/test_converters.py +++ b/test/optimization/test_converters.py @@ -20,7 +20,7 @@ import numpy as np from docplex.mp.model import Model -from qiskit.aqua.operators import WeightedPauliOperator +from qiskit.aqua.operators import Z, I from qiskit.aqua.algorithms import NumPyMinimumEigensolver from qiskit.optimization import QuadraticProgram, QiskitOptimizationError from qiskit.optimization.problems import Constraint, Variable @@ -34,25 +34,19 @@ ) 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])], - ] -) +QUBIT_OP_MAXIMIZE_SAMPLE = -199999.5 * (I ^ I ^ I ^ Z) + \ + -399999.5 * (I ^ I ^ Z ^ I) + \ + -599999.5 * (I ^ Z ^ I ^ I) + \ + -799999.5 * (Z ^ I ^ I ^ I) + \ + 100000 * (I ^ I ^ Z ^ Z) + \ + 150000 * (I ^ Z ^ I ^ Z) + \ + 300000 * (I ^ Z ^ Z ^ I) + \ + 200000 * (Z ^ I ^ I ^ Z) + \ + 400000 * (Z ^ I ^ Z ^ I) + \ + 600000 * (Z ^ Z ^ I ^ I) OFFSET_MAXIMIZE_SAMPLE = 1149998 @@ -432,12 +426,7 @@ def test_optimizationproblem_to_ising(self): op2 = penalize.encode(op) qubitop, offset = op2ope.encode(op2) - # the encoder uses a dictionary, in which the order of items in Python 3.5 is not - # maintained, therefore don't do a list compare but dictionary compare - qubit_op_as_dict = dict(qubitop.paulis) - for coeff, paulis in QUBIT_OP_MAXIMIZE_SAMPLE.paulis: - self.assertEqual(paulis, qubit_op_as_dict[coeff]) - + self.assertEqual(qubitop, QUBIT_OP_MAXIMIZE_SAMPLE) self.assertEqual(offset, OFFSET_MAXIMIZE_SAMPLE) def test_ising_to_quadraticprogram_linear(self): diff --git a/test/optimization/test_docplex.py b/test/optimization/test_docplex.py index fdc7f6c181..e10a33c7af 100755 --- a/test/optimization/test_docplex.py +++ b/test/optimization/test_docplex.py @@ -21,112 +21,63 @@ 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.applications.ising import docplex, tsp -from qiskit.aqua.operators import WeightedPauliOperator +from qiskit.aqua.operators import I, Z # 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])]]) +QUBIT_OP_MAXCUT = 0.5 * ((I ^ I ^ Z ^ Z) + (I ^ Z ^ I ^ Z) + (I ^ Z ^ Z ^ I) + (Z ^ I ^ I ^ Z) + + (Z ^ Z ^ I ^ I)) 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], - x=[False, False, False, False, False, False, False, False, False])], - [14.5, Pauli(z=[False, True, False, False, False, True, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [-100057.0, Pauli(z=[False, False, True, False, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [-100071.0, Pauli(z=[False, False, False, True, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.5, Pauli(z=[False, False, True, True, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [-100070.0, Pauli(z=[False, False, False, False, False, False, False, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.0, Pauli(z=[True, False, False, False, False, False, False, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [-100070.0, Pauli(z=[False, False, False, False, False, False, False, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [14.0, Pauli(z=[False, True, False, False, False, False, False, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [-100070.0, Pauli(z=[False, False, False, False, False, False, True, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.0, Pauli(z=[False, False, True, False, False, False, True, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.5, Pauli(z=[False, True, False, True, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.5, Pauli(z=[False, False, True, False, True, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.5, Pauli(z=[True, False, False, False, False, True, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [21.0, Pauli(z=[False, False, False, True, False, False, False, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [21.0, Pauli(z=[False, False, False, False, True, False, False, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [21.0, Pauli(z=[False, False, False, False, False, True, True, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.0, Pauli(z=[False, True, False, False, False, False, True, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.0, Pauli(z=[False, False, True, False, False, False, False, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [14.0, Pauli(z=[True, False, False, False, False, False, False, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [21.0, Pauli(z=[False, False, False, False, True, False, True, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [21.0, Pauli(z=[False, False, False, False, False, True, False, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [21.0, Pauli(z=[False, False, False, True, False, False, False, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[True, False, False, True, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[True, False, False, False, False, False, True, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, True, False, False, True, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, True, False, False, True, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, True, False, False, False, False, False, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, False, True, False, False, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, True, False, False, True, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, True, False, False, False, False, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, False, False, True, False, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[True, True, False, False, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[True, False, True, False, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, True, True, False, False, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, True, True, False, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, True, False, True, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, False, True, True, False, False, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, False, False, False, True, True, False], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, False, False, False, True, False, True], - x=[False, False, False, False, False, False, False, False, False])], - [50000.0, Pauli(z=[False, False, False, False, False, False, False, True, True], - x=[False, False, False, False, False, False, False, False, False])]]) +QUBIT_OP_TSP = ( + -100057.0 * (I ^ I ^ I ^ I ^ I ^ I ^ I ^ I ^ Z) + + -100071.0 * (I ^ I ^ I ^ I ^ Z ^ I ^ I ^ I ^ I) + + 14.5 * (I ^ I ^ I ^ I ^ Z ^ I ^ I ^ I ^ Z) + + -100057.0 * (I ^ I ^ I ^ I ^ I ^ I ^ I ^ Z ^ I) + + -100071.0 * (I ^ I ^ I ^ Z ^ I ^ I ^ I ^ I ^ I) + + 14.5 * (I ^ I ^ I ^ Z ^ I ^ I ^ I ^ Z ^ I) + + -100057.0 * (I ^ I ^ I ^ I ^ I ^ I ^ Z ^ I ^ I) + + -100071.0 * (I ^ I ^ I ^ I ^ I ^ Z ^ I ^ I ^ I) + + 14.5 * (I ^ I ^ I ^ I ^ I ^ Z ^ Z ^ I ^ I) + + -100070.0 * (I ^ Z ^ I ^ I ^ I ^ I ^ I ^ I ^ I) + + 14.0 * (I ^ Z ^ I ^ I ^ I ^ I ^ I ^ I ^ Z) + + -100070.0 * (Z ^ I ^ I ^ I ^ I ^ I ^ I ^ I ^ I) + + 14.0 * (Z ^ I ^ I ^ I ^ I ^ I ^ I ^ Z ^ I) + + -100070.0 * (I ^ I ^ Z ^ I ^ I ^ I ^ I ^ I ^ I) + + 14.0 * (I ^ I ^ Z ^ I ^ I ^ I ^ Z ^ I ^ I) + + 14.5 * (I ^ I ^ I ^ I ^ I ^ Z ^ I ^ Z ^ I) + + 14.5 * (I ^ I ^ I ^ I ^ Z ^ I ^ Z ^ I ^ I) + + 14.5 * (I ^ I ^ I ^ Z ^ I ^ I ^ I ^ I ^ Z) + + 21.0 * (I ^ Z ^ I ^ I ^ I ^ Z ^ I ^ I ^ I) + + 21.0 * (Z ^ I ^ I ^ I ^ Z ^ I ^ I ^ I ^ I) + + 21.0 * (I ^ I ^ Z ^ Z ^ I ^ I ^ I ^ I ^ I) + + 14.0 * (I ^ I ^ Z ^ I ^ I ^ I ^ I ^ Z ^ I) + + 14.0 * (I ^ Z ^ I ^ I ^ I ^ I ^ Z ^ I ^ I) + + 14.0 * (Z ^ I ^ I ^ I ^ I ^ I ^ I ^ I ^ Z) + + 21.0 * (I ^ I ^ Z ^ I ^ Z ^ I ^ I ^ I ^ I) + + 21.0 * (I ^ Z ^ I ^ Z ^ I ^ I ^ I ^ I ^ I) + + 21.0 * (Z ^ I ^ I ^ I ^ I ^ Z ^ I ^ I ^ I) + + 50000.0 * (I ^ I ^ I ^ I ^ I ^ Z ^ I ^ I ^ Z) + + 50000.0 * (I ^ I ^ Z ^ I ^ I ^ I ^ I ^ I ^ Z) + + 50000.0 * (I ^ I ^ Z ^ I ^ I ^ Z ^ I ^ I ^ I) + + 50000.0 * (I ^ I ^ I ^ I ^ Z ^ I ^ I ^ Z ^ I) + + 50000.0 * (I ^ Z ^ I ^ I ^ I ^ I ^ I ^ Z ^ I) + + 50000.0 * (I ^ Z ^ I ^ I ^ Z ^ I ^ I ^ I ^ I) + + 50000.0 * (I ^ I ^ I ^ Z ^ I ^ I ^ Z ^ I ^ I) + + 50000.0 * (Z ^ I ^ I ^ I ^ I ^ I ^ Z ^ I ^ I) + + 50000.0 * (Z ^ I ^ I ^ Z ^ I ^ I ^ I ^ I ^ I) + + 50000.0 * (I ^ I ^ I ^ I ^ I ^ I ^ I ^ Z ^ Z) + + 50000.0 * (I ^ I ^ I ^ I ^ I ^ I ^ Z ^ I ^ Z) + + 50000.0 * (I ^ I ^ I ^ I ^ I ^ I ^ Z ^ Z ^ I) + + 50000.0 * (I ^ I ^ I ^ I ^ Z ^ Z ^ I ^ I ^ I) + + 50000.0 * (I ^ I ^ I ^ Z ^ I ^ Z ^ I ^ I ^ I) + + 50000.0 * (I ^ I ^ I ^ Z ^ Z ^ I ^ I ^ I ^ I) + + 50000.0 * (I ^ Z ^ Z ^ I ^ I ^ I ^ I ^ I ^ I) + + 50000.0 * (Z ^ I ^ Z ^ I ^ I ^ I ^ I ^ I ^ I) + + 50000.0 * (Z ^ Z ^ I ^ I ^ I ^ I ^ I ^ I ^ I) +) OFFSET_TSP = 600279.0 diff --git a/test/optimization/test_qaoa.py b/test/optimization/test_qaoa.py index 3d9aa33ab7..08778ed8c0 100755 --- a/test/optimization/test_qaoa.py +++ b/test/optimization/test_qaoa.py @@ -26,7 +26,7 @@ from qiskit.aqua.components.optimizers import COBYLA from qiskit.aqua.algorithms import QAOA from qiskit.aqua import QuantumInstance, aqua_globals -from qiskit.aqua.operators import WeightedPauliOperator, X, Z +from qiskit.aqua.operators import X, Z, I W1 = np.array([ [0, 1, 0, 1], @@ -35,11 +35,7 @@ [1, 0, 1, 0] ]) P1 = 1 -M1 = WeightedPauliOperator.from_dict({'paulis': [{'label': 'IIIX', 'coeff': {'real': 1}}, - {'label': 'IIXI', 'coeff': {'real': 1}}, - {'label': 'IXII', 'coeff': {'real': 1}}, - {'label': 'XIII', 'coeff': {'real': 1}}] - }).to_opflow() +M1 = (I ^ I ^ I ^ X) + (I ^ I ^ X ^ I) + (I ^ X ^ I ^ I) + (X ^ I ^ I ^ I) S1 = {'0101', '1010'}