def test_z2_symmetry(self):
        """Test mapping to qubit operator with z2 symmetry tapering"""
        z2_sector = [-1, 1, -1]

        def cb_finder(z2_symmetries: Z2Symmetries,
                      converter: QubitConverter) -> Optional[List[int]]:
            return z2_sector if not z2_symmetries.is_empty() else None

        def cb_find_none(_z2_symmetries: Z2Symmetries,
                         converter: QubitConverter) -> Optional[List[int]]:
            return None

        mapper = JordanWignerMapper()
        qubit_conv = QubitConverter(mapper, z2symmetry_reduction="auto")

        with self.subTest(
                "Locator returns None, should be untapered operator"):
            qubit_op = qubit_conv.convert(self.h2_op,
                                          sector_locator=cb_find_none)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        qubit_op = qubit_conv.convert(self.h2_op, sector_locator=cb_finder)
        self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW_TAPERED)
            self.assertIsNone(qubit_conv.num_particles)
            self.assertListEqual(qubit_conv.z2symmetries.tapering_values,
                                 z2_sector)
    def test_two_qubit_reduction_and_z2_symmetry(self):
        """Test mapping to qubit operator with z2 symmetry tapering and two qubit reduction"""
        z2_sector = [-1]

        def cb_finder(z2_symmetries: Z2Symmetries,
                      converter: QubitConverter) -> Optional[List[int]]:
            return z2_sector if not z2_symmetries.is_empty() else None

        mapper = ParityMapper()
        qubit_conv = QubitConverter(mapper,
                                    two_qubit_reduction=True,
                                    z2symmetry_reduction="auto")
        qubit_op = qubit_conv.convert(self.h2_op,
                                      self.num_particles,
                                      sector_locator=cb_finder)
        self.assertEqual(qubit_op,
                         TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)
        self.assertEqual(qubit_conv.num_particles, self.num_particles)
        self.assertListEqual(qubit_conv.z2symmetries.tapering_values,
                             z2_sector)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)
            self.assertListEqual(qubit_conv.z2symmetries.tapering_values,
                                 z2_sector)

        with self.subTest("Change setting"):
            qubit_conv.z2symmetry_reduction = [1]
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertNotEqual(
                qubit_op, TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)
            qubit_conv.z2symmetry_reduction = [-1]
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)

        with self.subTest("Specify sector upfront"):
            qubit_conv = QubitConverter(mapper,
                                        two_qubit_reduction=True,
                                        z2symmetry_reduction=z2_sector)
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED_TAPER)

        with self.subTest("Specify sector upfront, but invalid content"):
            with self.assertRaises(ValueError):
                _ = QubitConverter(mapper,
                                   two_qubit_reduction=True,
                                   z2symmetry_reduction=[5])

        with self.subTest("Specify sector upfront, but invalid length"):
            qubit_conv = QubitConverter(mapper,
                                        two_qubit_reduction=True,
                                        z2symmetry_reduction=[-1, 1])
            with self.assertRaises(QiskitNatureError):
                _ = qubit_conv.convert(self.h2_op, self.num_particles)
Example #3
0
    def test_uvcc_vscf(self):
        """uvcc vscf test"""

        co2_2modes_2modals_2body = [
            [
                [[[0, 0, 0]], 320.8467332810141],
                [[[0, 1, 1]], 1760.878530705873],
                [[[1, 0, 0]], 342.8218290247543],
                [[[1, 1, 1]], 1032.396323618631],
            ],
            [
                [[[0, 0, 0], [1, 0, 0]], -57.34003649795117],
                [[[0, 0, 1], [1, 0, 0]], -56.33205925807966],
                [[[0, 1, 0], [1, 0, 0]], -56.33205925807966],
                [[[0, 1, 1], [1, 0, 0]], -60.13032761856809],
                [[[0, 0, 0], [1, 0, 1]], -65.09576309934431],
                [[[0, 0, 1], [1, 0, 1]], -62.2363839133389],
                [[[0, 1, 0], [1, 0, 1]], -62.2363839133389],
                [[[0, 1, 1], [1, 0, 1]], -121.5533969109279],
                [[[0, 0, 0], [1, 1, 0]], -65.09576309934431],
                [[[0, 0, 1], [1, 1, 0]], -62.2363839133389],
                [[[0, 1, 0], [1, 1, 0]], -62.2363839133389],
                [[[0, 1, 1], [1, 1, 0]], -121.5533969109279],
                [[[0, 0, 0], [1, 1, 1]], -170.744837386338],
                [[[0, 0, 1], [1, 1, 1]], -167.7433236025723],
                [[[0, 1, 0], [1, 1, 1]], -167.7433236025723],
                [[[0, 1, 1], [1, 1, 1]], -179.0536532281924],
            ],
        ]
        num_modes = 2
        num_modals = [2, 2]

        vibrational_op_labels = _create_labels(co2_2modes_2modals_2body)
        vibr_op = VibrationalOp(vibrational_op_labels, num_modes, num_modals)

        converter = QubitConverter(DirectMapper())

        qubit_op = converter.convert_match(vibr_op)

        init_state = VSCF(num_modals)

        uvcc_ansatz = UVCC(converter, num_modals, "sd", initial_state=init_state)

        q_instance = QuantumInstance(
            BasicAer.get_backend("statevector_simulator"),
            seed_transpiler=90,
            seed_simulator=12,
        )
        optimizer = COBYLA(maxiter=1000)

        algo = VQE(uvcc_ansatz, optimizer=optimizer, quantum_instance=q_instance)
        vqe_result = algo.compute_minimum_eigenvalue(qubit_op)

        energy = vqe_result.optimal_value

        self.assertAlmostEqual(energy, self.reference_energy, places=4)
    def test_two_qubit_reduction(self):
        """Test mapping to qubit operator with two qubit reduction"""
        mapper = ParityMapper()
        qubit_conv = QubitConverter(mapper, two_qubit_reduction=True)

        with self.subTest(
                "Two qubit reduction ignored as no num particles given"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest("Two qubit reduction, num particles given"):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
            self.assertEqual(qubit_conv.num_particles, self.num_particles)

        with self.subTest("State is reset (Num particles lost)"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)
            self.assertIsNone(qubit_conv.num_particles)

        with self.subTest("Num particles given again"):
            qubit_op = qubit_conv.convert(self.h2_op, self.num_particles)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)

        with self.subTest("Set for no two qubit reduction"):
            qubit_conv.two_qubit_reduction = False
            self.assertFalse(qubit_conv.two_qubit_reduction)
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)

        # Regression test against https://github.com/Qiskit/qiskit-nature/issues/271
        with self.subTest(
                "Two qubit reduction skipped when operator too small"):
            qubit_conv.two_qubit_reduction = True
            small_op = FermionicOp([("N_0", 1.0), ("E_1", 1.0)],
                                   register_length=2,
                                   display_format="sparse")
            expected_op = 1.0 * (I ^ I) - 0.5 * (I ^ Z) + 0.5 * (Z ^ Z)
            with contextlib.redirect_stderr(io.StringIO()) as out:
                qubit_op = qubit_conv.convert(small_op,
                                              num_particles=self.num_particles)
            self.assertEqual(qubit_op, expected_op)
            self.assertTrue(out.getvalue().strip().startswith(
                "The original qubit operator only contains 2 qubits! "
                "Skipping the requested two-qubit reduction!"))
    def test_mapping_basic(self):
        """Test mapping to qubit operator"""
        mapper = JordanWignerMapper()
        qubit_conv = QubitConverter(mapper)
        qubit_op = qubit_conv.convert(self.h2_op)

        self.assertIsInstance(qubit_op, PauliSumOp)

        # Note: The PauliSumOp equals, as used in the test below, use the equals of the
        #       SparsePauliOp which in turn uses np.allclose() to determine equality of
        #       coeffs. So the reference operator above will be matched on that basis so
        #       we don't need to worry about tiny precision changes for any reason.

        self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        with self.subTest("Re-use test"):
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        with self.subTest("convert_match()"):
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_JW)

        with self.subTest("Re-use with different mapper"):
            qubit_conv.mapper = ParityMapper()
            qubit_op = qubit_conv.convert(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)

        with self.subTest(
                "Set two qubit reduction - no effect without num particles"):
            qubit_conv.two_qubit_reduction = True
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op, TestQubitConverter.REF_H2_PARITY)

        with self.subTest("Force match set num particles"):
            qubit_conv.force_match(self.num_particles)
            qubit_op = qubit_conv.convert_match(self.h2_op)
            self.assertEqual(qubit_op,
                             TestQubitConverter.REF_H2_PARITY_2Q_REDUCED)
Example #6
0
def _build_single_hopping_operator(
    excitation: Tuple[Tuple[int, ...], Tuple[int, ...]],
    num_modals: List[int],
    qubit_converter: QubitConverter,
) -> PauliSumOp:
    sum_modes = sum(num_modals)

    label = ["I"] * sum_modes
    for occ in excitation[0]:
        label[occ] = "+"
    for unocc in excitation[1]:
        label[unocc] = "-"
    vibrational_op = VibrationalOp("".join(label), len(num_modals), num_modals)
    qubit_op: PauliSumOp = qubit_converter.convert_match(vibrational_op)

    return qubit_op
Example #7
0
    def setUp(self):
        super().setUp()
        algorithm_globals.random_seed = 42

        driver = HDF5Driver(hdf5_input=self.get_resource_path(
            "test_driver_hdf5.hdf5", "second_q/drivers/hdf5d"))
        problem = ElectronicStructureProblem(driver)
        main_op, aux_ops = problem.second_q_ops()
        converter = QubitConverter(mapper=ParityMapper(),
                                   two_qubit_reduction=True)
        num_particles = (
            problem.grouped_property_transformed.get_property(
                "ParticleNumber").num_alpha,
            problem.grouped_property_transformed.get_property(
                "ParticleNumber").num_beta,
        )
        self.qubit_op = converter.convert(main_op, num_particles)
        self.aux_ops = converter.convert_match(aux_ops)
        self.reference_energy = -1.857275027031588
class TestGroundStateEigensolver(QiskitNatureTestCase):
    """Test GroundStateEigensolver"""
    def setUp(self):
        super().setUp()
        self.driver = HDF5Driver(
            self.get_resource_path("test_driver_hdf5.hdf5",
                                   "second_q/drivers/hdf5d"))
        self.seed = 56
        algorithm_globals.random_seed = self.seed

        self.reference_energy = -1.1373060356951838

        self.qubit_converter = QubitConverter(JordanWignerMapper())
        self.electronic_structure_problem = ElectronicStructureProblem(
            self.driver)

        self.num_spin_orbitals = 4
        self.num_particles = (1, 1)

    def test_npme(self):
        """Test NumPyMinimumEigensolver"""
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_npme_with_default_filter(self):
        """Test NumPyMinimumEigensolver with default filter"""
        solver = NumPyMinimumEigensolverFactory(
            use_default_filter_criterion=True)
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_vqe_uccsd(self):
        """Test VQE UCCSD case"""
        solver = VQEUCCFactory(
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator")),
            ansatz=UCC(excitations="d"),
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_vqe_uccsd_with_callback(self):
        """Test VQE UCCSD with callback."""
        def callback(nfev, parameters, energy, stddev):
            # pylint: disable=unused-argument
            print(f"iterations {nfev}: energy: {energy}")

        solver = VQEUCCFactory(
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator")),
            callback=callback,
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        with contextlib.redirect_stdout(io.StringIO()) as out:
            res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)
        for idx, line in enumerate(out.getvalue().split("\n")):
            if line.strip():
                self.assertTrue(
                    line.startswith(f"iterations {idx+1}: energy: "))

    def test_vqe_ucc_custom(self):
        """Test custom ansatz in Factory use case"""
        solver = VQEUCCFactory(quantum_instance=QuantumInstance(
            BasicAer.get_backend("statevector_simulator")))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_aux_ops_reusability(self):
        """Test that the auxiliary operators can be reused"""
        # Regression test against #1475
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)

        modes = 4
        h_1 = np.eye(modes, dtype=complex)
        h_2 = np.zeros((modes, modes, modes, modes))
        aux_ops = list(
            ElectronicEnergy([
                OneBodyElectronicIntegrals(ElectronicBasis.MO, (h_1, None)),
                TwoBodyElectronicIntegrals(ElectronicBasis.MO,
                                           (h_2, None, None, None)),
            ], ).second_q_ops().values())
        aux_ops_copy = copy.deepcopy(aux_ops)

        _ = calc.solve(self.electronic_structure_problem)

        assert all(
            frozenset(a.to_list()) == frozenset(b.to_list())
            for a, b in zip(aux_ops, aux_ops_copy))

    def _setup_evaluation_operators(self):
        # first we run a ground state calculation
        solver = VQEUCCFactory(quantum_instance=QuantumInstance(
            BasicAer.get_backend("statevector_simulator")))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)

        # now we decide that we want to evaluate another operator
        # for testing simplicity, we just use some pre-constructed auxiliary operators
        _, second_q_ops = self.electronic_structure_problem.second_q_ops()
        aux_ops_dict = self.qubit_converter.convert_match(second_q_ops)
        return calc, res, aux_ops_dict

    def test_eval_op_single(self):
        """Test evaluating a single additional operator"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because in this test we test a single operator evaluation
        add_aux_op = aux_ops["ParticleNumber"][0]

        # now we have the ground state calculation evaluate it
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res[0], complex)
        self.assertAlmostEqual(add_aux_op_res[0].real, 2, places=6)

    def test_eval_op_single_none(self):
        """Test evaluating a single `None` operator"""
        calc, res, _ = self._setup_evaluation_operators()
        # we filter the list because in this test we test a single operator evaluation
        add_aux_op = None

        # now we have the ground state calculation evaluate it
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsNone(add_aux_op_res)

    def test_eval_op_list(self):
        """Test evaluating a list of additional operators"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ]

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, list)
        # in this list we require that the order of the results remains unchanged
        for idx, expected in enumerate(expected_results.values()):
            self.assertAlmostEqual(add_aux_op_res[idx][0].real,
                                   expected,
                                   places=6)

    def test_eval_op_list_none(self):
        """Test evaluating a list of additional operators incl. `None`"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ] + [None]

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, list)
        # in this list we require that the order of the results remains unchanged
        for idx, expected in enumerate(expected_results.values()):
            self.assertAlmostEqual(add_aux_op_res[idx][0].real,
                                   expected,
                                   places=6)
        self.assertIsNone(add_aux_op_res[-1])

    def test_eval_op_dict(self):
        """Test evaluating a dict of additional operators"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ]
        # now we convert it into a dictionary
        add_aux_op = dict(zip(expected_results.keys(), add_aux_op))

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, dict)
        for name, expected in expected_results.items():
            self.assertAlmostEqual(add_aux_op_res[name][0].real,
                                   expected,
                                   places=6)

    def test_eval_op_dict_none(self):
        """Test evaluating a dict of additional operators incl. `None`"""
        calc, res, aux_ops = self._setup_evaluation_operators()
        # we filter the list because of simplicity
        expected_results = {
            "number of particles": 2,
            "s^2": 0,
            "magnetization": 0
        }
        add_aux_op = [
            aux_ops["ParticleNumber"],
            aux_ops["AngularMomentum"],
            aux_ops["Magnetization"],
        ]
        # now we convert it into a dictionary
        add_aux_op = dict(zip(expected_results.keys(), add_aux_op))
        add_aux_op["None"] = None

        # now we have the ground state calculation evaluate them
        add_aux_op_res = calc.evaluate_operators(res.raw_result.eigenstate,
                                                 add_aux_op)
        self.assertIsInstance(add_aux_op_res, dict)
        for name, expected in expected_results.items():
            self.assertAlmostEqual(add_aux_op_res[name][0].real,
                                   expected,
                                   places=6)
        self.assertIsNone(add_aux_op_res["None"])

    @slow_test
    def test_eval_op_qasm(self):
        """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53."""
        solver = VQEUCCFactory(
            optimizer=SLSQP(maxiter=100),
            expectation=PauliExpectation(),
            quantum_instance=QuantumInstance(
                backend=BasicAer.get_backend("qasm_simulator"),
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res_qasm = calc.solve(self.electronic_structure_problem)

        hamiltonian, _ = self.electronic_structure_problem.second_q_ops()
        qubit_op = self.qubit_converter.map(hamiltonian)

        ansatz = solver.get_solver(self.electronic_structure_problem,
                                   self.qubit_converter).ansatz
        circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point)
        mean = calc.evaluate_operators(circuit, qubit_op)

        self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)

    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_eval_op_qasm_aer(self):
        """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53."""

        backend = qiskit.providers.aer.Aer.get_backend("aer_simulator")

        solver = VQEUCCFactory(
            optimizer=SLSQP(maxiter=100),
            expectation=AerPauliExpectation(),
            include_custom=True,
            quantum_instance=QuantumInstance(
                backend=backend,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res_qasm = calc.solve(self.electronic_structure_problem)

        hamiltonian, _ = self.electronic_structure_problem.second_q_ops()
        qubit_op = self.qubit_converter.map(hamiltonian)

        ansatz = solver.get_solver(self.electronic_structure_problem,
                                   self.qubit_converter).ansatz
        circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point)
        mean = calc.evaluate_operators(circuit, qubit_op)

        self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)

    def _prepare_uccsd_hf(self, qubit_converter):
        initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles,
                                    qubit_converter)
        ansatz = UCCSD(
            qubit_converter,
            self.num_particles,
            self.num_spin_orbitals,
            initial_state=initial_state,
        )

        return ansatz

    def test_uccsd_hf(self):
        """uccsd hf test"""
        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SLSQP(maxiter=100)
        backend = BasicAer.get_backend("statevector_simulator")
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(backend=backend),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)

        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=6)

    @slow_test
    def test_uccsd_hf_qasm(self):
        """uccsd hf test with qasm simulator."""
        qubit_converter = QubitConverter(ParityMapper())
        ansatz = self._prepare_uccsd_hf(qubit_converter)

        backend = BasicAer.get_backend("qasm_simulator")

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            expectation=PauliExpectation(),
            quantum_instance=QuantumInstance(
                backend=backend,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )

        gsc = GroundStateEigensolver(qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0], -1.138, places=2)

    @slow_test
    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_uccsd_hf_aer_statevector(self):
        """uccsd hf test with Aer statevector"""

        backend = qiskit.providers.aer.Aer.get_backend(
            "aer_simulator_statevector")

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SLSQP(maxiter=100)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            quantum_instance=QuantumInstance(backend=backend),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=6)

    @slow_test
    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_uccsd_hf_aer_qasm(self):
        """uccsd hf test with Aer qasm simulator."""

        backend = qiskit.providers.aer.Aer.get_backend("aer_simulator")

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            expectation=PauliExpectation(group_paulis=False),
            quantum_instance=QuantumInstance(
                backend=backend,
                seed_simulator=algorithm_globals.random_seed,
                seed_transpiler=algorithm_globals.random_seed,
            ),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0], -1.131, places=2)

    @slow_test
    @unittest.skipUnless(optionals.HAS_AER,
                         "qiskit-aer is required to run this test")
    def test_uccsd_hf_aer_qasm_snapshot(self):
        """uccsd hf test with Aer qasm simulator snapshot."""

        backend = qiskit.providers.aer.Aer.get_backend("aer_simulator")

        ansatz = self._prepare_uccsd_hf(self.qubit_converter)

        optimizer = SPSA(maxiter=200, last_avg=5)
        solver = VQE(
            ansatz=ansatz,
            optimizer=optimizer,
            expectation=AerPauliExpectation(),
            quantum_instance=QuantumInstance(backend=backend),
        )

        gsc = GroundStateEigensolver(self.qubit_converter, solver)

        result = gsc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(result.total_energies[0],
                               self.reference_energy,
                               places=3)

    def test_freeze_core_z2_symmetry_compatibility(self):
        """Regression test against #192.

        An issue arose when the FreezeCoreTransformer was combined with the automatic Z2Symmetry
        reduction. This regression test ensures that this behavior remains fixed.
        """
        driver = HDF5Driver(hdf5_input=self.get_resource_path(
            "LiH_sto3g.hdf5", "second_q/transformers"))
        problem = ElectronicStructureProblem(driver, [FreezeCoreTransformer()])
        qubit_converter = QubitConverter(
            ParityMapper(),
            two_qubit_reduction=True,
            z2symmetry_reduction="auto",
        )

        solver = NumPyMinimumEigensolverFactory()
        gsc = GroundStateEigensolver(qubit_converter, solver)

        result = gsc.solve(problem)
        self.assertAlmostEqual(result.total_energies[0], -7.882, places=2)

    def test_total_dipole(self):
        """Regression test against #198.

        An issue with calculating the dipole moment that had division None/float.
        """
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        self.assertAlmostEqual(res.total_dipole_moment_in_debye[0],
                               0.0,
                               places=1)

    def test_print_result(self):
        """Regression test against #198 and general issues with printing results."""
        solver = NumPyMinimumEigensolverFactory()
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        with contextlib.redirect_stdout(io.StringIO()) as out:
            print(res)
        # do NOT change the below! Lines have been truncated as to not force exact numerical matches
        expected = """\
            === GROUND STATE ENERGY ===

            * Electronic ground state energy (Hartree): -1.857
              - computed part:      -1.857
            ~ Nuclear repulsion energy (Hartree): 0.719
            > Total ground state energy (Hartree): -1.137

            === MEASURED OBSERVABLES ===

              0:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000

            === DIPOLE MOMENTS ===

            ~ Nuclear dipole moment (a.u.): [0.0  0.0  1.38

              0:
              * Electronic dipole moment (a.u.): [0.0  0.0  -1.38
                - computed part:      [0.0  0.0  -1.38
              > Dipole moment (a.u.): [0.0  0.0  0.0]  Total: 0.
                             (debye): [0.0  0.0  0.0]  Total: 0.
        """
        for truth, expected in zip(out.getvalue().split("\n"),
                                   expected.split("\n")):
            assert truth.strip().startswith(expected.strip())

    def test_default_initial_point(self):
        """Test when using the default initial point."""

        solver = VQEUCCFactory(quantum_instance=QuantumInstance(
            BasicAer.get_backend("statevector_simulator")))
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)

        np.testing.assert_array_equal(solver.initial_point.to_numpy_array(),
                                      [0.0, 0.0, 0.0])
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)

    def test_vqe_ucc_factory_with_user_initial_point(self):
        """Test VQEUCCFactory when using it with a user defined initial point."""

        initial_point = np.asarray(
            [1.28074029e-19, 5.92226076e-08, 1.11762559e-01])
        solver = VQEUCCFactory(
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator")),
            initial_point=initial_point,
            optimizer=SLSQP(maxiter=1),
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)
        np.testing.assert_array_almost_equal(res.raw_result.optimal_point,
                                             initial_point)

    def test_vqe_ucc_factory_with_mp2(self):
        """Test when using MP2InitialPoint to generate the initial point."""

        informed_start = MP2InitialPoint()

        solver = VQEUCCFactory(
            quantum_instance=QuantumInstance(
                BasicAer.get_backend("statevector_simulator")),
            initial_point=informed_start,
        )
        calc = GroundStateEigensolver(self.qubit_converter, solver)
        res = calc.solve(self.electronic_structure_problem)

        np.testing.assert_array_almost_equal(
            solver.initial_point.to_numpy_array(), [0.0, 0.0, -0.07197145])
        self.assertAlmostEqual(res.total_energies[0],
                               self.reference_energy,
                               places=6)