From 40b6376b57b8490420936128e94c2f766f72fdb2 Mon Sep 17 00:00:00 2001
From: Gordian Edenhofer <gordian.edenhofer@gmail.com>
Date: Thu, 23 Jan 2020 13:58:53 +0100
Subject: [PATCH] operator.py: Raise not-implemented in matmul call

Contrary to other overloaded operators, the `__matmul__` call apparently
needs to raise an exception instead of returning `NotImplemented`. This
behaviour can be seen for example in:

```python
psp = ift.RGSpace(512)
m = ift.MaskOperator(ift.Field.from_raw(psp, np.random.randint(0, 2, 512)))
m(ift.from_random("normal", m.domain).val) is NotImplemented
```

which should be invalid and raise an exception but previously returned
`True` instead.
---
 nifty6/operators/linear_operator.py | 2 +-
 nifty6/operators/operator.py        | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/nifty6/operators/linear_operator.py b/nifty6/operators/linear_operator.py
index 9d10390b1..6be9bb455 100644
--- a/nifty6/operators/linear_operator.py
+++ b/nifty6/operators/linear_operator.py
@@ -175,7 +175,7 @@ class LinearOperator(Operator):
         from ..linearization import Linearization
         if isinstance(x, Linearization):
             return x.new(self(x._val), self(x._jac))
-        return self.__matmul__(x)
+        return self@x
 
     def times(self, x):
         """Applies the Operator to a given Field.
diff --git a/nifty6/operators/operator.py b/nifty6/operators/operator.py
index 31b24772b..c731c4571 100644
--- a/nifty6/operators/operator.py
+++ b/nifty6/operators/operator.py
@@ -79,6 +79,11 @@ class Operator(metaclass=NiftyMeta):
             return NotImplemented
         return _OpChain.make((self, x))
 
+    def __rmatmul__(self, x):
+        if not isinstance(x, Operator):
+            return NotImplemented
+        return _OpChain.make((x, self))
+
     def partial_insert(self, x):
         from ..multi_domain import MultiDomain
         if not isinstance(x, Operator):
-- 
GitLab