Repository: PennyLaneAI/pennylane

Issue:
[unitaryhack] Deprecate `qml.inv`
*This issue has been tagged for contributions during [unitaryHACK](https://unitaryfund.github.io/unitaryhack/participating-projects.html)*

Currently, PennyLane has two functions for inverting quantum operations:

* [`qml.inv()`](https://github.com/PennyLaneAI/pennylane/blob/4ece39acb42dacafd5b5cc566c4d3f0512dfa6fb/pennylane/utils.py#L236) accepts a list of operations, unqueues them from the tape, inverts them, and re-queues.

* [`qml.adjoint()`](https://github.com/PennyLaneAI/pennylane/blob/master/pennylane/transforms/adjoint.py) transforms a function that queues operations to one that queues the inverse.

While both have very different internal implementations, for end users, they provide pretty much the same functionality; `qml.adjoint()`, however, is more general and `qml.inv()` has been marked for removal.

Further, the term `adjoint` is already in use for the adjoint differentiation method, and could be confusing to have two independent concepts share the same term.

So we can kill two birds with one stone:

- Remove `qml.inv()`
- Rename the `qml.adjoint()` transform to `qml.inv()`.

This has the advantage that existing users code that uses `qml.inv()` should continue to work as is.


Discussion:
Hi! Is this issue an open issue or has it already been assigned?
Hi @tgag17, it's still an open issue. :slightly_smiling_face: (The assignment was from a while back.)
Hi! I have been working on this issue. An integral part of the issue is to rename the qml.adjoint() transform to qml.inv(). I had some doubts about the same. 
-  If we want to enable the existing codes that use qml.inv() shouldn't the data type of the argument change too when the renaming is done as qml.adjoint() takes a function while qml.inv() takes an operation list.
- There would be a drawback as the existing codes that use qml.adjoint() will become redundant

Thanks!
Hi @tgag17 this is a great point, thanks for pointing it out. Perhaps we should modify this issue --- instead, we could keep `qml.adjoint` as is, and mark `qml.inv()` for deprecation (with a deprecation message that informs users to switch to `qml.adjoint`).
Yes! That seems like a good option 👍 
@tgag17 feel free to tackle this --- I will edit the title of this issue 🙂 

Resolving patch:
diff --git a/pennylane/utils.py b/pennylane/utils.py
--- a/pennylane/utils.py
+++ b/pennylane/utils.py
@@ -22,6 +22,7 @@
 import itertools
 import numbers
 from operator import matmul
+import warnings
 
 import numpy as np
 
@@ -239,6 +240,10 @@ def inv(operation_list):
     If the inversion happens inside a QNode, the operations are removed and requeued
     in the reversed order for proper inversion.
 
+    .. warning::
+        Use of :func:`~.inv()` is deprecated and should be replaced with
+        :func:`~.adjoint()`.
+
     **Example:**
 
     The following example illuminates the inversion of a template:
@@ -291,6 +296,11 @@ def circuit2():
     Returns:
         List[~.Operation]: The inverted list of operations
     """
+
+    warnings.warn(
+        "Use of qml.inv() is deprecated and should be replaced with qml.adjoint().",
+        UserWarning,
+    )
     if isinstance(operation_list, qml.operation.Operation):
         operation_list = [operation_list]
     elif operation_list is None:


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -833,3 +833,12 @@ def test_non_operations_in_list(self, arg):
             ValueError, match="The given operation_list does not only contain Operations"
         ):
             pu.inv(arg)
+
+    def test_warning(self):
+        """Test that the warning is generated."""
+
+        with pytest.warns(
+            UserWarning,
+            match=r"Use of qml\.inv\(\) is deprecated and should be replaced with qml\.adjoint\(\)\.",
+        ):
+            qml.inv(qml.Hadamard(wires=[0]))