From 02f106cef3529f17f23d8609ee0da8490e4ba4de Mon Sep 17 00:00:00 2001
From: Tom Bromley <49409390+trbromley@users.noreply.github.com>
Date: Thu, 19 Nov 2020 15:44:26 -0500
Subject: [PATCH] Rename VQECost to ExpvalCost (#913)
* Rename VQECost to ExpvalCost
* Add VQECost as deprecated
* Add to changelog
* Update PR number
* Revert changes to changelog
* Change a to an
* Add pylint exception
* Remove VQECost from docs
* Reintroduce docstring
---
.github/CHANGELOG.md | 12 ++--
doc/code/qml_qaoa.rst | 4 +-
doc/introduction/chemistry.rst | 4 +-
pennylane/__init__.py | 2 +-
pennylane/optimize/qng.py | 10 ++--
.../layers/particle_conserving_u1.py | 2 +-
.../layers/particle_conserving_u2.py | 2 +-
pennylane/templates/subroutines/uccsd.py | 2 +-
pennylane/utils.py | 2 +-
pennylane/vqe/__init__.py | 2 +-
pennylane/vqe/vqe.py | 38 ++++++++----
qchem/tests/test_convert_observable.py | 8 +--
tests/test_optimize_qng.py | 6 +-
tests/test_qaoa.py | 2 +-
tests/test_vqe.py | 59 +++++++++++--------
15 files changed, 95 insertions(+), 60 deletions(-)
diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md
index e7a3939bcaa..d97aa277e99 100644
--- a/.github/CHANGELOG.md
+++ b/.github/CHANGELOG.md
@@ -2,8 +2,8 @@
New features since last release
-* The ``VQECost`` class now provides observable optimization using the ``optimize`` argument,
- resulting in potentially fewer device executions.
+* The ``ExpvalCost`` class (previously ``VQECost``) now provides observable optimization using the
+ ``optimize`` argument, resulting in potentially fewer device executions.
[(#902)](https://github.com/PennyLaneAI/pennylane/pull/902)
This is achieved by separating the observables composing the Hamiltonian into qubit-wise
@@ -18,8 +18,8 @@
dev = qml.device("default.qubit", wires=2)
ansatz = qml.templates.StronglyEntanglingLayers
- cost_opt = qml.VQECost(ansatz, H, dev, optimize=True)
- cost_no_opt = qml.VQECost(ansatz, H, dev, optimize=False)
+ cost_opt = qml.ExpvalCost(ansatz, H, dev, optimize=True)
+ cost_no_opt = qml.ExpvalCost(ansatz, H, dev, optimize=False)
params = qml.init.strong_ent_layers_uniform(3, 2)
```
@@ -276,6 +276,10 @@
Breaking changes
+- The ``VQECost`` class has been renamed to ``ExpvalCost`` to reflect its general applicability
+ beyond VQE. Use of ``VQECost`` is still possible but will result in a deprecation warning.
+ [(#913)](https://github.com/PennyLaneAI/pennylane/pull/913)
+
Documentation
Bug fixes
diff --git a/doc/code/qml_qaoa.rst b/doc/code/qml_qaoa.rst
index e9a947c7874..9a0a50888cc 100644
--- a/doc/code/qml_qaoa.rst
+++ b/doc/code/qml_qaoa.rst
@@ -51,7 +51,7 @@ computational basis states, and then repeatedly apply QAOA layers with the
qml.layer(qaoa_layer, 2, params[0], params[1])
-With the circuit defined, we call the device on which QAOA will be executed, as well as the ``qml.VQECost``, which
+With the circuit defined, we call the device on which QAOA will be executed, as well as the ``qml.ExpvalCost``, which
creates the QAOA cost function: the expected value of the cost Hamiltonian with respect to the parametrized output
of the QAOA circuit.
@@ -59,7 +59,7 @@ of the QAOA circuit.
# Defines the device and the QAOA cost function
dev = qml.device('default.qubit', wires=len(wires))
- cost_function = qml.VQECost(circuit, cost_h, dev)
+ cost_function = qml.ExpvalCost(circuit, cost_h, dev)
>>> print(cost_function([[1, 1], [1, 1]]))
-1.8260274380964299
diff --git a/doc/introduction/chemistry.rst b/doc/introduction/chemistry.rst
index 8b4db7eddcd..1316d1ae92d 100644
--- a/doc/introduction/chemistry.rst
+++ b/doc/introduction/chemistry.rst
@@ -158,7 +158,7 @@ where a quantum computer is used to prepare the trial wave function of a molecul
the expectation value of the *electronic Hamiltonian*, while a classical optimizer is used to
find its ground state.
-We can use :class:`~.VQECost` to automatically create the required PennyLane QNodes and define
+We can use :class:`~.ExpvalCost` to automatically create the required PennyLane QNodes and define
the cost function:
.. code-block:: python
@@ -175,7 +175,7 @@ the cost function:
qml.CNOT(wires=[2, 0])
qml.CNOT(wires=[3, 1])
- cost = qml.VQECost(circuit, hamiltonian, dev, interface="torch")
+ cost = qml.ExpvalCost(circuit, hamiltonian, dev, interface="torch")
params = torch.rand([4, 3])
cost(params)
diff --git a/pennylane/__init__.py b/pennylane/__init__.py
index 255f20f3395..7b13b084d8c 100644
--- a/pennylane/__init__.py
+++ b/pennylane/__init__.py
@@ -34,7 +34,7 @@
import pennylane.qaoa as qaoa
from pennylane.templates import template, broadcast, layer
from pennylane.about import about
-from pennylane.vqe import Hamiltonian, VQECost
+from pennylane.vqe import Hamiltonian, ExpvalCost, VQECost
from .circuit_graph import CircuitGraph
from .configuration import Configuration
diff --git a/pennylane/optimize/qng.py b/pennylane/optimize/qng.py
index 311841d7802..cfe6e9c775e 100644
--- a/pennylane/optimize/qng.py
+++ b/pennylane/optimize/qng.py
@@ -73,7 +73,7 @@ class QNGOptimizer(GradientDescentOptimizer):
.. note::
- The QNG optimizer supports single QNodes or :class:`~.VQECost` objects as objective functions.
+ The QNG optimizer supports single QNodes or :class:`~.ExpvalCost` objects as objective functions.
Alternatively, the metric tensor can directly be provided to the :func:`step` method of the optimizer,
using the ``metric_tensor_fn`` argument.
@@ -91,7 +91,7 @@ class QNGOptimizer(GradientDescentOptimizer):
If the objective function is VQE/VQE-like, i.e., a function of a group
of QNodes that share an ansatz, there are two ways to use the optimizer:
- * Realize the objective function as a :class:`~.VQECost` object, which has
+ * Realize the objective function as an :class:`~.ExpvalCost` object, which has
a ``metric_tensor`` method.
* Manually provide the ``metric_tensor_fn`` corresponding to the metric tensor of
@@ -100,7 +100,7 @@ class QNGOptimizer(GradientDescentOptimizer):
**Examples:**
For VQE/VQE-like problems, the objective function for the optimizer can be
- realized as a VQECost object.
+ realized as an ExpvalCost object.
>>> dev = qml.device("default.qubit", wires=1)
>>> def circuit(params, wires=0):
@@ -109,7 +109,7 @@ class QNGOptimizer(GradientDescentOptimizer):
>>> coeffs = [1, 1]
>>> obs = [qml.PauliX(0), qml.PauliZ(0)]
>>> H = qml.Hamiltonian(coeffs, obs)
- >>> cost_fn = qml.VQECost(circuit, H, dev)
+ >>> cost_fn = qml.ExpvalCost(circuit, H, dev)
Once constructed, the cost function can be passed directly to the
optimizer's ``step`` function:
@@ -174,7 +174,7 @@ def step(self, qnode, x, recompute_tensor=True, metric_tensor_fn=None):
if not hasattr(qnode, "metric_tensor") and not metric_tensor_fn:
raise ValueError(
"The objective function must either be encoded as a single QNode or "
- "a VQECost object for the natural gradient to be automatically computed. "
+ "an ExpvalCost object for the natural gradient to be automatically computed. "
"Otherwise, metric_tensor_fn must be explicitly provided to the optimizer."
)
diff --git a/pennylane/templates/layers/particle_conserving_u1.py b/pennylane/templates/layers/particle_conserving_u1.py
index 0a2fbcb7ae2..2750f2eeb0e 100644
--- a/pennylane/templates/layers/particle_conserving_u1.py
+++ b/pennylane/templates/layers/particle_conserving_u1.py
@@ -219,7 +219,7 @@ def ParticleConservingU1(weights, wires, init_state=None):
ansatz = partial(ParticleConservingU1, init_state=ref_state)
# Define the cost function
- cost_fn = qml.VQECost(ansatz, h, dev)
+ cost_fn = qml.ExpvalCost(ansatz, h, dev)
# Compute the expectation value of 'h'
layers = 2
diff --git a/pennylane/templates/layers/particle_conserving_u2.py b/pennylane/templates/layers/particle_conserving_u2.py
index eb24bb182d8..67482b6d43f 100644
--- a/pennylane/templates/layers/particle_conserving_u2.py
+++ b/pennylane/templates/layers/particle_conserving_u2.py
@@ -140,7 +140,7 @@ def ParticleConservingU2(weights, wires, init_state=None):
ansatz = partial(ParticleConservingU2, init_state=ref_state)
# Define the cost function
- cost_fn = qml.VQECost(ansatz, h, dev)
+ cost_fn = qml.ExpvalCost(ansatz, h, dev)
# Compute the expectation value of 'h' for a given set of parameters
layers = 1
diff --git a/pennylane/templates/subroutines/uccsd.py b/pennylane/templates/subroutines/uccsd.py
index f2859e99d84..a9134d9e87c 100644
--- a/pennylane/templates/subroutines/uccsd.py
+++ b/pennylane/templates/subroutines/uccsd.py
@@ -145,7 +145,7 @@ def UCCSD(weights, wires, s_wires=None, d_wires=None, init_state=None):
ansatz = partial(UCCSD, init_state=ref_state, s_wires=s_wires, d_wires=d_wires)
# Define the cost function
- cost_fn = qml.VQECost(ansatz, h, dev)
+ cost_fn = qml.ExpvalCost(ansatz, h, dev)
# Compute the expectation value of 'h' for given set of parameters 'params'
params = np.random.normal(0, np.pi, len(singles) + len(doubles))
diff --git a/pennylane/utils.py b/pennylane/utils.py
index af58d1f08f0..a08f4f3d471 100644
--- a/pennylane/utils.py
+++ b/pennylane/utils.py
@@ -68,7 +68,7 @@ def decompose_hamiltonian(H, hide_identity=False):
+ (-0.5) [Z0 X1]
+ (-0.5) [Z0 Y1]
- This Hamiltonian can then be used in defining VQE problems using :class:`~.VQECost`.
+ This Hamiltonian can then be used in defining VQE problems using :class:`~.ExpvalCost`.
"""
n = int(np.log2(len(H)))
N = 2 ** n
diff --git a/pennylane/vqe/__init__.py b/pennylane/vqe/__init__.py
index 4823c8dc649..2a969a4636d 100644
--- a/pennylane/vqe/__init__.py
+++ b/pennylane/vqe/__init__.py
@@ -15,4 +15,4 @@
This package contains functionality for running Variational Quantum Eigensolver (VQE)
computations using PennyLane.
"""
-from .vqe import Hamiltonian, VQECost
+from .vqe import Hamiltonian, ExpvalCost, VQECost
diff --git a/pennylane/vqe/vqe.py b/pennylane/vqe/vqe.py
index 14aafbd4f66..56dbc6a2a2d 100644
--- a/pennylane/vqe/vqe.py
+++ b/pennylane/vqe/vqe.py
@@ -17,6 +17,7 @@
"""
# pylint: disable=too-many-arguments, too-few-public-methods
import itertools
+import warnings
import pennylane as qml
from pennylane import numpy as np
@@ -40,7 +41,7 @@ class Hamiltonian:
simplify (bool): Specifies whether the Hamiltonian is simplified upon initialization
(like-terms are combined). The default value is `False`.
- .. seealso:: :class:`~.VQECost`, :func:`~.generate_hamiltonian`
+ .. seealso:: :class:`~.ExpvalCost`, :func:`~.generate_hamiltonian`
**Example:**
@@ -346,9 +347,10 @@ def __isub__(self, H):
raise ValueError(f"Cannot subtract {type(H)} from Hamiltonian")
-class VQECost:
- """Create a VQE cost function, i.e., a cost function returning the
- expectation value of a Hamiltonian.
+class ExpvalCost:
+ """Create a cost function that gives the expectation value of an input Hamiltonian.
+
+ This cost function is useful for a range of problems including VQE and QAOA.
Args:
ansatz (callable): The ansatz for the circuit before the final measurement step.
@@ -382,7 +384,7 @@ class VQECost:
**Example:**
- To construct a ``VQECost`` cost function, we require a Hamiltonian to measure, and an ansatz
+ To construct an ``ExpvalCost`` cost function, we require a Hamiltonian to measure, and an ansatz
for our variational circuit.
We can construct a Hamiltonian manually,
@@ -404,7 +406,7 @@ class VQECost:
>>> ansatz = qml.templates.StronglyEntanglingLayers
>>> dev = qml.device("default.qubit", wires=4)
- >>> cost = qml.VQECost(ansatz, H, dev, interface="torch")
+ >>> cost = qml.ExpvalCost(ansatz, H, dev, interface="torch")
>>> params = torch.rand([2, 4, 3])
>>> cost(params)
tensor(-0.2316, dtype=torch.float64)
@@ -430,8 +432,8 @@ class VQECost:
dev = qml.device("default.qubit", wires=2)
ansatz = qml.templates.StronglyEntanglingLayers
- cost_opt = qml.VQECost(ansatz, H, dev, optimize=True)
- cost_no_opt = qml.VQECost(ansatz, H, dev, optimize=False)
+ cost_opt = qml.ExpvalCost(ansatz, H, dev, optimize=True)
+ cost_no_opt = qml.ExpvalCost(ansatz, H, dev, optimize=False)
params = qml.init.strong_ent_layers_uniform(3, 2)
@@ -462,7 +464,7 @@ def __init__(
coeffs, observables = hamiltonian.terms
self.hamiltonian = hamiltonian
- """Hamiltonian: the hamiltonian defining the VQE problem."""
+ """Hamiltonian: the input Hamiltonian."""
self.qnodes = None
"""QNodeCollection: The QNodes to be evaluated. Each QNode corresponds to the expectation
@@ -527,7 +529,23 @@ def metric_tensor(self, args, kwargs=None, diag_approx=False, only_construct=Fal
"optimized observables. Set the argument optimize=False to obtain "
"the metric tensor."
)
- # We know that for VQE, all the qnodes share the same ansatz so we select the first
+ # all the qnodes share the same ansatz so we select the first
return self.qnodes.qnodes[0].metric_tensor(
args=args, kwargs=kwargs, diag_approx=diag_approx, only_construct=only_construct
)
+
+
+class VQECost(ExpvalCost):
+ """Create a cost function that gives the expectation value of an input Hamiltonian.
+
+ .. warning::
+ Use of :class:`~.VQECost` is deprecated and should be replaced with
+ :class:`~.ExpvalCost`.
+ """
+
+ def __init__(self, *args, **kwargs):
+ warnings.warn(
+ "Use of VQECost is deprecated and should be replaced with ExpvalCost",
+ DeprecationWarning,
+ )
+ super().__init__(*args, **kwargs)
diff --git a/qchem/tests/test_convert_observable.py b/qchem/tests/test_convert_observable.py
index fffa10792d0..2d04f3ae63d 100644
--- a/qchem/tests/test_convert_observable.py
+++ b/qchem/tests/test_convert_observable.py
@@ -352,7 +352,7 @@ def test_not_xyz_terms_to_qubit_operator():
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"""
+ r"""Test if `convert_observable()` in qchem integrates with `ExpvalCost()` in pennylane"""
qOp = QubitOperator()
if terms_ref is not None:
@@ -375,7 +375,7 @@ 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)
+ dummy_cost = qml.ExpvalCost(dummy_ansatz, vqe_observable, dev)
params = [0.1 * i for i in range(num_qubits)]
res = dummy_cost(params)
@@ -397,7 +397,7 @@ 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()`"""
+ to generate `ExpvalCost()`"""
ref_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_ref_files")
hf_file = os.path.join(ref_dir, name)
@@ -424,7 +424,7 @@ def dummy_ansatz(phis, wires):
phis = np.load(os.path.join(ref_dir, "dummy_ansatz_parameters.npy"))
- dummy_cost = qml.VQECost(dummy_ansatz, vqe_hamiltonian, dev)
+ dummy_cost = qml.ExpvalCost(dummy_ansatz, vqe_hamiltonian, dev)
res = dummy_cost(phis)
assert np.abs(res - expected_cost) < tol["atol"]
diff --git a/tests/test_optimize_qng.py b/tests/test_optimize_qng.py
index 157ef1951cc..9b531136b09 100644
--- a/tests/test_optimize_qng.py
+++ b/tests/test_optimize_qng.py
@@ -40,7 +40,7 @@ def cost(a):
params = 0.5
with pytest.raises(
- ValueError, match="The objective function must either be encoded as a single QNode or a VQECost object"
+ ValueError, match="The objective function must either be encoded as a single QNode or an ExpvalCost object"
):
opt.step(cost, params)
@@ -143,7 +143,7 @@ def gradient(params):
assert np.allclose(cost_fn(theta), -1.41421356, atol=tol, rtol=0)
def test_single_qubit_vqe_using_vqecost(self, tol):
- """Test single-qubit VQE using VQECost
+ """Test single-qubit VQE using ExpvalCost
has the correct QNG value every step, the correct parameter updates,
and correct cost after 200 steps"""
dev = qml.device("default.qubit", wires=1)
@@ -160,7 +160,7 @@ def circuit(params, wires=0):
h = qml.Hamiltonian(coeffs=coeffs, observables=obs_list)
- cost_fn = qml.VQECost(ansatz=circuit, hamiltonian=h, device=dev)
+ cost_fn = qml.ExpvalCost(ansatz=circuit, hamiltonian=h, device=dev)
def gradient(params):
"""Returns the gradient"""
diff --git a/tests/test_qaoa.py b/tests/test_qaoa.py
index effcb7d9ac4..aabe70b28eb 100644
--- a/tests/test_qaoa.py
+++ b/tests/test_qaoa.py
@@ -659,7 +659,7 @@ def circuit(params, **kwargs):
# Defines the device and the QAOA cost function
dev = qml.device('default.qubit', wires=len(wires))
- cost_function = qml.VQECost(circuit, cost_h, dev)
+ cost_function = qml.ExpvalCost(circuit, cost_h, dev)
res = cost_function([[1, 1], [1, 1]])
expected = -1.8260274380964299
diff --git a/tests/test_vqe.py b/tests/test_vqe.py
index 0d3ac2cc206..c20aa2c42ed 100644
--- a/tests/test_vqe.py
+++ b/tests/test_vqe.py
@@ -683,7 +683,7 @@ 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)
+ expval = qml.ExpvalCost(ansatz, hamiltonian, dev)
assert type(expval(params)) == np.float64
assert np.shape(expval(params)) == () # expval should be scalar
@@ -692,7 +692,7 @@ 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)
+ cost = qml.ExpvalCost(lambda params, **kwargs: None, hamiltonian, dev)
assert cost([]) == sum(expected)
@pytest.mark.parametrize("ansatz", JUNK_INPUTS)
@@ -700,7 +700,7 @@ 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())
+ cost = qml.ExpvalCost(4, hamiltonian, mock_device())
@pytest.mark.parametrize("coeffs, observables, expected", hamiltonians_with_expvals)
def test_passing_kwargs(self, coeffs, observables, expected):
@@ -709,7 +709,7 @@ def test_passing_kwargs(self, coeffs, observables, expected):
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)
+ cost = qml.ExpvalCost(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:
@@ -726,12 +726,12 @@ def test_optimize_outside_tape_mode(self):
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)
+ qml.ExpvalCost(lambda params, **kwargs: None, hamiltonian, dev, optimize=True)
@pytest.mark.parametrize("interface", ["tf", "torch", "autograd"])
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."""
+ """Test that an ExpvalCost with observable optimization gives the same result as another
+ ExpvalCost 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:
@@ -742,14 +742,14 @@ def test_optimize(self, interface, tf_support, torch_support):
dev = qml.device("default.qubit", wires=4)
hamiltonian = big_hamiltonian
- cost = qml.VQECost(
+ cost = qml.ExpvalCost(
qml.templates.StronglyEntanglingLayers,
hamiltonian,
dev,
optimize=True,
interface=interface,
)
- cost2 = qml.VQECost(
+ cost2 = qml.ExpvalCost(
qml.templates.StronglyEntanglingLayers,
hamiltonian,
dev,
@@ -772,7 +772,7 @@ def test_optimize(self, interface, tf_support, torch_support):
assert np.allclose(c1, c2)
def test_optimize_grad(self):
- """Test that the gradient of VQECost is accessible and correct when using observable
+ """Test that the gradient of ExpvalCost 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")
@@ -780,8 +780,8 @@ def test_optimize_grad(self):
dev = qml.device("default.qubit", wires=4)
hamiltonian = big_hamiltonian
- cost = qml.VQECost(qml.templates.StronglyEntanglingLayers, hamiltonian, dev, optimize=True)
- cost2 = qml.VQECost(
+ cost = qml.ExpvalCost(qml.templates.StronglyEntanglingLayers, hamiltonian, dev, optimize=True)
+ cost2 = qml.ExpvalCost(
qml.templates.StronglyEntanglingLayers, hamiltonian, dev, optimize=False
)
@@ -799,7 +799,7 @@ def test_optimize_grad(self):
assert np.allclose(dc2, big_hamiltonian_grad)
def test_optimize_grad_torch(self, torch_support):
- """Test that the gradient of VQECost is accessible and correct when using observable
+ """Test that the gradient of ExpvalCost 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")
@@ -809,7 +809,7 @@ def test_optimize_grad_torch(self, torch_support):
dev = qml.device("default.qubit", wires=4)
hamiltonian = big_hamiltonian
- cost = qml.VQECost(
+ cost = qml.ExpvalCost(
qml.templates.StronglyEntanglingLayers,
hamiltonian,
dev,
@@ -826,7 +826,7 @@ def test_optimize_grad_torch(self, torch_support):
assert np.allclose(dc, big_hamiltonian_grad)
def test_optimize_grad_tf(self, tf_support):
- """Test that the gradient of VQECost is accessible and correct when using observable
+ """Test that the gradient of ExpvalCost 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")
@@ -836,7 +836,7 @@ def test_optimize_grad_tf(self, tf_support):
dev = qml.device("default.qubit", wires=4)
hamiltonian = big_hamiltonian
- cost = qml.VQECost(
+ cost = qml.ExpvalCost(
qml.templates.StronglyEntanglingLayers, hamiltonian, dev, optimize=True, interface="tf"
)
@@ -857,7 +857,7 @@ def test_metric_tensor(self):
dev = qml.device("default.qubit", wires=4)
hamiltonian = big_hamiltonian
- cost = qml.VQECost(qml.templates.StronglyEntanglingLayers, hamiltonian, dev, optimize=True)
+ cost = qml.ExpvalCost(qml.templates.StronglyEntanglingLayers, hamiltonian, dev, optimize=True)
with pytest.raises(ValueError, match="Evaluation of the metric tensor is not supported"):
cost.metric_tensor(None)
@@ -896,7 +896,7 @@ def ansatz(params, **kwargs):
a, b = 0.54, 0.123
params = np.array([a, b])
- cost = qml.VQECost(ansatz, H, dev, interface=interface)
+ cost = qml.ExpvalCost(ansatz, H, dev, interface=interface)
dcost = qml.grad(cost, argnum=[0])
res = dcost(params)
@@ -939,7 +939,7 @@ def ansatz(params, **kwargs):
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")
+ cost = qml.ExpvalCost(ansatz, H, dev, interface="torch")
loss = cost(params)
loss.backward()
@@ -986,7 +986,7 @@ def ansatz(params, **kwargs):
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")
+ cost = qml.ExpvalCost(ansatz, H, dev, interface="tf")
with tf.GradientTape() as tape:
loss = cost(params)
@@ -1019,7 +1019,7 @@ def test_all_interfaces_gradient_agree(self, tol):
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")
+ cost = qml.ExpvalCost(ansatz, H, dev, interface="tf")
with tf.GradientTape() as tape:
loss = cost(params)
@@ -1030,7 +1030,7 @@ def test_all_interfaces_gradient_agree(self, tol):
params = torch.autograd.Variable(params, requires_grad=True)
ansatz = qml.templates.layers.StronglyEntanglingLayers
- cost = qml.VQECost(ansatz, H, dev, interface="torch")
+ cost = qml.ExpvalCost(ansatz, H, dev, interface="torch")
loss = cost(params)
loss.backward()
res_torch = params.grad.numpy()
@@ -1038,9 +1038,22 @@ def test_all_interfaces_gradient_agree(self, tol):
# 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="autograd")
+ cost = qml.ExpvalCost(ansatz, H, dev, interface="autograd")
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)
+
+
+def test_vqe_cost():
+ """Tests that VQECost raises a DeprecationWarning 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(DeprecationWarning, match="Use of VQECost is deprecated"):
+ cost = qml.VQECost(ansatz, h, dev)
+
+ assert isinstance(cost, qml.ExpvalCost)