Ejemplo n.º 1
0
    def test_aux_operator_std_dev(self):
        """Test actuall standard deviation of aux operators in non-zero case."""
        wavefunction = self.ry_wavefunction
        vqe = VQE(
            ansatz=wavefunction,
            optimizer=SPSA(maxiter=300, last_avg=5),
            quantum_instance=self.qasm_simulator,
        )

        # Go again with two auxiliary operators
        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)])
        aux_ops = [aux_op1, aux_op2, None, 0]
        result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops)
        self.assertAlmostEqual(result.eigenvalue.real, -1.8691994, places=6)
        self.assertEqual(len(result.aux_operator_eigenvalues), 4)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2, places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0.0019531, places=6)
        self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0)
        self.assertEqual(result.aux_operator_eigenvalues[3][0], 0.0)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0214711)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0)
Ejemplo n.º 2
0
    def test_to_ising(self):
        """test to_ising"""

        with self.subTest("minimize"):
            # minimize: x + x * y
            # subject to: x, y \in {0, 1}
            q_p = QuadraticProgram("test")
            q_p.binary_var(name="x")
            q_p.binary_var(name="y")
            q_p.minimize(linear={"x": 1}, quadratic={("x", "y"): 1})
            op, offset = to_ising(q_p)
            op_ref = PauliSumOp.from_list([("ZI", -0.25), ("IZ", -0.75), ("ZZ", 0.25)])
            np.testing.assert_allclose(op.to_matrix(), op_ref.to_matrix())
            self.assertAlmostEqual(offset, 0.75)

        with self.subTest("maximize"):
            # maximize: x + x * y
            # subject to: x, y \in {0, 1}
            q_p = QuadraticProgram("test")
            q_p.binary_var(name="x")
            q_p.binary_var(name="y")
            q_p.maximize(linear={"x": 1}, quadratic={("x", "y"): 1})
            op, offset = to_ising(q_p)
            op_ref = PauliSumOp.from_list([("ZI", 0.25), ("IZ", 0.75), ("ZZ", -0.25)])
            np.testing.assert_allclose(op.to_matrix(), op_ref.to_matrix())
            self.assertAlmostEqual(offset, -0.75)
    def test_mapping_for_single_op(self):
        """Test for single register operator."""
        with self.subTest("test +"):
            op = FermionicOp("+", display_format="dense")
            expected = PauliSumOp.from_list([("X", 0.5), ("Y", -0.5j)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test -"):
            op = FermionicOp("-", display_format="dense")
            expected = PauliSumOp.from_list([("X", 0.5), ("Y", 0.5j)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test N"):
            op = FermionicOp("N", display_format="dense")
            expected = PauliSumOp.from_list([("I", 0.5), ("Z", -0.5)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test E"):
            op = FermionicOp("E", display_format="dense")
            expected = PauliSumOp.from_list([("I", 0.5), ("Z", 0.5)])
            self.assertEqual(JordanWignerMapper().map(op), expected)

        with self.subTest("test I"):
            op = FermionicOp("I", display_format="dense")
            expected = PauliSumOp.from_list([("I", 1)])
            self.assertEqual(JordanWignerMapper().map(op), expected)
Ejemplo n.º 4
0
def number_operator(fer_op, mode_number=None):
    """Find the qubit operator for the number operator in bravyi_kitaev_fast representation.

    Args:
        fer_op (FermionicOperator): the fermionic operator in the second quantized form
        mode_number (int): index, it corresponds to the mode for which number operator is required.

    Returns:
        PauliSumOp: the qubit operator
    """
    modes = fer_op.h1.modes
    edge_list = bravyi_kitaev_fast_edge_list(fer_op)
    num_qubits = edge_list.shape[1]
    num_operator = PauliSumOp.from_list([('I' * num_qubits, 1.0)])

    if mode_number is None:
        for i in range(modes):
            num_operator -= edge_operator_bi(edge_list, i)
        num_operator += \
            PauliSumOp.from_list([('I' * num_qubits, 1.0 * modes)])
    else:
        num_operator += (PauliSumOp.from_list([('I' * num_qubits, 1.0)]) -
                         edge_operator_bi(edge_list, mode_number))

    num_operator = 0.5 * num_operator
    return num_operator
Ejemplo n.º 5
0
    def test_is_hermitian(self):
        """Test is_hermitian method"""
        with self.subTest("True test"):
            target = PauliSumOp.from_list(
                [
                    ("II", -1.052373245772859),
                    ("IZ", 0.39793742484318045),
                    ("ZI", -0.39793742484318045),
                    ("ZZ", -0.01128010425623538),
                    ("XX", 0.18093119978423156),
                ]
            )
            self.assertTrue(target.is_hermitian())

        with self.subTest("False test"):
            target = PauliSumOp.from_list(
                [
                    ("II", -1.052373245772859),
                    ("IZ", 0.39793742484318045j),
                    ("ZI", -0.39793742484318045),
                    ("ZZ", -0.01128010425623538),
                    ("XX", 0.18093119978423156),
                ]
            )
            self.assertFalse(target.is_hermitian())
Ejemplo n.º 6
0
def vacuum_operator(fer_op):
    """Use the stabilizers to find the vacuum state in bravyi_kitaev_fast.

    Args:
        fer_op (FermionicOperator): the fermionic operator in the second quantized form

    Returns:
        PauliSumOp: the qubit operator
    """
    edge_list = bravyi_kitaev_fast_edge_list(fer_op)
    num_qubits = edge_list.shape[1]
    vac_operator = PauliSumOp.from_list([('I' * num_qubits, 1.0)])

    graph = retworkx.PyGraph()
    graph.extend_from_edge_list(list(map(tuple, edge_list.transpose())))
    stabs = np.asarray(retworkx.cycle_basis(graph))
    for stab in stabs:
        a_op = PauliSumOp.from_list([('I' * num_qubits, 1.0)])
        stab = np.asarray(stab)
        for i in range(np.size(stab)):
            a_op = a_op * edge_operator_aij(edge_list, stab[i],
                                            stab[(i + 1) % np.size(stab)]) * 1j
            # a_op.scaling_coeff(1j)
        a_op += PauliSumOp.from_list([('I' * num_qubits, 1.0)])
        vac_operator = vac_operator * a_op * np.sqrt(2)
        # vac_operator.scaling_coeff()

    return vac_operator
Ejemplo n.º 7
0
    def test_aux_operator_std_dev_pauli(self):
        """Test non-zero standard deviations of aux operators with PauliExpectation."""
        wavefunction = self.ry_wavefunction
        vqd = VQD(
            ansatz=wavefunction,
            expectation=PauliExpectation(),
            initial_point=[
                1.70256666,
                -5.34843975,
                -0.39542903,
                5.99477786,
                -2.74374986,
                -4.85284669,
                0.2442925,
                -1.51638917,
            ],
            optimizer=COBYLA(maxiter=0),
            quantum_instance=self.qasm_simulator,
        )

        # Go again with two auxiliary operators
        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5),
                                        ("XX", -0.5)])
        aux_ops = [aux_op1, aux_op2]
        result = vqd.compute_eigenvalues(self.h2_op, aux_operators=aux_ops)
        self.assertEqual(len(result.aux_operator_eigenvalues), 2)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][0],
                               2.0,
                               places=1)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][0],
                               0.0019531249999999445,
                               places=1)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][1],
                               0.015183867579396111,
                               places=1)

        # Go again with additional None and zero operators
        aux_ops = [*aux_ops, None, 0]
        result = vqd.compute_eigenvalues(self.h2_op, aux_operators=aux_ops)
        self.assertEqual(len(result.aux_operator_eigenvalues[0]), 4)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][0],
                               2.0,
                               places=1)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][0],
                               0.0019531249999999445,
                               places=1)
        self.assertEqual(result.aux_operator_eigenvalues[0][2][0], 0.0)
        self.assertEqual(result.aux_operator_eigenvalues[0][3][0], 0.0)
        # # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][1],
                               0.01548658094658011,
                               places=1)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][2][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][3][1], 0.0)
    def test_opflow_qnn_2_2(self, q_i):
        """Test Torch Connector + Opflow QNN with input/output dimension 2/2."""
        from torch import Tensor

        if q_i == "sv":
            quantum_instance = self._sv_quantum_instance
        else:
            quantum_instance = self._qasm_quantum_instance

        # construct parametrized circuit
        params_1 = [Parameter("input1"), Parameter("weight1")]
        qc_1 = QuantumCircuit(1)
        qc_1.h(0)
        qc_1.ry(params_1[0], 0)
        qc_1.rx(params_1[1], 0)
        qc_sfn_1 = StateFn(qc_1)

        # construct cost operator
        h_1 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_1 = ~h_1 @ qc_sfn_1

        # construct parametrized circuit
        params_2 = [Parameter("input2"), Parameter("weight2")]
        qc_2 = QuantumCircuit(1)
        qc_2.h(0)
        qc_2.ry(params_2[0], 0)
        qc_2.rx(params_2[1], 0)
        qc_sfn_2 = StateFn(qc_2)

        # construct cost operator
        h_2 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_2 = ~h_2 @ qc_sfn_2

        op = ListOp([op_1, op_2])

        qnn = OpflowQNN(
            op,
            [params_1[0], params_2[0]],
            [params_1[1], params_2[1]],
            quantum_instance=quantum_instance,
            input_gradients=True,
        )
        model = TorchConnector(qnn)

        test_data = [
            Tensor([1]),
            Tensor([1, 2]),
            Tensor([[1], [2]]),
            Tensor([[1, 2], [3, 4]]),
        ]

        # test model
        self._validate_output_shape(model, test_data)
        if q_i == "sv":
            self._validate_backward_pass(model)
    def test_opflow_qnn_2_2(self, config):
        """Test Opflow QNN with input/output dimension 2/2."""
        q_i, input_grad_required = config

        if q_i == STATEVECTOR:
            quantum_instance = self.sv_quantum_instance
        elif q_i == QASM:
            quantum_instance = self.qasm_quantum_instance
        else:
            quantum_instance = None

        # construct parametrized circuit
        params_1 = [Parameter("input1"), Parameter("weight1")]
        qc_1 = QuantumCircuit(1)
        qc_1.h(0)
        qc_1.ry(params_1[0], 0)
        qc_1.rx(params_1[1], 0)
        qc_sfn_1 = StateFn(qc_1)

        # construct cost operator
        h_1 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_1 = ~h_1 @ qc_sfn_1

        # construct parametrized circuit
        params_2 = [Parameter("input2"), Parameter("weight2")]
        qc_2 = QuantumCircuit(1)
        qc_2.h(0)
        qc_2.ry(params_2[0], 0)
        qc_2.rx(params_2[1], 0)
        qc_sfn_2 = StateFn(qc_2)

        # construct cost operator
        h_2 = StateFn(PauliSumOp.from_list([("Z", 1.0), ("X", 1.0)]))

        # combine operator and circuit to objective function
        op_2 = ~h_2 @ qc_sfn_2

        op = ListOp([op_1, op_2])

        qnn = OpflowQNN(
            op,
            [params_1[0], params_2[0]],
            [params_1[1], params_2[1]],
            quantum_instance=quantum_instance,
        )
        qnn.input_gradients = input_grad_required

        test_data = [np.array([1, 2]), np.array([[1, 2], [3, 4]])]

        # test model
        self.validate_output_shape(qnn, test_data)

        # test the qnn after we set a quantum instance
        if quantum_instance is None:
            qnn.quantum_instance = self.qasm_quantum_instance
            self.validate_output_shape(qnn, test_data)
Ejemplo n.º 10
0
    def test_opflow_qnn_2_2(self, q_i):
        """ Test Torch Connector + Opflow QNN with input/output dimension 2/2."""

        if q_i == 'sv':
            quantum_instance = self.sv_quantum_instance
        else:
            quantum_instance = self.qasm_quantum_instance

        # construct parametrized circuit
        params_1 = [Parameter('input1'), Parameter('weight1')]
        qc_1 = QuantumCircuit(1)
        qc_1.h(0)
        qc_1.ry(params_1[0], 0)
        qc_1.rx(params_1[1], 0)
        qc_sfn_1 = StateFn(qc_1)

        # construct cost operator
        h_1 = StateFn(PauliSumOp.from_list([('Z', 1.0), ('X', 1.0)]))

        # combine operator and circuit to objective function
        op_1 = ~h_1 @ qc_sfn_1

        # construct parametrized circuit
        params_2 = [Parameter('input2'), Parameter('weight2')]
        qc_2 = QuantumCircuit(1)
        qc_2.h(0)
        qc_2.ry(params_2[0], 0)
        qc_2.rx(params_2[1], 0)
        qc_sfn_2 = StateFn(qc_2)

        # construct cost operator
        h_2 = StateFn(PauliSumOp.from_list([('Z', 1.0), ('X', 1.0)]))

        # combine operator and circuit to objective function
        op_2 = ~h_2 @ qc_sfn_2

        op = ListOp([op_1, op_2])

        qnn = OpflowQNN(op, [params_1[0], params_2[0]],
                        [params_1[1], params_2[1]],
                        quantum_instance=quantum_instance)
        try:
            model = TorchConnector(qnn)

            test_data = [
                Tensor(1),
                Tensor([1, 2]),
                Tensor([[1], [2]]),
                Tensor([[1, 2], [3, 4]])
            ]

            # test model
            self.validate_output_shape(model, test_data)
            if q_i == 'sv':
                self.validate_backward_pass(model)
        except MissingOptionalLibraryError as ex:
            self.skipTest(str(ex))
Ejemplo n.º 11
0
    def test_aux_operators_list(self):
        """Test list-based aux_operators."""
        wavefunction = self.ry_wavefunction
        vqe = VQE(ansatz=wavefunction,
                  quantum_instance=self.statevector_simulator)

        # Start with an empty list
        result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=[])
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=6)
        self.assertIsNone(result.aux_operator_eigenvalues)

        # Go again with two auxiliary operators
        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5),
                                        ("XX", -0.5)])
        aux_ops = [aux_op1, aux_op2]
        result = vqe.compute_minimum_eigenvalue(self.h2_op,
                                                aux_operators=aux_ops)
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=6)
        self.assertEqual(len(result.aux_operator_eigenvalues), 2)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0],
                               2,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0],
                               0,
                               places=6)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0)

        # Go again with additional None and zero operators
        extra_ops = [*aux_ops, None, 0]
        result = vqe.compute_minimum_eigenvalue(self.h2_op,
                                                aux_operators=extra_ops)
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=6)
        self.assertEqual(len(result.aux_operator_eigenvalues), 4)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0],
                               2,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0],
                               0,
                               places=6)
        self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0)
        self.assertEqual(result.aux_operator_eigenvalues[3][0], 0.0)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0)
Ejemplo n.º 12
0
    def test_aux_operator_std_dev_aer_pauli(self):
        """Test non-zero standard deviations of aux operators with AerPauliExpectation."""
        wavefunction = self.ry_wavefunction
        vqe = VQE(
            ansatz=wavefunction,
            expectation=AerPauliExpectation(),
            optimizer=COBYLA(maxiter=0),
            quantum_instance=QuantumInstance(
                backend=Aer.get_backend("qasm_simulator"),
                shots=1,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )

        # Go again with two auxiliary operators
        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5),
                                        ("XX", -0.5)])
        aux_ops = [aux_op1, aux_op2]
        result = vqe.compute_minimum_eigenvalue(self.h2_op,
                                                aux_operators=aux_ops)
        self.assertEqual(len(result.aux_operator_eigenvalues), 2)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0],
                               2.0,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0],
                               0.6698863565455391,
                               places=6)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1],
                               0.0,
                               places=6)

        # Go again with additional None and zero operators
        aux_ops = [*aux_ops, None, 0]
        result = vqe.compute_minimum_eigenvalue(self.h2_op,
                                                aux_operators=aux_ops)
        self.assertEqual(len(result.aux_operator_eigenvalues), 4)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0],
                               2.0,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0],
                               0.6036400943063891,
                               places=6)
        self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0)
        self.assertEqual(result.aux_operator_eigenvalues[3][0], 0.0)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1],
                               0.0,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0)
    def test_aux_operators_dict(self):
        """Test dict-based aux_operators."""
        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5),
                                        ("XX", -0.5)])
        aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2}
        algo = NumPyEigensolver()
        result = algo.compute_eigenvalues(operator=self.qubit_op,
                                          aux_operators=aux_ops)
        self.assertEqual(len(result.eigenvalues), 1)
        self.assertEqual(len(result.eigenstates), 1)
        self.assertEqual(result.eigenvalues.dtype, np.float64)
        self.assertAlmostEqual(result.eigenvalues[0], -1.85727503)
        self.assertEqual(len(result.aux_operator_eigenvalues), 1)
        self.assertEqual(len(result.aux_operator_eigenvalues[0]), 2)
        # expectation values
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op1"][0], 2, places=6)
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op2"][0], 0, places=6)
        # standard deviations
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op1"][1], 0.0)
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op2"][1], 0.0)

        # Go again with additional None and zero operators
        extra_ops = {**aux_ops, "None_operator": None, "zero_operator": 0}
        result = algo.compute_eigenvalues(operator=self.qubit_op,
                                          aux_operators=extra_ops)
        self.assertEqual(len(result.eigenvalues), 1)
        self.assertEqual(len(result.eigenstates), 1)
        self.assertEqual(result.eigenvalues.dtype, np.float64)
        self.assertAlmostEqual(result.eigenvalues[0], -1.85727503)
        self.assertEqual(len(result.aux_operator_eigenvalues), 1)
        self.assertEqual(len(result.aux_operator_eigenvalues[0]), 3)
        # expectation values
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op1"][0], 2, places=6)
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op2"][0], 0, places=6)
        self.assertEqual(
            result.aux_operator_eigenvalues[0]["zero_operator"][0], 0.0)
        self.assertTrue(
            "None_operator" not in result.aux_operator_eigenvalues[0].keys())
        # standard deviations
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op1"][1], 0.0)
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["aux_op2"][1], 0.0)
        self.assertAlmostEqual(
            result.aux_operator_eigenvalues[0]["zero_operator"][1], 0.0)
Ejemplo n.º 14
0
    def test_aux_operator_std_dev_pauli(self):
        """Test non-zero standard deviations of aux operators with PauliExpectation."""
        wavefunction = self.ry_wavefunction
        vqe = VQE(
            ansatz=wavefunction,
            expectation=PauliExpectation(),
            optimizer=COBYLA(maxiter=0),
            quantum_instance=self.qasm_simulator,
        )

        # Go again with two auxiliary operators
        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5),
                                        ("XX", -0.5)])
        aux_ops = [aux_op1, aux_op2]
        result = vqe.compute_minimum_eigenvalue(self.h2_op,
                                                aux_operators=aux_ops)
        self.assertEqual(len(result.aux_operator_eigenvalues), 2)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0],
                               2.0,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0],
                               0.6796875,
                               places=6)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1],
                               0.02534712219145965,
                               places=6)

        # Go again with additional None and zero operators
        aux_ops = [*aux_ops, None, 0]
        result = vqe.compute_minimum_eigenvalue(self.h2_op,
                                                aux_operators=aux_ops)
        self.assertEqual(len(result.aux_operator_eigenvalues), 4)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0],
                               2.0,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0],
                               0.57421875,
                               places=6)
        self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0)
        self.assertEqual(result.aux_operator_eigenvalues[3][0], 0.0)
        # # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1],
                               0.026562146577166837,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0)
    def setUp(self):
        super().setUp()
        self.qubit_op = PauliSumOp.from_list([
            ("II", -1.052373245772859),
            ("ZI", 0.39793742484318045),
            ("IZ", -0.39793742484318045),
            ("ZZ", -0.01128010425623538),
            ("XX", 0.18093119978423156),
        ])

        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5),
                                        ("XX", -0.5)])
        self.aux_ops = [aux_op1, aux_op2]
    def test_aux_operators_list(self):
        """Test list-based aux_operators."""
        aux_op1 = PauliSumOp.from_list([("II", 2.0)])
        aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5),
                                        ("XX", -0.5)])
        aux_ops = [aux_op1, aux_op2]
        algo = NumPyEigensolver()
        result = algo.compute_eigenvalues(operator=self.qubit_op,
                                          aux_operators=aux_ops)
        self.assertEqual(len(result.eigenvalues), 1)
        self.assertEqual(len(result.eigenstates), 1)
        self.assertEqual(result.eigenvalues.dtype, np.float64)
        self.assertAlmostEqual(result.eigenvalues[0], -1.85727503)
        self.assertEqual(len(result.aux_operator_eigenvalues), 1)
        self.assertEqual(len(result.aux_operator_eigenvalues[0]), 2)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][0],
                               2,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][0],
                               0,
                               places=6)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][1], 0.0)

        # Go again with additional None and zero operators
        extra_ops = [*aux_ops, None, 0]
        result = algo.compute_eigenvalues(operator=self.qubit_op,
                                          aux_operators=extra_ops)
        self.assertEqual(len(result.eigenvalues), 1)
        self.assertEqual(len(result.eigenstates), 1)
        self.assertEqual(result.eigenvalues.dtype, np.float64)
        self.assertAlmostEqual(result.eigenvalues[0], -1.85727503)
        self.assertEqual(len(result.aux_operator_eigenvalues), 1)
        self.assertEqual(len(result.aux_operator_eigenvalues[0]), 4)
        # expectation values
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][0],
                               2,
                               places=6)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][0],
                               0,
                               places=6)
        self.assertIsNone(result.aux_operator_eigenvalues[0][2], None)
        self.assertEqual(result.aux_operator_eigenvalues[0][3][0], 0.0)
        # standard deviations
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0][1], 0.0)
        self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1][1], 0.0)
        self.assertEqual(result.aux_operator_eigenvalues[0][3][1], 0.0)
    def test_opflow_qnn_2_2(self, q_i):
        """ Test Opflow QNN with input/output dimension 2/2."""

        if q_i == 'sv':
            quantum_instance = self.sv_quantum_instance
        else:
            quantum_instance = self.qasm_quantum_instance

        # construct parametrized circuit
        params_1 = [Parameter('input1'), Parameter('weight1')]
        qc_1 = QuantumCircuit(1)
        qc_1.h(0)
        qc_1.ry(params_1[0], 0)
        qc_1.rx(params_1[1], 0)
        qc_sfn_1 = StateFn(qc_1)

        # construct cost operator
        h_1 = StateFn(PauliSumOp.from_list([('Z', 1.0), ('X', 1.0)]))

        # combine operator and circuit to objective function
        op_1 = ~h_1 @ qc_sfn_1

        # construct parametrized circuit
        params_2 = [Parameter('input2'), Parameter('weight2')]
        qc_2 = QuantumCircuit(1)
        qc_2.h(0)
        qc_2.ry(params_2[0], 0)
        qc_2.rx(params_2[1], 0)
        qc_sfn_2 = StateFn(qc_2)

        # construct cost operator
        h_2 = StateFn(PauliSumOp.from_list([('Z', 1.0), ('X', 1.0)]))

        # combine operator and circuit to objective function
        op_2 = ~h_2 @ qc_sfn_2

        op = ListOp([op_1, op_2])

        qnn = OpflowQNN(op, [params_1[0], params_2[0]], [params_1[1], params_2[1]],
                        quantum_instance=quantum_instance)

        test_data = [
            np.array([1, 2]),
            np.array([[1, 2], [3, 4]])
        ]

        # test model
        self.validate_output_shape(qnn, test_data)
 def test_quadratic_program_element_when_loaded_from_source(self):
     """Test QuadraticProgramElement when QuadraticProgram is loaded from an external source"""
     with self.subTest("from_ising"):
         q_p = QuadraticProgram()
         q_p.from_ising(PauliSumOp.from_list([("IZ", 1), ("ZZ", 2)]))
         self.assertEqual(id(q_p.objective.quadratic_program), id(q_p))
         for elem in q_p.variables:
             self.assertEqual(id(elem.quadratic_program), id(q_p))
         for elem in q_p.linear_constraints:
             self.assertEqual(id(elem.quadratic_program), id(q_p))
         for elem in q_p.quadratic_constraints:
             self.assertEqual(id(elem.quadratic_program), id(q_p))
     try:
         lp_file = self.get_resource_path("test_quadratic_program.lp",
                                          "problems/resources")
         q_p = QuadraticProgram()
         q_p.read_from_lp_file(lp_file)
         self.assertEqual(id(q_p.objective.quadratic_program), id(q_p))
         for elem in q_p.variables:
             self.assertEqual(id(elem.quadratic_program), id(q_p))
         for elem in q_p.linear_constraints:
             self.assertEqual(id(elem.quadratic_program), id(q_p))
         for elem in q_p.quadratic_constraints:
             self.assertEqual(id(elem.quadratic_program), id(q_p))
     except RuntimeError as ex:
         self.fail(str(ex))
Ejemplo n.º 19
0
 def test_with_two_qubit_reduction(self):
     """Test the VQE using TwoQubitReduction."""
     qubit_op = PauliSumOp.from_list([
         ("IIII", -0.8105479805373266),
         ("IIIZ", 0.17218393261915552),
         ("IIZZ", -0.22575349222402472),
         ("IZZI", 0.1721839326191556),
         ("ZZII", -0.22575349222402466),
         ("IIZI", 0.1209126326177663),
         ("IZZZ", 0.16892753870087912),
         ("IXZX", -0.045232799946057854),
         ("ZXIX", 0.045232799946057854),
         ("IXIX", 0.045232799946057854),
         ("ZXZX", -0.045232799946057854),
         ("ZZIZ", 0.16614543256382414),
         ("IZIZ", 0.16614543256382414),
         ("ZZZZ", 0.17464343068300453),
         ("ZIZI", 0.1209126326177663),
     ])
     tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op)
     for simulator in [self.qasm_simulator, self.statevector_simulator]:
         with self.subTest(f"Test for {simulator}."):
             vqe = VQE(
                 self.ry_wavefunction,
                 SPSA(maxiter=300, last_avg=5),
                 quantum_instance=simulator,
             )
             result = vqe.compute_minimum_eigenvalue(tapered_qubit_op)
             energy = -1.868 if simulator == self.qasm_simulator else self.h2_energy
             self.assertAlmostEqual(result.eigenvalue.real,
                                    energy,
                                    places=2)
Ejemplo n.º 20
0
    def test_from_ising2(self):
        """test to_from_ising 2"""
        # minimize: 1 - 2 * x1 - 2 * x2 + 4 * x1 * x2
        # subject to: x, y \in {0, 1}
        op = PauliSumOp.from_list([("ZZ", 1)])
        with self.subTest("linear: True"):
            q_p = from_ising(op, 0, linear=True)
            self.assertEqual(q_p.get_num_vars(), op.num_qubits)
            self.assertEqual(q_p.get_num_linear_constraints(), 0)
            self.assertEqual(q_p.get_num_quadratic_constraints(), 0)
            self.assertAlmostEqual(q_p.objective.constant, 1)
            np.testing.assert_array_almost_equal(
                q_p.objective.linear.to_array(), [-2, -2])
            np.testing.assert_array_almost_equal(
                q_p.objective.quadratic.to_array(), [[0, 4], [0, 0]])

        with self.subTest("linear: False"):
            q_p = from_ising(op, 0, linear=False)
            self.assertEqual(q_p.get_num_vars(), op.num_qubits)
            self.assertEqual(q_p.get_num_linear_constraints(), 0)
            self.assertEqual(q_p.get_num_quadratic_constraints(), 0)
            self.assertAlmostEqual(q_p.objective.constant, 1)
            np.testing.assert_array_almost_equal(
                q_p.objective.linear.to_array(), [0, 0])
            np.testing.assert_array_almost_equal(
                q_p.objective.quadratic.to_array(), [[-2, 4], [0, -2]])
Ejemplo n.º 21
0
def get_operator(values: np.ndarray) -> Tuple[PauliSumOp, float]:
    """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: array of values.

    Returns:
        operator for the Hamiltonian and a
        constant shift for the obj function.

    """
    n = len(values)
    # The Hamiltonian is:
    # \sum_{i,j=1,\dots,n} ij z_iz_j + \sum_{i=1,\dots,n} i^2
    pauli_list = []
    for i in range(n):
        for j in range(i):
            x_p = np.zeros(n, dtype=np.bool)
            z_p = np.zeros(n, dtype=np.bool)
            z_p[i] = True
            z_p[j] = True
            pauli_list.append([2. * values[i] * values[j], Pauli(z_p, x_p)])
    opflow_list = [(pauli[1].to_label(), pauli[0]) for pauli in pauli_list]
    return PauliSumOp.from_list(opflow_list), sum(values * values)
def _build_single_hopping_operator(
    excitation: Tuple[Tuple[int, ...], Tuple[int, ...]],
    num_spin_orbitals: int,
    qubit_converter: QubitConverter,
) -> Tuple[PauliSumOp, List[bool]]:
    label = ["I"] * num_spin_orbitals
    for occ in excitation[0]:
        label[occ] = "+"
    for unocc in excitation[1]:
        label[unocc] = "-"
    fer_op = FermionicOp(("".join(label), 4.0**len(excitation[0])))

    qubit_op: PauliSumOp = qubit_converter.convert_match(fer_op)
    z2_symmetries = qubit_converter.z2symmetries

    commutativities = []
    if not z2_symmetries.is_empty():
        for symmetry in z2_symmetries.symmetries:
            symmetry_op = PauliSumOp.from_list([(symmetry.to_label(), 1.0)])
            commuting = qubit_op.primitive.table.commutes_with_all(
                symmetry_op.primitive.table)
            anticommuting = qubit_op.primitive.table.anticommutes_with_all(
                symmetry_op.primitive.table)

            if commuting != anticommuting:  # only one of them is True
                if commuting:
                    commutativities.append(True)
                elif anticommuting:
                    commutativities.append(False)
            else:
                raise QiskitNatureError(
                    "Symmetry {} is nor commute neither anti-commute "
                    "to exciting operator.".format(symmetry.to_label()))

    return qubit_op, commutativities
Ejemplo n.º 23
0
 def test_list_pauli_sum(self):
     """Test AerPauliExpectation for ListOp[PauliSumOp]"""
     test_op = ListOp([PauliSumOp.from_list([("XX", 1), ("ZI", 3), ("ZZ", 5)])])
     observable = AerPauliExpectation().convert(~StateFn(test_op))
     self.assertIsInstance(observable, ListOp)
     self.assertIsInstance(observable[0], CircuitStateFn)
     self.assertTrue(observable[0].is_measurement)
Ejemplo n.º 24
0
    def test_from_ising(self):
        """test to_from_ising"""
        # minimize: x + x * y
        # subject to: x, y \in {0, 1}
        op = PauliSumOp.from_list([("ZI", -0.25), ("IZ", -0.75), ("ZZ", 0.25)])
        with self.subTest("linear: True"):
            q_p = from_ising(op, 0.75, linear=True)
            self.assertEqual(q_p.get_num_vars(), op.num_qubits)
            self.assertEqual(q_p.get_num_linear_constraints(), 0)
            self.assertEqual(q_p.get_num_quadratic_constraints(), 0)
            self.assertAlmostEqual(q_p.objective.constant, 0)
            np.testing.assert_array_almost_equal(
                q_p.objective.linear.to_array(), [1, 0])
            np.testing.assert_array_almost_equal(
                q_p.objective.quadratic.to_array(), [[0, 1], [0, 0]])

        with self.subTest("linear: False"):
            q_p = from_ising(op, 0.75, linear=False)
            self.assertEqual(q_p.get_num_vars(), op.num_qubits)
            self.assertEqual(q_p.get_num_linear_constraints(), 0)
            self.assertEqual(q_p.get_num_quadratic_constraints(), 0)
            self.assertAlmostEqual(q_p.objective.constant, 0)
            np.testing.assert_array_almost_equal(
                q_p.objective.linear.to_array(), [0, 0])
            np.testing.assert_array_almost_equal(
                q_p.objective.quadratic.to_array(), [[1, 1], [0, 0]])
Ejemplo n.º 25
0
    def mixer_operator(self):
        """Returns an optional mixer operator expressed as an operator or a quantum circuit.

        Returns:
            OperatorBase or QuantumCircuit, optional: mixer operator or circuit.
        """
        if self._mixer is not None:
            return self._mixer

        # if no mixer is passed and we know the number of qubits, then initialize it.
        if self.cost_operator is not None:
            # local imports to avoid circular imports
            from qiskit.opflow import PauliSumOp

            num_qubits = self.cost_operator.num_qubits

            # Mixer is just a sum of single qubit X's on each qubit. Evolving by this operator
            # will simply produce rx's on each qubit.
            mixer_terms = [("I" * left + "X" + "I" * (num_qubits - left - 1),
                            1) for left in range(num_qubits)]
            mixer = PauliSumOp.from_list(mixer_terms)
            return mixer

        # otherwise we cannot provide a default
        return None
Ejemplo n.º 26
0
    def _symmetry_reduce(self, qubit_ops: List[PauliSumOp],
                         suppress_none: bool) -> List[Optional[PauliSumOp]]:

        if self._z2symmetries is None or self._z2symmetries.is_empty():
            tapered_qubit_ops = qubit_ops
        else:
            logger.debug("Checking operators commute with symmetry:")
            symmetry_ops = []
            for symmetry in self._z2symmetries.symmetries:
                symmetry_ops.append(
                    PauliSumOp.from_list([(symmetry.to_label(), 1.0)]))
            commuted = []
            for i, qubit_op in enumerate(qubit_ops):
                commutes = QubitConverter._check_commutes(
                    symmetry_ops, qubit_op)
                commuted.append(commutes)
                logger.debug("Qubit operators commuted with symmetry %s",
                             commuted)

            # Tapering values were set from prior convert so we go ahead and taper operators
            tapered_qubit_ops = []
            for i, commutes in enumerate(commuted):
                if commutes:
                    tapered_qubit_ops.append(
                        self._z2symmetries.taper(qubit_ops[i]))
                elif not suppress_none:
                    tapered_qubit_ops.append(None)

        return tapered_qubit_ops
Ejemplo n.º 27
0
 def test_taper_empty_operator(self):
     """Test tapering of empty operator"""
     z2_symmetries = Z2Symmetries(
         symmetries=[Pauli("IIZI"),
                     Pauli("IZIZ"),
                     Pauli("ZIII")],
         sq_paulis=[Pauli("IIXI"),
                    Pauli("IIIX"),
                    Pauli("XIII")],
         sq_list=[1, 0, 3],
         tapering_values=[1, -1, -1],
     )
     empty_op = PauliSumOp.from_list([("IIII", 0.0)])
     tapered_op = z2_symmetries.taper(empty_op)
     expected_op = PauliSumOp.from_list([("I", 0.0)])
     self.assertEqual(tapered_op, expected_op)
Ejemplo n.º 28
0
    def _get_operator(self, weight_matrix):
        """Generate Hamiltonian for the max-cut problem of a graph.

        Args:
            weight_matrix (numpy.ndarray) : adjacency matrix.

        Returns:
            PauliSumOp: operator for the Hamiltonian
            float: a constant shift for the obj function.

        """
        num_nodes = weight_matrix.shape[0]
        pauli_list = []
        shift = 0
        for i in range(num_nodes):
            for j in range(i):
                if weight_matrix[i, j] != 0:
                    x_p = np.zeros(num_nodes, dtype=bool)
                    z_p = np.zeros(num_nodes, dtype=bool)
                    z_p[i] = True
                    z_p[j] = True
                    pauli_list.append(
                        [0.5 * weight_matrix[i, j],
                         Pauli((z_p, x_p))])
                    shift -= 0.5 * weight_matrix[i, j]
        opflow_list = [(pauli[1].to_label(), pauli[0]) for pauli in pauli_list]
        return PauliSumOp.from_list(opflow_list), shift
    def test_find_Z2_symmetries(self):
        """test for find_Z2_symmetries"""

        qubit_op = PauliSumOp.from_list([
            ("II", -1.0537076071291125),
            ("IZ", 0.393983679438514),
            ("ZI", -0.39398367943851387),
            ("ZZ", -0.01123658523318205),
            ("XX", 0.1812888082114961),
        ])
        z2_symmetries = Z2Symmetries.find_Z2_symmetries(qubit_op)
        self.assertEqual(z2_symmetries.symmetries, [Pauli("ZZ")])
        self.assertEqual(z2_symmetries.sq_paulis, [Pauli("IX")])
        self.assertEqual(z2_symmetries.sq_list, [0])
        self.assertEqual(z2_symmetries.tapering_values, None)

        tapered_op = z2_symmetries.taper(qubit_op)[1]
        self.assertEqual(tapered_op.z2_symmetries.symmetries, [Pauli("ZZ")])
        self.assertEqual(tapered_op.z2_symmetries.sq_paulis, [Pauli("IX")])
        self.assertEqual(tapered_op.z2_symmetries.sq_list, [0])
        self.assertEqual(tapered_op.z2_symmetries.tapering_values, [-1])

        z2_symmetries.tapering_values = [-1]
        primitive = SparsePauliOp.from_list([
            ("I", -1.0424710218959303),
            ("Z", -0.7879673588770277),
            ("X", -0.18128880821149604),
        ])
        expected_op = TaperedPauliSumOp(primitive, z2_symmetries)
        self.assertEqual(tapered_op, expected_op)
Ejemplo n.º 30
0
    def setUp(self):
        super().setUp()
        self.ansatz = RealAmplitudes(num_qubits=2, reps=2)
        self.observable = PauliSumOp.from_list([
            ("II", -1.052373245772859),
            ("IZ", 0.39793742484318045),
            ("ZI", -0.39793742484318045),
            ("ZZ", -0.01128010425623538),
            ("XX", 0.18093119978423156),
        ])
        self.expvals = -1.0284380963435145, -1.284366511861733

        self.psi = (RealAmplitudes(num_qubits=2,
                                   reps=2), RealAmplitudes(num_qubits=2,
                                                           reps=3))
        self.params = tuple(psi.parameters for psi in self.psi)
        self.hamiltonian = (
            SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)]),
            SparsePauliOp.from_list([("IZ", 1)]),
            SparsePauliOp.from_list([("ZI", 1), ("ZZ", 1)]),
        )
        self.theta = (
            [0, 1, 1, 2, 3, 5],
            [0, 1, 1, 2, 3, 5, 8, 13],
            [1, 2, 3, 4, 5, 6],
        )