Repository: PennyLaneAI/pennylane
Pull request #1987 (2021-12-06 13:50:54)

Fix metric tensor for circuits with inverted gates
**Context:**
The generator  and coefficient stored in `op.generator` are not modified when an operation is inverted. Therefore,
using this information in the metric tensor led to the wrong result for inverted gates. This is now fixed and three tests were modified to include this szenario.
Note that this bug affects both, the new Hadamard test-based metric tensor introduced in #1725 and the block-diagonal original version.

**Description of the Change:**
The coefficient is inverted with a minus sign if the operation in question has the `inverse` flag set to `True`. The documentation clearly states now that this assumes the generator of the operations for which the metric tensor is computed to be Hermitian.

**Benefits:**
bug fix and better documentation as well as test coverage.

**Possible Drawbacks:** n/a

**Related GitHub Issues:** n/a


codecov[bot]: # [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) Report
> Merging [#1987](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (34bcf38) into [master](https://codecov.io/gh/PennyLaneAI/pennylane/commit/53b3b2b8ca9baff88d4aa3b5b72cb7cf9b8b713b?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) (53b3b2b) will **decrease** coverage by `1.91%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/graphs/tree.svg?width=650&height=150&src=pr&token=9S3YzlUgGk&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)

```diff
@@            Coverage Diff             @@
##           master    #1987      +/-   ##
==========================================
- Coverage   98.81%   96.89%   -1.92%     
==========================================
  Files         227      227              
  Lines       17291    17293       +2     
==========================================
- Hits        17086    16756     -330     
- Misses        205      537     +332     
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | Coverage Δ | |
|---|---|---|
| [pennylane/transforms/metric\_tensor.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RyYW5zZm9ybXMvbWV0cmljX3RlbnNvci5weQ==) | `99.49% <100.00%> (+<0.01%)` | :arrow_up: |
| [pennylane/interfaces/batch/jax.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2ludGVyZmFjZXMvYmF0Y2gvamF4LnB5) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pennylane/interfaces/jax.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2ludGVyZmFjZXMvamF4LnB5) | `0.00% <0.00%> (-97.44%)` | :arrow_down: |
| [pennylane/devices/default\_qubit\_jax.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2RldmljZXMvZGVmYXVsdF9xdWJpdF9qYXgucHk=) | `0.00% <0.00%> (-95.00%)` | :arrow_down: |
| [pennylane/qnn/cost.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3Fubi9jb3N0LnB5) | `42.85% <0.00%> (-57.15%)` | :arrow_down: |
| [pennylane/transforms/classical\_jacobian.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL3RyYW5zZm9ybXMvY2xhc3NpY2FsX2phY29iaWFuLnB5) | `80.00% <0.00%> (-20.00%)` | :arrow_down: |
| [pennylane/math/utils.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL21hdGgvdXRpbHMucHk=) | `81.81% <0.00%> (-18.19%)` | :arrow_down: |
| [pennylane/math/multi\_dispatch.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL21hdGgvbXVsdGlfZGlzcGF0Y2gucHk=) | `86.84% <0.00%> (-13.16%)` | :arrow_down: |
| [pennylane/math/is\_independent.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL21hdGgvaXNfaW5kZXBlbmRlbnQucHk=) | `88.50% <0.00%> (-11.50%)` | :arrow_down: |
| [pennylane/collections/sum.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI#diff-cGVubnlsYW5lL2NvbGxlY3Rpb25zL3N1bS5weQ==) | `89.47% <0.00%> (-10.53%)` | :arrow_down: |
| ... and [14 more](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Last update [53b3b2b...34bcf38](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1987?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PennyLaneAI).


Patch:
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 1ddd22e87..dd4a03c33 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -528,6 +528,10 @@
 
 <h3>Bug fixes</h3>
 
+* Fixes a bug where the metric tensor was computed incorrectly when using
+  gates with `gate.inverse=True`.
+  [(#1987)](https://github.com/PennyLaneAI/pennylane/pull/1987)
+
 * Corrects the documentation of `qml.transforms.classical_jacobian`
   for the Autograd interface (and improves test coverage).
   [(#1978)](https://github.com/PennyLaneAI/pennylane/pull/1978)
diff --git a/pennylane/transforms/metric_tensor.py b/pennylane/transforms/metric_tensor.py
index bf344e092..71953c845 100644
--- a/pennylane/transforms/metric_tensor.py
+++ b/pennylane/transforms/metric_tensor.py
@@ -58,14 +58,17 @@ def expand_fn(
 def metric_tensor(
     tape, approx=None, diag_approx=None, allow_nonunitary=True, aux_wire=None, device_wires=None
 ):
-    r"""Returns a function that computes the block-diagonal approximation of the metric tensor
-    of a given QNode or quantum tape.
+    r"""Returns a function that computes the metric tensor of a given QNode or quantum tape.
 
     .. note::
 
         Only gates that have a single parameter and define a ``generator`` are supported.
         All other parametrized gates will be decomposed if possible.
 
+        The ``generator`` of all parametrized operations, with respect to which the
+        tensor is computed, are assumed to be Hermitian.
+        This is the case for unitary single-parameter operations.
+
     Args:
         tape (pennylane.QNode or .QuantumTape): quantum tape or QNode to find the metric tensor of
         approx (str): Which approximation of the metric tensor to compute.
@@ -370,6 +373,10 @@ def _metric_tensor_cov_matrix(tape, diag_approx):
             corresponding to one tape in the first return value
         list[list[float]]: Coefficients to scale the results for each observable, one inner list
             corresponding to one tape in the first return value
+
+    This method assumes the ``generator`` of all parametrized operations with respect to
+    which the tensor is computed to be Hermitian. This is the case for unitary single-parameter
+    operations.
     """
     # get the circuit graph
     graph = tape.graph
@@ -387,6 +394,8 @@ def _metric_tensor_cov_matrix(tape, diag_approx):
         # for each operation in the layer, get the generator
         for op in curr_ops:
             gen, s = op.generator
+            if op.inverse:
+                s = -s
             w = op.wires
             coeffs_list[-1].append(s)
 


Test patch:
diff --git a/tests/transforms/test_metric_tensor.py b/tests/transforms/test_metric_tensor.py
index 1e9c0d71e..c5d3f3171 100644
--- a/tests/transforms/test_metric_tensor.py
+++ b/tests/transforms/test_metric_tensor.py
@@ -309,7 +309,7 @@ class TestMetricTensor:
         def final(x, y, z, h, g, f):
             non_parametrized_layer(a, b, c)
             qml.RX(x, wires=0)
-            qml.RY(y, wires=1)
+            qml.RY(-y, wires=1).inv()
             qml.RZ(z, wires=2)
             non_parametrized_layer(a, b, c)
             qml.RY(f, wires=1)
@@ -628,8 +628,8 @@ def fubini_ansatz2(params, wires=None):
     qml.RY(params0, wires=0)
     qml.RY(params0, wires=1)
     qml.CNOT(wires=[0, 1])
-    qml.RX(params1, wires=0)
-    qml.RX(params1, wires=1)
+    qml.RX(params1, wires=0).inv()
+    qml.RX(params1, wires=1).inv()
 
 
 def fubini_ansatz3(params, wires=None):
@@ -640,7 +640,7 @@ def fubini_ansatz3(params, wires=None):
     qml.RX(fixed_pars[3], wires=1)
     qml.CNOT(wires=[0, 1])
     qml.CNOT(wires=[1, 2])
-    qml.RX(params0, wires=0)
+    qml.RX(params0, wires=0).inv()
     qml.RX(params0, wires=1)
     qml.CNOT(wires=[0, 1])
     qml.CNOT(wires=[1, 2])