From 380b260fd32b21eea735675ca3b21ca368b778f5 Mon Sep 17 00:00:00 2001 From: krbhanushali Date: Tue, 31 Aug 2021 09:42:31 +0530 Subject: [PATCH 1/2] Added pinv to tensorflow backend based on: https://numpy.org/doc/stable/reference/generated/numpy.linalg.pinv.html --- .../backends/tensorflow/tensorflow_backend.py | 23 +++++++++++++++++++ .../tensorflow/tensorflow_backend_test.py | 12 ++++++++++ 2 files changed, 35 insertions(+) diff --git a/tensornetwork/backends/tensorflow/tensorflow_backend.py b/tensornetwork/backends/tensorflow/tensorflow_backend.py index 0cf960838..39e1ddb73 100644 --- a/tensornetwork/backends/tensorflow/tensorflow_backend.py +++ b/tensornetwork/backends/tensorflow/tensorflow_backend.py @@ -430,3 +430,26 @@ def eps(self, dtype: Type[np.number]) -> float: float: Machine epsilon. """ return tf.experimental.numpy.finfo(dtype).eps + + def pinv(self, tensor: Tensor, rcond: float = 1E-15, hermitian: bool = False) -> Tensor: + """ + Compute the Moore-Penrose/Pseudo inverse of a tensor. + + Args: + tensor: A tensor. + rcond: Cutoff for small singular values + hermitian: If True, matrix provided in function argument is assumed to be + Hermitian (symmetric if real-valued) + This argument is not supported in the TensorFlow + backend and an error will be raised if it is + specified. + + Returns: + tensor: The pseudo inverse of `tensor` + """ + if hermitian != False: + errstr = (f"hermitian = {hermitian} must be False (the default)" + f"with TensorFlow backend.") + raise NotImplementedError(errstr) + + return tf.linalg.pinv(tensor, rcond=rcond) \ No newline at end of file diff --git a/tensornetwork/backends/tensorflow/tensorflow_backend_test.py b/tensornetwork/backends/tensorflow/tensorflow_backend_test.py index 134c21bfd..767eb2e45 100644 --- a/tensornetwork/backends/tensorflow/tensorflow_backend_test.py +++ b/tensornetwork/backends/tensorflow/tensorflow_backend_test.py @@ -629,3 +629,15 @@ def test_power(dtype): def test_eps(dtype): backend = tensorflow_backend.TensorFlowBackend() assert backend.eps(dtype) == tf.experimental.numpy.finfo(dtype).eps + +def test_pinv(): + backend = tensorflow_backend.TensorFlowBackend() + np.random.seed(10) + tensor = np.random.rand(2, 3, 4) + rcond = np.random.rand(1)[0] * 1E-14 + expected = tf.linalg.pinv(tensor, rcond) + actual = backend.pinv(tensor, rcond) + np.testing.assert_allclose(expected, actual) + expected = tf.linalg.pinv(tensor) + actual = backend.pinv(tensor) + np.testing.assert_allclose(expected, actual) \ No newline at end of file From 3f6d0a4116cc2dfff62c60de469eaa298941e218 Mon Sep 17 00:00:00 2001 From: krbhanushali Date: Tue, 31 Aug 2021 09:42:31 +0530 Subject: [PATCH 2/2] Added pinv to tensorflow_backend Issue : https://github.com/google/TensorNetwork/issues/844 --- .../backends/tensorflow/tensorflow_backend.py | 23 +++++++++++++++++++ .../tensorflow/tensorflow_backend_test.py | 12 ++++++++++ 2 files changed, 35 insertions(+) diff --git a/tensornetwork/backends/tensorflow/tensorflow_backend.py b/tensornetwork/backends/tensorflow/tensorflow_backend.py index 0cf960838..39e1ddb73 100644 --- a/tensornetwork/backends/tensorflow/tensorflow_backend.py +++ b/tensornetwork/backends/tensorflow/tensorflow_backend.py @@ -430,3 +430,26 @@ def eps(self, dtype: Type[np.number]) -> float: float: Machine epsilon. """ return tf.experimental.numpy.finfo(dtype).eps + + def pinv(self, tensor: Tensor, rcond: float = 1E-15, hermitian: bool = False) -> Tensor: + """ + Compute the Moore-Penrose/Pseudo inverse of a tensor. + + Args: + tensor: A tensor. + rcond: Cutoff for small singular values + hermitian: If True, matrix provided in function argument is assumed to be + Hermitian (symmetric if real-valued) + This argument is not supported in the TensorFlow + backend and an error will be raised if it is + specified. + + Returns: + tensor: The pseudo inverse of `tensor` + """ + if hermitian != False: + errstr = (f"hermitian = {hermitian} must be False (the default)" + f"with TensorFlow backend.") + raise NotImplementedError(errstr) + + return tf.linalg.pinv(tensor, rcond=rcond) \ No newline at end of file diff --git a/tensornetwork/backends/tensorflow/tensorflow_backend_test.py b/tensornetwork/backends/tensorflow/tensorflow_backend_test.py index 134c21bfd..767eb2e45 100644 --- a/tensornetwork/backends/tensorflow/tensorflow_backend_test.py +++ b/tensornetwork/backends/tensorflow/tensorflow_backend_test.py @@ -629,3 +629,15 @@ def test_power(dtype): def test_eps(dtype): backend = tensorflow_backend.TensorFlowBackend() assert backend.eps(dtype) == tf.experimental.numpy.finfo(dtype).eps + +def test_pinv(): + backend = tensorflow_backend.TensorFlowBackend() + np.random.seed(10) + tensor = np.random.rand(2, 3, 4) + rcond = np.random.rand(1)[0] * 1E-14 + expected = tf.linalg.pinv(tensor, rcond) + actual = backend.pinv(tensor, rcond) + np.testing.assert_allclose(expected, actual) + expected = tf.linalg.pinv(tensor) + actual = backend.pinv(tensor) + np.testing.assert_allclose(expected, actual) \ No newline at end of file