Example #1
0
 def setUp(self) -> None:
     super().setUp()
     self.seed = 97
     backend = Aer.get_backend('qasm_simulator')
     q_instance = QuantumInstance(backend,
                                  seed_simulator=self.seed,
                                  seed_transpiler=self.seed)
     self.sampler = CircuitSampler(q_instance, attach_results=True)
     self.expect = AerPauliExpectation()
    def setUp(self) -> None:
        super().setUp()
        try:
            from qiskit import Aer

            self.seed = 97
            self.backend = Aer.get_backend('qasm_simulator')
            q_instance = QuantumInstance(self.backend, seed_simulator=self.seed,
                                         seed_transpiler=self.seed)
            self.sampler = CircuitSampler(q_instance, attach_results=True)
            self.expect = AerPauliExpectation()
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex)))
            return
Example #3
0
    def test_vqe_expectation_select(self):
        """Test expectation selection with Aer's qasm_simulator."""
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        backend = Aer.get_backend('qasm_simulator')

        with self.subTest('Defaults'):
            vqe = VQE(self.h2_op, quantum_instance=backend)
            self.assertIsInstance(vqe.expectation, PauliExpectation)

        with self.subTest('Include custom'):
            vqe = VQE(self.h2_op,
                      include_custom=True,
                      quantum_instance=backend)
            self.assertIsInstance(vqe.expectation, AerPauliExpectation)

        with self.subTest('Set explicitly'):
            vqe = VQE(self.h2_op,
                      expectation=AerPauliExpectation(),
                      quantum_instance=backend)
            self.assertIsInstance(vqe.expectation, AerPauliExpectation)
Example #4
0
    def test_qasm_snapshot_mode(self):
        """Test the VQE using Aer's qasm_simulator snapshot mode."""
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        backend = Aer.get_backend('qasm_simulator')
        optimizer = L_BFGS_B()
        wavefunction = self.ry_wavefunction

        vqe = VQE(self.h2_op,
                  wavefunction,
                  optimizer,
                  expectation=AerPauliExpectation(),
                  max_evals_grouped=1)

        quantum_instance = QuantumInstance(
            backend,
            shots=1,
            seed_simulator=aqua_globals.random_seed,
            seed_transpiler=aqua_globals.random_seed)
        result = vqe.run(quantum_instance)
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=6)
Example #5
0
def get_exp(H, circ):
    psi = CircuitStateFn(circ)
    backend = Aer.get_backend('statevector_simulator')
    measurable_expression = StateFn(H, is_measurement=True).compose(psi)
    expectation = AerPauliExpectation().convert(measurable_expression)
    sampler = CircuitSampler(backend).convert(expectation)
    return sampler.eval().real
    def test_setters_getters(self):
        """ Test Getter/Setter """

        # quantum instance
        self.assertEqual(self._vqe_uccsd_factory.quantum_instance,
                         self.quantum_instance)
        self._vqe_uccsd_factory.quantum_instance = None
        self.assertEqual(self._vqe_uccsd_factory.quantum_instance, None)

        # optimizer
        self.assertEqual(self._vqe_uccsd_factory.optimizer, None)
        optimizer = COBYLA()
        self._vqe_uccsd_factory.optimizer = optimizer
        self.assertEqual(self._vqe_uccsd_factory.optimizer, optimizer)

        # initial point
        self.assertEqual(self._vqe_uccsd_factory.initial_point, None)
        initial_point = [1, 2, 3]
        self._vqe_uccsd_factory.initial_point = initial_point
        self.assertEqual(self._vqe_uccsd_factory.initial_point, initial_point)

        # expectation
        self.assertEqual(self._vqe_uccsd_factory.expectation, None)
        expectation = AerPauliExpectation()
        self._vqe_uccsd_factory.expectation = expectation
        self.assertEqual(self._vqe_uccsd_factory.expectation, expectation)

        # include_custom
        self.assertEqual(self._vqe_uccsd_factory.include_custom, False)
        self._vqe_uccsd_factory.include_custom = True
        self.assertEqual(self._vqe_uccsd_factory.include_custom, True)

        # method_singles
        self.assertEqual(self._vqe_uccsd_factory.method_singles, 'both')
        self._vqe_uccsd_factory.method_singles = 'alpha'
        self.assertEqual(self._vqe_uccsd_factory.method_singles, 'alpha')

        # method_doubles
        self.assertEqual(self._vqe_uccsd_factory.method_doubles, 'ucc')
        self._vqe_uccsd_factory.method_doubles = 'succ'
        self.assertEqual(self._vqe_uccsd_factory.method_doubles, 'succ')

        # excitation_type
        self.assertEqual(self._vqe_uccsd_factory.excitation_type, 'sd')
        self._vqe_uccsd_factory.excitation_type = 's'
        self.assertEqual(self._vqe_uccsd_factory.excitation_type, 's')

        # same_spin_doubles
        self.assertEqual(self._vqe_uccsd_factory.same_spin_doubles, True)
        self._vqe_uccsd_factory.same_spin_doubles = False
        self.assertEqual(self._vqe_uccsd_factory.same_spin_doubles, False)
Example #7
0
    def test_uccsd_hf_aer_qasm_snapshot(self):
        """ uccsd hf test with Aer qasm_simulator snapshot. """
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(ex)))
            return
        backend = Aer.get_backend('qasm_simulator')
        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(var_form=self.var_form, optimizer=optimizer,
                     expectation=AerPauliExpectation(),
                     quantum_instance=QuantumInstance(backend=backend))

        gsc = GroundStateEigensolver(self.fermionic_transformation, solver)

        result = gsc.solve(self.driver)
        self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=3)
Example #8
0
 def test_uccsd_hf_aer_qasm_snapshot(self):
     """ uccsd hf test with Aer qasm_simulator snapshot. """
     try:
         # pylint: disable=import-outside-toplevel
         from qiskit import Aer
     except Exception as ex:  # pylint: disable=broad-except
         self.skipTest(
             "Aer doesn't appear to be installed. Error: '{}'".format(
                 str(ex)))
         return
     backend = Aer.get_backend('qasm_simulator')
     algo = VQE(self.qubit_op,
                self.var_form,
                self.optimizer,
                expectation=AerPauliExpectation())
     result = algo.run(QuantumInstance(backend))
     result = self.core.process_algorithm_result(result)
     self.assertAlmostEqual(result.energy, self.reference_energy, places=6)
Example #9
0
 def setUp(self) -> None:
     super().setUp()
     backend = Aer.get_backend('qasm_simulator')
     self.sampler = CircuitSampler(backend, attach_results=True)
     self.expect = AerPauliExpectation()
Example #10
0
class TestAerPauliExpectation(QiskitAquaTestCase):
    """Pauli Change of Basis Expectation tests."""
    def setUp(self) -> None:
        super().setUp()
        backend = Aer.get_backend('qasm_simulator')
        self.sampler = CircuitSampler(backend, attach_results=True)
        self.expect = AerPauliExpectation()

    def test_pauli_expect_pair(self):
        """ pauli expect pair test """
        op = (Z ^ Z)
        # wf = (Pl^Pl) + (Ze^Ze)
        wf = CX @ (H ^ I) @ Zero

        converted_meas = self.expect.convert(~StateFn(op) @ wf)
        sampled = self.sampler.convert(converted_meas)
        self.assertAlmostEqual(sampled.eval(), 0, delta=.1)

    def test_pauli_expect_single(self):
        """ pauli expect single test """
        # TODO bug in Aer with Y measurements
        # paulis = [Z, X, Y, I]
        paulis = [Z, X, I]
        states = [Zero, One, Plus, Minus, S @ Plus, S @ Minus]
        for pauli, state in itertools.product(paulis, states):
            converted_meas = self.expect.convert(~StateFn(pauli) @ state)
            matmulmean = state.adjoint().to_matrix() @ pauli.to_matrix(
            ) @ state.to_matrix()
            sampled = self.sampler.convert(converted_meas)
            self.assertAlmostEqual(sampled.eval(), matmulmean, delta=.1)

    def test_pauli_expect_op_vector(self):
        """ pauli expect op vector test """
        paulis_op = ListOp([X, Y, Z, I])
        converted_meas = self.expect.convert(~StateFn(paulis_op))

        plus_mean = (converted_meas @ Plus)
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1],
                                             decimal=1)

        minus_mean = (converted_meas @ Minus)
        sampled_minus = self.sampler.convert(minus_mean)
        np.testing.assert_array_almost_equal(sampled_minus.eval(),
                                             [-1, 0, 0, 1],
                                             decimal=1)

        zero_mean = (converted_meas @ Zero)
        sampled_zero = self.sampler.convert(zero_mean)
        # TODO bug with Aer's Y
        np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 1, 1, 1],
                                             decimal=1)

        sum_zero = (Plus + Minus) * (.5**.5)
        sum_zero_mean = (converted_meas @ sum_zero)
        sampled_zero_mean = self.sampler.convert(sum_zero_mean)
        # !!NOTE!!: Depolarizing channel (Sampling) means interference
        # does not happen between circuits in sum, so expectation does
        # not equal expectation for Zero!!
        np.testing.assert_array_almost_equal(sampled_zero_mean.eval(),
                                             [0, 0, 0, 2],
                                             decimal=1)

    def test_pauli_expect_state_vector(self):
        """ pauli expect state vector test """
        states_op = ListOp([One, Zero, Plus, Minus])

        paulis_op = X
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        sampled = self.sampler.convert(converted_meas)

        # Small test to see if execution results are accessible
        for composed_op in sampled:
            self.assertIn('counts', composed_op[0].execution_results)

        np.testing.assert_array_almost_equal(sampled.eval(), [0, 0, 1, -1],
                                             decimal=1)

    def test_pauli_expect_op_vector_state_vector(self):
        """ pauli expect op vector state vector test """
        # TODO Bug in Aer with Y Measurements!!
        # paulis_op = ListOp([X, Y, Z, I])
        paulis_op = ListOp([X, Z, I])
        states_op = ListOp([One, Zero, Plus, Minus])

        valids = [
            [+0, 0, 1, -1],
            # [+0, 0, 0, 0],
            [-1, 1, 0, -0],
            [+1, 1, 1, 1]
        ]
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        sampled = self.sampler.convert(converted_meas)
        np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1)

    def test_multi_representation_ops(self):
        """ Test observables with mixed representations """
        mixed_ops = ListOp([X.to_matrix_op(), H, H + I, X])
        converted_meas = self.expect.convert(~StateFn(mixed_ops))

        plus_mean = (converted_meas @ Plus)
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(),
                                             [1, .5**.5, (1 + .5**.5), 1],
                                             decimal=1)

    def test_parameterized_qobj(self):
        """ Test direct-to-aer parameter passing in Qobj header. """
        pass
Example #11
0
 def test_unsupported_expectation(self):
     """Assert passing an AerPauliExpectation raises an error."""
     expecation = AerPauliExpectation()
     with self.assertRaises(NotImplementedError):
         _ = CVaRExpectation(alpha=1, expectation=expecation)
class TestAerPauliExpectation(QiskitAquaTestCase):
    """Pauli Change of Basis Expectation tests."""
    def setUp(self) -> None:
        super().setUp()
        try:
            from qiskit import Aer

            self.seed = 97
            self.backend = Aer.get_backend('qasm_simulator')
            q_instance = QuantumInstance(self.backend,
                                         seed_simulator=self.seed,
                                         seed_transpiler=self.seed)
            self.sampler = CircuitSampler(q_instance, attach_results=True)
            self.expect = AerPauliExpectation()
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return

    def test_pauli_expect_pair(self):
        """ pauli expect pair test """
        op = (Z ^ Z)
        # wvf = (Pl^Pl) + (Ze^Ze)
        wvf = CX @ (H ^ I) @ Zero

        converted_meas = self.expect.convert(~StateFn(op) @ wvf)
        sampled = self.sampler.convert(converted_meas)
        self.assertAlmostEqual(sampled.eval(), 0, delta=.1)

    def test_pauli_expect_single(self):
        """ pauli expect single test """
        # TODO bug in Aer with Y measurements
        # paulis = [Z, X, Y, I]
        paulis = [Z, X, I]
        states = [Zero, One, Plus, Minus, S @ Plus, S @ Minus]
        for pauli, state in itertools.product(paulis, states):
            converted_meas = self.expect.convert(~StateFn(pauli) @ state)
            matmulmean = state.adjoint().to_matrix() @ pauli.to_matrix(
            ) @ state.to_matrix()
            sampled = self.sampler.convert(converted_meas)
            self.assertAlmostEqual(sampled.eval(), matmulmean, delta=.1)

    def test_pauli_expect_op_vector(self):
        """ pauli expect op vector test """
        paulis_op = ListOp([X, Y, Z, I])
        converted_meas = self.expect.convert(~StateFn(paulis_op))

        plus_mean = (converted_meas @ Plus)
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(), [1, 0, 0, 1],
                                             decimal=1)

        minus_mean = (converted_meas @ Minus)
        sampled_minus = self.sampler.convert(minus_mean)
        np.testing.assert_array_almost_equal(sampled_minus.eval(),
                                             [-1, 0, 0, 1],
                                             decimal=1)

        zero_mean = (converted_meas @ Zero)
        sampled_zero = self.sampler.convert(zero_mean)
        np.testing.assert_array_almost_equal(sampled_zero.eval(), [0, 0, 1, 1],
                                             decimal=1)

        sum_zero = (Plus + Minus) * (.5**.5)
        sum_zero_mean = (converted_meas @ sum_zero)
        sampled_zero_mean = self.sampler.convert(sum_zero_mean)
        # !!NOTE!!: Depolarizing channel (Sampling) means interference
        # does not happen between circuits in sum, so expectation does
        # not equal expectation for Zero!!
        np.testing.assert_array_almost_equal(sampled_zero_mean.eval(),
                                             [0, 0, 0, 2],
                                             decimal=1)

    def test_pauli_expect_state_vector(self):
        """ pauli expect state vector test """
        states_op = ListOp([One, Zero, Plus, Minus])

        paulis_op = X
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        sampled = self.sampler.convert(converted_meas)

        # Small test to see if execution results are accessible
        for composed_op in sampled:
            self.assertIn('counts', composed_op[0].execution_results)

        np.testing.assert_array_almost_equal(sampled.eval(), [0, 0, 1, -1],
                                             decimal=1)

    def test_pauli_expect_op_vector_state_vector(self):
        """ pauli expect op vector state vector test """
        # TODO Bug in Aer with Y Measurements!!
        # paulis_op = ListOp([X, Y, Z, I])
        paulis_op = ListOp([X, Z, I])
        states_op = ListOp([One, Zero, Plus, Minus])

        valids = [
            [+0, 0, 1, -1],
            # [+0, 0, 0, 0],
            [-1, 1, 0, -0],
            [+1, 1, 1, 1]
        ]
        converted_meas = self.expect.convert(~StateFn(paulis_op) @ states_op)
        sampled = self.sampler.convert(converted_meas)
        np.testing.assert_array_almost_equal(sampled.eval(), valids, decimal=1)

    def test_multi_representation_ops(self):
        """ Test observables with mixed representations """
        mixed_ops = ListOp([X.to_matrix_op(), H, H + I, X])
        converted_meas = self.expect.convert(~StateFn(mixed_ops))

        plus_mean = (converted_meas @ Plus)
        sampled_plus = self.sampler.convert(plus_mean)
        np.testing.assert_array_almost_equal(sampled_plus.eval(),
                                             [1, .5**.5, (1 + .5**.5), 1],
                                             decimal=1)

    def test_parameterized_qobj(self):
        """ grouped pauli expectation test """
        two_qubit_h2 = (-1.052373245772859 * I ^ I) + \
                       (0.39793742484318045 * I ^ Z) + \
                       (-0.39793742484318045 * Z ^ I) + \
                       (-0.01128010425623538 * Z ^ Z) + \
                       (0.18093119978423156 * X ^ X)

        aer_sampler = CircuitSampler(self.sampler.quantum_instance,
                                     param_qobj=True,
                                     attach_results=True)

        var_form = RealAmplitudes()
        var_form.num_qubits = 2

        observable_meas = self.expect.convert(
            StateFn(two_qubit_h2, is_measurement=True))
        ansatz_circuit_op = CircuitStateFn(var_form)
        expect_op = observable_meas.compose(ansatz_circuit_op).reduce()

        def generate_parameters(num):
            param_bindings = {}
            for param in var_form.parameters:
                values = []
                for _ in range(num):
                    values.append(np.random.rand())
                param_bindings[param] = values
            return param_bindings

        def validate_sampler(ideal, sut, param_bindings):
            expect_sampled = ideal.convert(expect_op,
                                           params=param_bindings).eval()
            actual_sampled = sut.convert(expect_op,
                                         params=param_bindings).eval()
            self.assertAlmostEqual(actual_sampled, expect_sampled, delta=.1)

        def get_circuit_templates(sampler):
            return sampler._transpiled_circ_templates

        def validate_aer_binding_used(templates):
            self.assertIsNotNone(templates)

        def validate_aer_templates_reused(prev_templates, cur_templates):
            self.assertIs(prev_templates, cur_templates)

        validate_sampler(self.sampler, aer_sampler, generate_parameters(1))
        cur_templates = get_circuit_templates(aer_sampler)

        validate_aer_binding_used(cur_templates)

        prev_templates = cur_templates
        validate_sampler(self.sampler, aer_sampler, generate_parameters(2))
        cur_templates = get_circuit_templates(aer_sampler)

        validate_aer_templates_reused(prev_templates, cur_templates)

        prev_templates = cur_templates
        validate_sampler(self.sampler, aer_sampler,
                         generate_parameters(2))  # same num of params
        cur_templates = get_circuit_templates(aer_sampler)

        validate_aer_templates_reused(prev_templates, cur_templates)

    def test_pauli_expectation_param_qobj(self):
        """ Test PauliExpectation with param_qobj """
        q_instance = QuantumInstance(self.backend,
                                     seed_simulator=self.seed,
                                     seed_transpiler=self.seed,
                                     shots=20000)
        qubit_op = (1 * I ^ I) + (2 * I ^ Z) + (3 * Z ^ I) + (4 * Z ^ Z) + (
            5 * X ^ X)
        var_form = RealAmplitudes(qubit_op.num_qubits)
        ansatz_circuit_op = CircuitStateFn(var_form)
        observable = PauliExpectation().convert(~StateFn(qubit_op))
        expect_op = observable.compose(ansatz_circuit_op).reduce()
        params1 = {}
        params2 = {}
        for param in var_form.parameters:
            params1[param] = [0]
            params2[param] = [0, 0]

        sampler1 = CircuitSampler(backend=q_instance, param_qobj=False)
        samples1 = sampler1.convert(expect_op, params=params1)
        val1 = np.real(samples1.eval())[0]
        samples2 = sampler1.convert(expect_op, params=params2)
        val2 = np.real(samples2.eval())
        sampler2 = CircuitSampler(backend=q_instance, param_qobj=True)
        samples3 = sampler2.convert(expect_op, params=params1)
        val3 = np.real(samples3.eval())
        samples4 = sampler2.convert(expect_op, params=params2)
        val4 = np.real(samples4.eval())

        np.testing.assert_array_almost_equal([val1] * 2, val2, decimal=2)
        np.testing.assert_array_almost_equal(val1, val3, decimal=2)
        np.testing.assert_array_almost_equal([val1] * 2, val4, decimal=2)
Example #13
0
class TestVQE(QiskitAquaTestCase):
    """ Test VQE """
    def setUp(self):
        super().setUp()
        self.seed = 50
        aqua_globals.random_seed = self.seed
        self.h2_op = -1.052373245772859 * (I ^ I) \
            + 0.39793742484318045 * (I ^ Z) \
            - 0.39793742484318045 * (Z ^ I) \
            - 0.01128010425623538 * (Z ^ Z) \
            + 0.18093119978423156 * (X ^ X)
        self.h2_energy = -1.85727503

        self.ryrz_wavefunction = TwoLocal(rotation_blocks=['ry', 'rz'],
                                          entanglement_blocks='cz')
        self.ry_wavefunction = TwoLocal(rotation_blocks='ry',
                                        entanglement_blocks='cz')

        self.qasm_simulator = QuantumInstance(
            BasicAer.get_backend('qasm_simulator'),
            shots=1024,
            seed_simulator=self.seed,
            seed_transpiler=self.seed)
        self.statevector_simulator = QuantumInstance(
            BasicAer.get_backend('statevector_simulator'),
            shots=1,
            seed_simulator=self.seed,
            seed_transpiler=self.seed)

    def test_basic_aer_statevector(self):
        """Test the VQE on BasicAer's statevector simulator."""
        wavefunction = self.ryrz_wavefunction
        vqe = VQE(self.h2_op, wavefunction, L_BFGS_B())

        result = vqe.run(
            QuantumInstance(BasicAer.get_backend('statevector_simulator'),
                            basis_gates=['u1', 'u2', 'u3', 'cx', 'id'],
                            coupling_map=[[0, 1]],
                            seed_simulator=aqua_globals.random_seed,
                            seed_transpiler=aqua_globals.random_seed))

        with self.subTest(msg='test eigenvalue'):
            self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy)

        with self.subTest(msg='test dimension of optimal point'):
            self.assertEqual(len(result.optimal_point), 16)

        with self.subTest(msg='assert cost_function_evals is set'):
            self.assertIsNotNone(result.cost_function_evals)

        with self.subTest(msg='assert optimizer_time is set'):
            self.assertIsNotNone(result.optimizer_time)

    def test_circuit_input(self):
        """Test running the VQE on a plain QuantumCircuit object."""
        wavefunction = QuantumCircuit(2).compose(EfficientSU2(2))
        optimizer = SLSQP(maxiter=50)
        vqe = VQE(self.h2_op, wavefunction, optimizer=optimizer)
        result = vqe.run(self.statevector_simulator)
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=5)

    @data(
        (MatrixExpectation(), 1),
        (AerPauliExpectation(), 1),
        (PauliExpectation(), 2),
    )
    @unpack
    def test_construct_circuit(self, expectation, num_circuits):
        """Test construct circuits returns QuantumCircuits and the right number of them."""
        wavefunction = EfficientSU2(2, reps=1)
        vqe = VQE(self.h2_op, wavefunction, expectation=expectation)
        params = [0] * wavefunction.num_parameters
        circuits = vqe.construct_circuit(params)

        self.assertEqual(len(circuits), num_circuits)
        for circuit in circuits:
            self.assertIsInstance(circuit, QuantumCircuit)

    def test_legacy_operator(self):
        """Test the VQE accepts and converts the legacy WeightedPauliOperator."""
        pauli_dict = {
            'paulis': [{
                "coeff": {
                    "imag": 0.0,
                    "real": -1.052373245772859
                },
                "label": "II"
            }, {
                "coeff": {
                    "imag": 0.0,
                    "real": 0.39793742484318045
                },
                "label": "IZ"
            }, {
                "coeff": {
                    "imag": 0.0,
                    "real": -0.39793742484318045
                },
                "label": "ZI"
            }, {
                "coeff": {
                    "imag": 0.0,
                    "real": -0.01128010425623538
                },
                "label": "ZZ"
            }, {
                "coeff": {
                    "imag": 0.0,
                    "real": 0.18093119978423156
                },
                "label": "XX"
            }]
        }
        h2_op = WeightedPauliOperator.from_dict(pauli_dict)
        vqe = VQE(h2_op)
        self.assertEqual(vqe.operator, self.h2_op)

    def test_missing_varform_params(self):
        """Test specifying a variational form with no parameters raises an error."""
        circuit = QuantumCircuit(self.h2_op.num_qubits)
        vqe = VQE(self.h2_op, circuit)
        with self.assertRaises(RuntimeError):
            vqe.run(BasicAer.get_backend('statevector_simulator'))

    @data(
        (SLSQP(maxiter=50), 5, 4),
        (SPSA(maxiter=150), 3, 2),  # max_evals_grouped=n or =2 if n>2
    )
    @unpack
    def test_max_evals_grouped(self, optimizer, places, max_evals_grouped):
        """ VQE Optimizers test """
        vqe = VQE(self.h2_op,
                  self.ryrz_wavefunction,
                  optimizer,
                  max_evals_grouped=max_evals_grouped,
                  quantum_instance=self.statevector_simulator)
        result = vqe.run()
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=places)

    def test_basic_aer_qasm(self):
        """Test the VQE on BasicAer's QASM simulator."""
        optimizer = SPSA(maxiter=300, last_avg=5)
        wavefunction = self.ry_wavefunction

        vqe = VQE(self.h2_op, wavefunction, optimizer, max_evals_grouped=1)

        # TODO benchmark this later.
        result = vqe.run(self.qasm_simulator)
        self.assertAlmostEqual(result.eigenvalue.real, -1.86823, places=2)

    def test_with_aer_statevector(self):
        """Test VQE with Aer's statevector_simulator."""
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        backend = Aer.get_backend('statevector_simulator')
        wavefunction = self.ry_wavefunction
        optimizer = L_BFGS_B()

        vqe = VQE(self.h2_op, wavefunction, optimizer, max_evals_grouped=1)

        quantum_instance = QuantumInstance(
            backend,
            seed_simulator=aqua_globals.random_seed,
            seed_transpiler=aqua_globals.random_seed)
        result = vqe.run(quantum_instance)
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=6)

    def test_with_aer_qasm(self):
        """Test VQE with Aer's qasm_simulator."""
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        backend = Aer.get_backend('qasm_simulator')
        optimizer = SPSA(maxiter=200, last_avg=5)
        wavefunction = self.ry_wavefunction

        vqe = VQE(self.h2_op,
                  wavefunction,
                  optimizer,
                  expectation=PauliExpectation())

        quantum_instance = QuantumInstance(
            backend,
            seed_simulator=aqua_globals.random_seed,
            seed_transpiler=aqua_globals.random_seed)
        result = vqe.run(quantum_instance)
        self.assertAlmostEqual(result.eigenvalue.real, -1.86305, places=2)

    def test_with_aer_qasm_snapshot_mode(self):
        """Test the VQE using Aer's qasm_simulator snapshot mode."""
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        backend = Aer.get_backend('qasm_simulator')
        optimizer = L_BFGS_B()
        wavefunction = self.ry_wavefunction

        vqe = VQE(self.h2_op,
                  wavefunction,
                  optimizer,
                  expectation=AerPauliExpectation())

        quantum_instance = QuantumInstance(
            backend,
            shots=1,
            seed_simulator=aqua_globals.random_seed,
            seed_transpiler=aqua_globals.random_seed)
        result = vqe.run(quantum_instance)
        self.assertAlmostEqual(result.eigenvalue.real,
                               self.h2_energy,
                               places=6)

    def test_callback(self):
        """Test the callback on VQE."""
        history = {'eval_count': [], 'parameters': [], 'mean': [], 'std': []}

        def store_intermediate_result(eval_count, parameters, mean, std):
            history['eval_count'].append(eval_count)
            history['parameters'].append(parameters)
            history['mean'].append(mean)
            history['std'].append(std)

        optimizer = COBYLA(maxiter=3)
        wavefunction = self.ry_wavefunction

        vqe = VQE(self.h2_op,
                  wavefunction,
                  optimizer,
                  callback=store_intermediate_result)
        vqe.run(self.qasm_simulator)

        self.assertTrue(
            all(isinstance(count, int) for count in history['eval_count']))
        self.assertTrue(
            all(isinstance(mean, float) for mean in history['mean']))
        self.assertTrue(all(isinstance(std, float) for std in history['std']))
        for params in history['parameters']:
            self.assertTrue(all(isinstance(param, float) for param in params))

    def test_reuse(self):
        """Test re-using a VQE algorithm instance."""
        vqe = VQE()
        with self.subTest(msg='assert running empty raises AquaError'):
            with self.assertRaises(AquaError):
                _ = vqe.run()

        var_form = TwoLocal(rotation_blocks=['ry', 'rz'],
                            entanglement_blocks='cz')
        vqe.var_form = var_form
        with self.subTest(msg='assert missing operator raises AquaError'):
            with self.assertRaises(AquaError):
                _ = vqe.run()

        vqe.operator = self.h2_op
        with self.subTest(msg='assert missing backend raises AquaError'):
            with self.assertRaises(AquaError):
                _ = vqe.run()

        vqe.quantum_instance = self.statevector_simulator
        with self.subTest(msg='assert VQE works once all info is available'):
            result = vqe.run()
            self.assertAlmostEqual(result.eigenvalue.real,
                                   self.h2_energy,
                                   places=5)

        operator = PrimitiveOp(
            np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0,
                                                                  3]]))

        with self.subTest(msg='assert minimum eigensolver interface works'):
            result = vqe.compute_minimum_eigenvalue(operator)
            self.assertAlmostEqual(result.eigenvalue.real, -1.0, places=5)

    def test_vqe_optimizer(self):
        """ Test running same VQE twice to re-use optimizer, then switch optimizer """
        vqe = VQE(self.h2_op,
                  optimizer=SLSQP(),
                  quantum_instance=QuantumInstance(
                      BasicAer.get_backend('statevector_simulator')))

        def run_check():
            result = vqe.compute_minimum_eigenvalue()
            self.assertAlmostEqual(result.eigenvalue.real,
                                   -1.85727503,
                                   places=5)

        run_check()

        with self.subTest('Optimizer re-use'):
            run_check()

        with self.subTest('Optimizer replace'):
            vqe.optimizer = L_BFGS_B()
            run_check()

    def test_vqe_expectation_select(self):
        """Test expectation selection with Aer's qasm_simulator."""
        try:
            # pylint: disable=import-outside-toplevel
            from qiskit import Aer
        except Exception as ex:  # pylint: disable=broad-except
            self.skipTest(
                "Aer doesn't appear to be installed. Error: '{}'".format(
                    str(ex)))
            return
        backend = Aer.get_backend('qasm_simulator')

        with self.subTest('Defaults'):
            vqe = VQE(self.h2_op, quantum_instance=backend)
            self.assertIsInstance(vqe.expectation, PauliExpectation)

        with self.subTest('Include custom'):
            vqe = VQE(self.h2_op,
                      include_custom=True,
                      quantum_instance=backend)
            self.assertIsInstance(vqe.expectation, AerPauliExpectation)

        with self.subTest('Set explicitly'):
            vqe = VQE(self.h2_op,
                      expectation=AerPauliExpectation(),
                      quantum_instance=backend)
            self.assertIsInstance(vqe.expectation, AerPauliExpectation)

    @unittest.skip(reason="IBMQ testing not available in general.")
    def test_ibmq(self):
        """ IBMQ VQE Test """
        from qiskit import IBMQ
        provider = IBMQ.load_account()
        backend = provider.get_backend('ibmq_qasm_simulator')
        ansatz = TwoLocal(rotation_blocks=['ry', 'rz'],
                          entanglement_blocks='cz')

        opt = SLSQP(maxiter=1)
        opt.set_max_evals_grouped(100)
        vqe = VQE(self.h2_op, ansatz, SLSQP(maxiter=2))

        result = vqe.run(backend)
        print(result)
        self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy)
        np.testing.assert_array_almost_equal(result.eigenvalue.real,
                                             self.h2_energy, 5)
        self.assertEqual(len(result.optimal_point), 16)
        self.assertIsNotNone(result.cost_function_evals)
        self.assertIsNotNone(result.optimizer_time)

    @data(MatrixExpectation(), None)
    def test_backend_change(self, user_expectation):
        """Test that VQE works when backend changes."""
        vqe = VQE(
            operator=self.h2_op,
            var_form=TwoLocal(rotation_blocks=['ry', 'rz'],
                              entanglement_blocks='cz'),
            optimizer=SLSQP(maxiter=2),
            expectation=user_expectation,
            quantum_instance=BasicAer.get_backend('statevector_simulator'))
        result0 = vqe.run()
        if user_expectation is not None:
            with self.subTest('User expectation kept.'):
                self.assertEqual(vqe.expectation, user_expectation)
        else:
            with self.subTest('Expectation created.'):
                self.assertIsInstance(vqe.expectation, ExpectationBase)
        try:
            vqe.set_backend(BasicAer.get_backend('qasm_simulator'))
        except Exception as ex:  # pylint: disable=broad-except
            self.fail("Failed to change backend. Error: '{}'".format(str(ex)))
            return

        result1 = vqe.run()
        if user_expectation is not None:
            with self.subTest(
                    'Change backend with user expectation, it is kept.'):
                self.assertEqual(vqe.expectation, user_expectation)
        else:
            with self.subTest(
                    'Change backend without user expectation, one created.'):
                self.assertIsInstance(vqe.expectation, ExpectationBase)

        with self.subTest('Check results.'):
            self.assertEqual(len(result0.optimal_point),
                             len(result1.optimal_point))