Repository: PennyLaneAI/pennylane
Pull request #1158 (2021-03-23 17:43:25)

Added adjoints for excititation gates
**Context:**
Add adjoint to excitiation gates.

Also updated the adjoint logic for `U2`, and `U3` operations so that they no longer rely on `.inv()`

github-actions[bot]: Hello. You may have forgotten to update the changelog!
Please edit [.github/CHANGELOG.md](/PennyLaneAI/pennylane/blob/master/.github/CHANGELOG.md) with:
* A one-to-two sentence description of the change. You may include a small working example for new features.
* A link back to this PR.
* Your name (or GitHub username) in the contributors section.
codecov[bot]: # [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158?src=pr&el=h1) Report
> Merging [#1158](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158?src=pr&el=desc) (e26fbb7) into [master](https://codecov.io/gh/PennyLaneAI/pennylane/commit/104ffbbbadf2d236458970f58e35fdc5df636910?el=desc) (104ffbb) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158/graphs/tree.svg?width=650&height=150&src=pr&token=9S3YzlUgGk)](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #1158   +/-   ##
=======================================
  Coverage   98.05%   98.05%           
=======================================
  Files         142      142           
  Lines       10522    10531    +9     
=======================================
+ Hits        10317    10326    +9     
  Misses        205      205           
```


| [Impacted Files](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pennylane/ops/qubit.py](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158/diff?src=pr&el=tree#diff-cGVubnlsYW5lL29wcy9xdWJpdC5weQ==) | `98.21% <100.00%> (+0.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158?src=pr&el=footer). Last update [104ffbb...e26fbb7](https://codecov.io/gh/PennyLaneAI/pennylane/pull/1158?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/pennylane/ops/qubit.py b/pennylane/ops/qubit.py
index ff433e447..e3f8619bc 100644
--- a/pennylane/ops/qubit.py
+++ b/pennylane/ops/qubit.py
@@ -1539,8 +1539,10 @@ class U2(Operation):
         return decomp_ops
 
     def adjoint(self, do_queue=False):
-        # TODO(chase): Replace the `inv()` by instead modifying the parameters.
-        return U2(*self.parameters, wires=self.wires, do_queue=do_queue).inv()
+        phi, lam = self.parameters
+        new_lam = (np.pi - phi) % (2 * np.pi)
+        new_phi = (np.pi - lam) % (2 * np.pi)
+        return U2(new_phi, new_lam, wires=self.wires, do_queue=do_queue)
 
 
 class U3(Operation):
@@ -1606,8 +1608,10 @@ class U3(Operation):
         return decomp_ops
 
     def adjoint(self, do_queue=False):
-        # TODO(chase): Replace the `inv()` by instead modifying the parameters.
-        return U3(*self.parameters, wires=self.wires, do_queue=do_queue).inv()
+        theta, phi, lam = self.parameters
+        new_lam = (np.pi - phi) % (2 * np.pi)
+        new_phi = (np.pi - lam) % (2 * np.pi)
+        return U3(theta, new_phi, new_lam, wires=self.wires, do_queue=do_queue)
 
 
 # =============================================================================
@@ -1678,6 +1682,10 @@ class SingleExcitation(Operation):
         ]
         return decomp_ops
 
+    def adjoint(self, do_queue=False):
+        (phi,) = self.parameters
+        return SingleExcitation(-phi, wires=self.wires, do_queue=do_queue)
+
 
 class SingleExcitationMinus(Operation):
     r"""SingleExcitationMinus(phi, wires)
@@ -1717,6 +1725,10 @@ class SingleExcitationMinus(Operation):
 
         return np.array([[e, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, e]])
 
+    def adjoint(self, do_queue=False):
+        (phi,) = self.parameters
+        return SingleExcitationMinus(-phi, wires=self.wires, do_queue=do_queue)
+
 
 class SingleExcitationPlus(Operation):
     r"""SingleExcitationPlus(phi, wires)
@@ -1756,6 +1768,10 @@ class SingleExcitationPlus(Operation):
 
         return np.array([[e, 0, 0, 0], [0, c, -s, 0], [0, s, c, 0], [0, 0, 0, e]])
 
+    def adjoint(self, do_queue=False):
+        (phi,) = self.parameters
+        return SingleExcitationPlus(-phi, wires=self.wires, do_queue=do_queue)
+
 
 # =============================================================================
 # Arbitrary operations
@@ -2155,6 +2171,10 @@ class DoubleExcitation(Operation):
         ]
         return decomp_ops
 
+    def adjoint(self, do_queue=False):
+        (theta,) = self.parameters
+        return DoubleExcitation(-theta, wires=self.wires, do_queue=do_queue)
+
 
 class DoubleExcitationPlus(Operation):
     r"""DoubleExcitationPlus(phi, wires)
@@ -2211,6 +2231,10 @@ class DoubleExcitationPlus(Operation):
 
         return U
 
+    def adjoint(self, do_queue=False):
+        (theta,) = self.parameters
+        return DoubleExcitationPlus(-theta, wires=self.wires, do_queue=do_queue)
+
 
 class DoubleExcitationMinus(Operation):
     r"""DoubleExcitationMinus(phi, wires)
@@ -2267,6 +2291,10 @@ class DoubleExcitationMinus(Operation):
 
         return U
 
+    def adjoint(self, do_queue=False):
+        (theta,) = self.parameters
+        return DoubleExcitationMinus(-theta, wires=self.wires, do_queue=do_queue)
+
 
 # =============================================================================
 # State preparation


Test patch:
diff --git a/tests/ops/test_qubit_ops.py b/tests/ops/test_qubit_ops.py
index 009f74e0c..24d244649 100644
--- a/tests/ops/test_qubit_ops.py
+++ b/tests/ops/test_qubit_ops.py
@@ -369,6 +369,12 @@ class TestOperations:
             qml.QFT(wires=[1, 2, 3]),
             qml.ControlledQubitUnitary(np.eye(2) * 1j, wires=[0], control_wires=[2]),
             qml.MultiControlledX(control_wires=[0, 1], wires=2, control_values='01'),
+            qml.SingleExcitation(0.123, wires=[0, 3]),
+            qml.SingleExcitationPlus(0.123, wires=[0, 3]),
+            qml.SingleExcitationMinus(0.123, wires=[0, 3]),
+            qml.DoubleExcitation(0.123, wires=[0, 1, 2, 3]),
+            qml.DoubleExcitationPlus(0.123, wires=[0, 1, 2, 3]),
+            qml.DoubleExcitationMinus(0.123, wires=[0, 1, 2, 3]),
         ])
     def test_adjoint_unitaries(self, op, tol):
         op_d = op.adjoint()