Ejemplo n.º 1
0
    def test_optimize_grad(self):
        """Test that the gradient of VQECost is accessible and correct when using observable
        optimization and the autograd interface."""
        if not qml.tape_mode_active():
            pytest.skip("This test is only intended for tape mode")

        dev = qml.device("default.qubit", wires=4)
        hamiltonian = big_hamiltonian

        cost = qml.VQECost(qml.templates.StronglyEntanglingLayers,
                           hamiltonian,
                           dev,
                           optimize=True)
        cost2 = qml.VQECost(qml.templates.StronglyEntanglingLayers,
                            hamiltonian,
                            dev,
                            optimize=False)

        w = qml.init.strong_ent_layers_uniform(2, 4, seed=1967)

        dc = qml.grad(cost)(w)
        exec_opt = dev.num_executions
        dev._num_executions = 0

        dc2 = qml.grad(cost2)(w)
        exec_no_opt = dev.num_executions

        assert exec_no_opt > exec_opt
        assert np.allclose(dc, big_hamiltonian_grad)
        assert np.allclose(dc2, big_hamiltonian_grad)
Ejemplo n.º 2
0
def test_integration_hamiltonian_to_vqe_cost(monkeypatch, mol_name, terms_ref,
                                             expected_cost, tol):
    r"""Test if `convert_hamiltonian()` in qchem integrates with `VQECost()` in pennylane"""

    qOp = QubitOperator()
    if terms_ref is not None:
        monkeypatch.setattr(qOp, "terms", terms_ref)
    vqe_hamiltonian = qchem.convert_hamiltonian(qOp)

    # maybe make num_qubits a @property of the Hamiltonian class?
    num_qubits = max(
        1, len(set([w for op in vqe_hamiltonian.ops for w in op.wires])))

    dev = qml.device("default.qubit", wires=num_qubits)
    print(vqe_hamiltonian.terms)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    dummy_cost = qml.VQECost(dummy_ansatz, vqe_hamiltonian, dev)
    params = [0.1 * i for i in range(num_qubits)]
    res = dummy_cost(params)

    assert np.allclose(res, expected_cost, **tol)
Ejemplo n.º 3
0
    def test_module_example(self, tol):
        """Test the example in the QAOA module docstring"""

        # Defines the wires and the graph on which MaxCut is being performed
        wires = range(3)
        graph = Graph([(0, 1), (1, 2), (2, 0)])

        # Defines the QAOA cost and mixer Hamiltonians
        cost_h, mixer_h = qaoa.maxcut(graph)

        # Defines a layer of the QAOA ansatz from the cost and mixer Hamiltonians
        def qaoa_layer(gamma, alpha):
            qaoa.cost_layer(gamma, cost_h)
            qaoa.mixer_layer(alpha, mixer_h)

        # Repeatedly applies layers of the QAOA ansatz
        def circuit(params, **kwargs):
            for w in wires:
                qml.Hadamard(wires=w)

            qml.layer(qaoa_layer, 2, params[0], params[1])

        # Defines the device and the QAOA cost function
        dev = qml.device('default.qubit', wires=len(wires))
        cost_function = qml.VQECost(circuit, cost_h, dev)

        res = cost_function([[1, 1], [1, 1]])
        expected = -1.8260274380964299

        assert np.allclose(res, expected, atol=tol, rtol=0)
Ejemplo n.º 4
0
def test_integration_observable_to_vqe_cost(monkeypatch, mol_name, terms_ref,
                                            expected_cost, custom_wires, tol):
    r"""Test if `convert_observable()` in qchem integrates with `VQECost()` in pennylane"""

    qOp = QubitOperator()
    if terms_ref is not None:
        monkeypatch.setattr(qOp, "terms", terms_ref)
    vqe_observable = qchem.convert_observable(qOp, custom_wires)

    num_qubits = len(vqe_observable.wires)
    assert vqe_observable.terms.__repr__()  # just to satisfy codecov

    if custom_wires is None:
        wires = num_qubits
    elif isinstance(custom_wires, dict):
        wires = qchem.structure._process_wires(custom_wires)
    else:
        wires = custom_wires[:num_qubits]
    dev = qml.device("default.qubit", wires=wires)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    dummy_cost = qml.VQECost(dummy_ansatz, vqe_observable, dev)
    params = [0.1 * i for i in range(num_qubits)]
    res = dummy_cost(params)

    assert np.allclose(res, expected_cost, **tol)
Ejemplo n.º 5
0
    def test_optimize_grad_tf(self, tf_support):
        """Test that the gradient of VQECost is accessible and correct when using observable
        optimization and the TensorFlow interface."""
        if not qml.tape_mode_active():
            pytest.skip("This test is only intended for tape mode")
        if not tf_support:
            pytest.skip("This test requires TensorFlow")

        dev = qml.device("default.qubit", wires=4)
        hamiltonian = big_hamiltonian

        cost = qml.VQECost(qml.templates.StronglyEntanglingLayers,
                           hamiltonian,
                           dev,
                           optimize=True,
                           interface="tf")

        w = tf.Variable(qml.init.strong_ent_layers_uniform(2, 4, seed=1967))

        with tf.GradientTape() as tape:
            res = cost(w)

        dc = tape.gradient(res, w).numpy()

        assert np.allclose(dc, big_hamiltonian_grad)
Ejemplo n.º 6
0
    def test_optimize_grad_torch(self, torch_support):
        """Test that the gradient of VQECost is accessible and correct when using observable
        optimization and the Torch interface."""
        if not qml.tape_mode_active():
            pytest.skip("This test is only intended for tape mode")
        if not torch_support:
            pytest.skip("This test requires Torch")

        dev = qml.device("default.qubit", wires=4)
        hamiltonian = big_hamiltonian

        cost = qml.VQECost(
            qml.templates.StronglyEntanglingLayers,
            hamiltonian,
            dev,
            optimize=True,
            interface="torch",
        )

        w = torch.tensor(qml.init.strong_ent_layers_uniform(2, 4, seed=1967),
                         requires_grad=True)

        res = cost(w)
        res.backward()
        dc = w.grad.detach().numpy()

        assert np.allclose(dc, big_hamiltonian_grad)
Ejemplo n.º 7
0
    def test_gradient(self, tol):
        """Test differentiation works"""
        dev = qml.device("default.qubit", wires=1)

        def ansatz(params, **kwargs):
            qml.RX(params[0], wires=0)
            qml.RY(params[1], wires=0)

        coeffs = [0.2, 0.5]
        observables = [qml.PauliX(0), qml.PauliY(0)]

        H = qml.vqe.Hamiltonian(coeffs, observables)
        a, b = 0.54, 0.123
        params = Variable([a, b], dtype=tf.float64)
        cost = qml.VQECost(ansatz, H, dev, interface="tf")

        with tf.GradientTape() as tape:
            loss = cost(params)
            res = np.array(tape.gradient(loss, params))

        expected = [
            -coeffs[0] * np.sin(a) * np.sin(b) - coeffs[1] * np.cos(a),
            coeffs[0] * np.cos(a) * np.cos(b)
        ]

        assert np.allclose(res, expected, atol=tol, rtol=0)
Ejemplo n.º 8
0
 def test_cost_evaluate(self, params, ansatz, coeffs, observables):
     """Tests that the cost function evaluates properly"""
     hamiltonian = qml.vqe.Hamiltonian(coeffs, observables)
     dev = qml.device("default.qubit", wires=3)
     expval = qml.VQECost(ansatz, hamiltonian, dev)
     assert type(expval(params)) == np.float64
     assert np.shape(expval(params)) == ()  # expval should be scalar
Ejemplo n.º 9
0
    def test_gradient(self, tol):
        """Test differentiation works"""
        dev = qml.device("default.qubit", wires=1)

        def ansatz(params, **kwargs):
            qml.RX(params[0], wires=0)
            qml.RY(params[1], wires=0)

        coeffs = [0.2, 0.5]
        observables = [qml.PauliX(0), qml.PauliY(0)]

        H = qml.vqe.Hamiltonian(coeffs, observables)
        a, b = 0.54, 0.123
        params = torch.autograd.Variable(torch.tensor([a, b]),
                                         requires_grad=True)

        cost = qml.VQECost(ansatz, H, dev, interface="torch")
        loss = cost(params)
        loss.backward()

        res = params.grad.numpy()

        expected = [
            -coeffs[0] * np.sin(a) * np.sin(b) - coeffs[1] * np.cos(a),
            coeffs[0] * np.cos(a) * np.cos(b)
        ]

        assert np.allclose(res, expected, atol=tol, rtol=0)
Ejemplo n.º 10
0
    def test_gradient(self, tol, interface):
        """Test differentiation works"""
        dev = qml.device("default.qubit", wires=1)

        def ansatz(params, **kwargs):
            qml.RX(params[0], wires=0)
            qml.RY(params[1], wires=0)

        coeffs = [0.2, 0.5]
        observables = [qml.PauliX(0), qml.PauliY(0)]

        H = qml.vqe.Hamiltonian(coeffs, observables)
        a, b = 0.54, 0.123
        params = np.array([a, b])

        cost = qml.VQECost(ansatz, H, dev, interface=interface)
        dcost = qml.grad(cost, argnum=[0])
        res = dcost(params)

        expected = [
            -coeffs[0] * np.sin(a) * np.sin(b) - coeffs[1] * np.cos(a),
            coeffs[0] * np.cos(a) * np.cos(b)
        ]

        assert np.allclose(res, expected, atol=tol, rtol=0)
Ejemplo n.º 11
0
    def test_all_interfaces_gradient_agree(self, tol):
        """Test the gradient agrees across all interfaces"""
        dev = qml.device("default.qubit", wires=2)

        coeffs = [0.2, 0.5]
        observables = [qml.PauliX(0) @ qml.PauliZ(1), qml.PauliY(0)]

        H = qml.vqe.Hamiltonian(coeffs, observables)

        # TensorFlow interface
        params = Variable(
            qml.init.strong_ent_layers_normal(n_layers=3, n_wires=2, seed=1))
        ansatz = qml.templates.layers.StronglyEntanglingLayers

        cost = qml.VQECost(ansatz, H, dev, interface="tf")

        with tf.GradientTape() as tape:
            loss = cost(params)
            res_tf = np.array(tape.gradient(loss, params))

        # Torch interface
        params = torch.tensor(
            qml.init.strong_ent_layers_normal(n_layers=3, n_wires=2, seed=1))
        params = torch.autograd.Variable(params, requires_grad=True)
        ansatz = qml.templates.layers.StronglyEntanglingLayers

        cost = qml.VQECost(ansatz, H, dev, interface="torch")
        loss = cost(params)
        loss.backward()
        res_torch = params.grad.numpy()

        # NumPy interface
        params = qml.init.strong_ent_layers_normal(n_layers=3,
                                                   n_wires=2,
                                                   seed=1)
        ansatz = qml.templates.layers.StronglyEntanglingLayers
        cost = qml.VQECost(ansatz, H, dev, interface="numpy")
        dcost = qml.grad(cost, argnum=[0])
        res = dcost(params)

        assert np.allclose(res, res_tf, atol=tol, rtol=0)
        assert np.allclose(res, res_torch, atol=tol, rtol=0)
Ejemplo n.º 12
0
def test_vqe_cost():
    """Tests that VQECost raises a UserWarning but otherwise behaves as ExpvalCost"""

    h = qml.Hamiltonian([1], [qml.PauliZ(0)])
    dev = qml.device("default.qubit", wires=1)
    ansatz = qml.templates.StronglyEntanglingLayers

    with pytest.warns(UserWarning, match="Use of VQECost is deprecated"):
        cost = qml.VQECost(ansatz, h, dev)

    assert isinstance(cost, qml.ExpvalCost)
Ejemplo n.º 13
0
    def test_optimize(self, interface, tf_support, torch_support):
        """Test that a VQECost with observable optimization gives the same result as another
        VQECost without observable optimization."""
        if not qml.tape_mode_active():
            pytest.skip("This test is only intended for tape mode")
        if interface == "tf" and not tf_support:
            pytest.skip("This test requires TensorFlow")
        if interface == "torch" and not torch_support:
            pytest.skip("This test requires Torch")

        dev = qml.device("default.qubit", wires=4)
        hamiltonian = big_hamiltonian

        cost = qml.VQECost(
            qml.templates.StronglyEntanglingLayers,
            hamiltonian,
            dev,
            optimize=True,
            interface=interface,
        )
        cost2 = qml.VQECost(
            qml.templates.StronglyEntanglingLayers,
            hamiltonian,
            dev,
            optimize=False,
            interface=interface,
        )

        w = qml.init.strong_ent_layers_uniform(2, 4, seed=1967)

        c1 = cost(w)
        exec_opt = dev.num_executions
        dev._num_executions = 0

        c2 = cost2(w)
        exec_no_opt = dev.num_executions

        assert exec_opt == 5  # Number of groups in the Hamiltonian
        assert exec_no_opt == 15

        assert np.allclose(c1, c2)
Ejemplo n.º 14
0
    def test_single_qubit_vqe_using_vqecost(self, tol):
        """Test single-qubit VQE using VQECost 
        has the correct QNG value every step, the correct parameter updates,
        and correct cost after 200 steps"""
        dev = qml.device("default.qubit", wires=1)

        def circuit(params, wires=0):
            qml.RX(params[0], wires=wires)
            qml.RY(params[1], wires=wires)

        coeffs = [1, 1]
        obs_list = [
            qml.PauliX(0),
            qml.PauliZ(0)
        ]

        h = qml.Hamiltonian(coeffs=coeffs, observables=obs_list)

        cost_fn = qml.VQECost(ansatz=circuit, hamiltonian=h, device=dev)

        def gradient(params):
            """Returns the gradient"""
            da = -np.sin(params[0]) * (np.cos(params[1]) + np.sin(params[1]))
            db = np.cos(params[0]) * (np.cos(params[1]) - np.sin(params[1]))
            return np.array([da, db])

        eta = 0.01
        init_params = np.array([0.011, 0.012])
        num_steps = 200

        opt = qml.QNGOptimizer(eta)
        theta = init_params

        # optimization for 200 steps total
        for t in range(num_steps):
            theta_new = opt.step(cost_fn, theta)

            # check metric tensor
            res = opt.metric_tensor
            exp = np.diag([0.25, (np.cos(theta[0]) ** 2)/4])
            assert np.allclose(res, exp, atol=tol, rtol=0)

            # check parameter update
            dtheta = eta * sp.linalg.pinvh(exp) @ gradient(theta)
            assert np.allclose(dtheta, theta - theta_new, atol=tol, rtol=0)

            theta = theta_new

        # check final cost
        assert np.allclose(cost_fn(theta), -1.41421356, atol=tol, rtol=0)
Ejemplo n.º 15
0
    def test_optimize_outside_tape_mode(self):
        """Test that an error is raised if observable optimization is requested outside of tape
        mode."""
        if qml.tape_mode_active():
            pytest.skip("This test is only intended for non-tape mode")

        dev = qml.device("default.qubit", wires=2)
        hamiltonian = qml.vqe.Hamiltonian([1], [qml.PauliZ(0)])

        with pytest.raises(
                ValueError,
                match="Observable optimization is only supported in tape"):
            qml.VQECost(lambda params, **kwargs: None,
                        hamiltonian,
                        dev,
                        optimize=True)
Ejemplo n.º 16
0
    def test_passing_kwargs(self, coeffs, observables, expected):
        """Test that the step size and order used for the finite differences
        differentiation method were passed to the QNode instances using the
        keyword arguments."""
        dev = qml.device("default.qubit", wires=2)
        hamiltonian = qml.vqe.Hamiltonian(coeffs, observables)
        cost = qml.VQECost(lambda params, **kwargs: None,
                           hamiltonian,
                           dev,
                           h=123,
                           order=2)

        # Checking that the qnodes contain the step size and order
        for qnode in cost.qnodes:
            assert qnode.h == 123
            assert qnode.order == 2
Ejemplo n.º 17
0
    def test_metric_tensor(self):
        """Test that an error is raised if the metric tensor is requested in optimize=True mode."""
        if not qml.tape_mode_active():
            pytest.skip("This test is only intended for tape mode")

        dev = qml.device("default.qubit", wires=4)
        hamiltonian = big_hamiltonian

        cost = qml.VQECost(qml.templates.StronglyEntanglingLayers,
                           hamiltonian,
                           dev,
                           optimize=True)

        with pytest.raises(
                ValueError,
                match="Evaluation of the metric tensor is not supported"):
            cost.metric_tensor(None)
Ejemplo n.º 18
0
def test_integration_mol_file_to_vqe_cost(name, core, active, mapping,
                                          expected_cost, custom_wires, tol):
    r"""Test if the output of `decompose()` works with `convert_observable()`
    to generate `VQECost()`"""

    ref_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                           "test_ref_files")
    hf_file = os.path.join(ref_dir, name)
    qubit_hamiltonian = qchem.decompose(
        hf_file,
        mapping=mapping,
        core=core,
        active=active,
    )

    vqe_hamiltonian = qchem.convert_observable(qubit_hamiltonian, custom_wires)
    assert len(vqe_hamiltonian.ops) > 1  # just to check if this runs

    num_qubits = len(vqe_hamiltonian.wires)
    assert num_qubits == 2 * len(active)

    if custom_wires is None:
        wires = num_qubits
    elif isinstance(custom_wires, dict):
        wires = qchem.structure._process_wires(custom_wires)
    else:
        wires = custom_wires[:num_qubits]
    dev = qml.device("default.qubit", wires=wires)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    phis = np.load(os.path.join(ref_dir, "dummy_ansatz_parameters.npy"))

    dummy_cost = qml.VQECost(dummy_ansatz, vqe_hamiltonian, dev)
    res = dummy_cost(phis)

    assert np.abs(res - expected_cost) < tol["atol"]
Ejemplo n.º 19
0
def test_integration_mol_file_to_vqe_cost(hf_filename, docc_mo, act_mo,
                                          type_of_transformation,
                                          expected_cost, tol):
    r"""Test if the output of `decompose_hamiltonian()` works with `convert_hamiltonian()`
    to generate `VQECost()`"""
    ref_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                           "test_ref_files")

    transformed_hamiltonian = qchem.decompose_hamiltonian(
        hf_filename,
        ref_dir,
        mapping=type_of_transformation,
        docc_mo_indices=docc_mo,
        active_mo_indices=act_mo,
    )

    vqe_hamiltonian = qchem.convert_hamiltonian(transformed_hamiltonian)
    assert len(vqe_hamiltonian.ops) > 1  # just to check if this runs

    num_qubits = max(
        1,
        len(
            set([
                w for op in vqe_hamiltonian.ops for ws in op.wires for w in ws
            ])))
    assert num_qubits == 2 * len(act_mo)

    dev = qml.device("default.qubit", wires=num_qubits)

    # can replace the ansatz with more suitable ones later.
    def dummy_ansatz(phis, wires):
        for phi, w in zip(phis, wires):
            qml.RX(phi, wires=w)

    phis = np.load(os.path.join(ref_dir, "dummy_ansatz_parameters.npy"))

    dummy_cost = qml.VQECost(dummy_ansatz, vqe_hamiltonian, dev)
    res = dummy_cost(phis)

    assert np.abs(res - expected_cost) < tol["atol"]
Ejemplo n.º 20
0
##############################################################################
# The ground state for each inter-atomic distance is characterized by a different Y-rotation angle.
# The values of these Y-rotations can be found by minimizing the ground state energy as outlined in
# :doc:`tutorial_vqe`. In this tutorial, we load pre-optimized rotations and focus on
# comparing the speed of evaluating the potential energy surface with sequential and parallel
# evaluation. These parameters can be downloaded by clicking :download:`here
# <../demonstrations/vqe_parallel/RY_params.npy>`.

params = np.load("vqe_parallel/RY_params.npy")

##############################################################################
# Finally, the energies as functions of rotation angle can be given using
# :class:`~.pennylane.VQECost`.

energies = [qml.VQECost(circuit, h, devs) for h in hamiltonians]

##############################################################################
# Calculating the potential energy surface
# ----------------------------------------
#
# :class:`~.pennylane.VQECost` returns a :class:`~.pennylane.QNodeCollection` which can be
# evaluated using the input parameters to the ansatz circuit. The
# :class:`~.pennylane.QNodeCollection` can be evaluated asynchronously by passing the keyword
# argument ``parallel=True``. When ``parallel=False`` (the default behaviour), the QNodes are
# instead evaluated sequentially.
#
# We can use this feature to compare the sequential and parallel times required to calculate the
# potential energy surface. The following function calculates the surface:

Ejemplo n.º 21
0
def circuit(params, wires=0):
    qml.RX(params[0], wires=wires)
    qml.RY(params[1], wires=wires)


##############################################################################
# We then define our cost function using the ``VQECost`` class, which supports the computation of
# block-diagonal or diagonal approximations to the Fubini-Study metric tensor. This tensor is a
# crucial component for optimizing with quantum natural gradients.

coeffs = [1, 1]
obs = [qml.PauliX(0), qml.PauliZ(0)]

H = qml.Hamiltonian(coeffs, obs)
cost_fn = qml.VQECost(circuit, H, dev)

##############################################################################
# To analyze performance of the quantum natural gradient on VQE calculations,
# we will set up and execute optimizations using the ``GradientDescentOptimizer``
# and the ``QNGOptimizer`` using the block-diagonal approximation to the metric tensor.
#
# To perform a fair comparison, we fix the initial parameters for the two optimizers.

init_params = np.array([3.97507603, 3.00854038])

##############################################################################
# We will carry out each optimization over a maximum of 500 steps. As was done in the VQE
# tutorial, we aim to reach a convergence tolerance of around :math:`10^{-6}`. We use a step size of 0.01.

max_iterations = 500
Ejemplo n.º 22
0
######################################################################
#
# Note that :func:`~.pennylane.layer` allows us to pass variational parameters
# ``params[0]`` and ``params[1]`` into each layer of the circuit. That's it! The last
# step is PennyLane's specialty: optimizing the circuit parameters.
#
# The cost function is the expectation value of :math:`H_C`, which we want to minimize. The
# function :func:`~.pennylane.VQECost` is designed for this purpose: it returns the
# expectation value of an input Hamiltonian with respect to the circuit's output state.
# We also define the device on which the simulation is
# performed. We use the PennyLane-Qulacs plugin to
# run the circuit on the Qulacs simulator:
#

dev = qml.device("qulacs.simulator", wires=wires)
cost_function = qml.VQECost(circuit, cost_h, dev)

######################################################################
#
# Finally, we optimize the cost function using the built-in
# :func:`~.pennylane.GradientDescentOptimizer`. We perform optimization for seventy steps and initialize the
# parameters:

optimizer = qml.GradientDescentOptimizer()
steps = 70
params = [[0.5, 0.5], [0.5, 0.5]]

######################################################################
#
# Notice that we set each of the initial parameters to :math:`0.5`. For demonstration purposes,
# we chose initial parameters that we know work fairly well, and don't get stuck in any local minima.
Ejemplo n.º 23
0
hf_state = qchem.hf_state(electrons, qubits)
print(hf_state)

##############################################################################
# Finally, we can use the :func:`~.pennylane.templates.subroutines.UCCSD` function to define
# our VQE ansatz,

ansatz = partial(UCCSD, init_state=hf_state, s_wires=s_wires, d_wires=d_wires)

##############################################################################
# Next, we use the PennyLane class :class:`~.pennylane.VQECost` to define the cost function.
# This requires specifying the circuit, target Hamiltonian, and the device. It returns
# a cost function that can be evaluated with the circuit parameters:

cost_fn = qml.VQECost(ansatz, H, dev)

##############################################################################
# As a reminder, we also built the total spin operator :math:`\hat{S}^2` for which
# we can now define a function to compute its expectation value:

S2_exp_value = qml.VQECost(ansatz, S2, dev)

##############################################################################
# The total spin :math:`S` of the trial state can be obtained from the
# expectation value :math:`\langle \hat{S}^2 \rangle` as,
#
# .. math::
#
#     S = -\frac{1}{2} + \sqrt{\frac{1}{4} + \langle \hat{S}^2 \rangle}.
#
Ejemplo n.º 24
0
    qml.CNOT(wires=[3, 1])


##############################################################################
# .. note::
#
#     The qubit register has been initialized to :math:`|1100\rangle` which encodes the
#     Hartree-Fock state of the hydrogen molecule described with a `minimal basis
#     <https://en.wikipedia.org/wiki/Basis_set_(chemistry)#Minimal_basis_sets>`__.
#
# The cost function for optimizing the circuit can be created using the :class:`~.VQECost`
# class, which is tailored for VQE optimization. It requires specifying the
# circuit, target Hamiltonian, and the device, and returns a cost function that can
# be evaluated with the circuit parameters:

cost_fn = qml.VQECost(circuit, h, dev)

##############################################################################
# Wrapping up, we fix an optimizer and randomly initialize circuit parameters. For reliable
# results, we fix the seed of the random number generator, since in practice it may be necessary
# to re-initialize the circuit several times before convergence occurs.

opt = qml.GradientDescentOptimizer(stepsize=0.4)
np.random.seed(0)
params = np.random.normal(0, np.pi, (qubits, 3))

print(params)

##############################################################################
# We carry out the optimization over a maximum of 200 steps, aiming to reach a convergence
# tolerance (difference in cost function for subsequent optimization steps) of :math:`\sim 10^{
Ejemplo n.º 25
0
 def test_cost_expvals(self, coeffs, observables, expected):
     """Tests that the cost function returns correct expectation values"""
     dev = qml.device("default.qubit", wires=2)
     hamiltonian = qml.vqe.Hamiltonian(coeffs, observables)
     cost = qml.VQECost(lambda params, **kwargs: None, hamiltonian, dev)
     assert cost([]) == sum(expected)
Ejemplo n.º 26
0
 def test_cost_invalid_ansatz(self, ansatz, mock_device):
     """Tests that the cost function raises an exception if the ansatz is not valid"""
     hamiltonian = qml.vqe.Hamiltonian((1.0, ), [qml.PauliZ(0)])
     with pytest.raises(ValueError, match="not a callable function."):
         cost = qml.VQECost(4, hamiltonian, mock_device)