From ee7bb7cee8fc365f1fe7acd4295c4054fe7ac7c8 Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Sat, 21 Aug 2021 14:25:49 -0500 Subject: [PATCH] np.linalg.norm --- src/TensorFlowNET.Core/APIs/tf.linalg.cs | 3 +++ src/TensorFlowNET.Core/Binding.Util.cs | 2 ++ .../NumPy/Implementation/LinearAlgebraImpl.cs | 14 +++++++++++++- src/TensorFlowNET.Core/Operations/linalg_ops.cs | 15 +++++++++++++++ src/TensorFlowNET.Core/Operations/nn_impl.py.cs | 10 ++++++++++ .../NumPy/LinearAlgebra.Test.cs | 8 ++++++++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/TensorFlowNET.Core/APIs/tf.linalg.cs b/src/TensorFlowNET.Core/APIs/tf.linalg.cs index 2b6051e0..1fef9c9e 100644 --- a/src/TensorFlowNET.Core/APIs/tf.linalg.cs +++ b/src/TensorFlowNET.Core/APIs/tf.linalg.cs @@ -39,6 +39,9 @@ namespace Tensorflow public Tensor matmul(Tensor a, Tensor b) => math_ops.matmul(a, b); + public Tensor norm(Tensor a, string ord = "euclidean", Axis axis = null, string name = null) + => ops.norm(a, ord: ord, axis: axis, name: name); + public Tensor batch_matmul(Tensor x, Tensor y, bool adj_x = false, bool adj_y = false, string name = null) => math_ops.batch_matmul(x, y, adj_x: adj_x, adj_y: adj_y, name: name); diff --git a/src/TensorFlowNET.Core/Binding.Util.cs b/src/TensorFlowNET.Core/Binding.Util.cs index c8379565..1dc8a035 100644 --- a/src/TensorFlowNET.Core/Binding.Util.cs +++ b/src/TensorFlowNET.Core/Binding.Util.cs @@ -166,6 +166,8 @@ namespace Tensorflow return arr.Count; case IEnumerable enumerable: return enumerable.OfType().Count(); + case Axis axis: + return axis.size; case Shape arr: return arr.ndim; } diff --git a/src/TensorFlowNET.Core/NumPy/Implementation/LinearAlgebraImpl.cs b/src/TensorFlowNET.Core/NumPy/Implementation/LinearAlgebraImpl.cs index 92ef6b69..7d287552 100644 --- a/src/TensorFlowNET.Core/NumPy/Implementation/LinearAlgebraImpl.cs +++ b/src/TensorFlowNET.Core/NumPy/Implementation/LinearAlgebraImpl.cs @@ -1,14 +1,26 @@ using System; using System.Collections.Generic; using System.Text; +using static Tensorflow.Binding; namespace Tensorflow.NumPy { public class LinearAlgebraImpl { + [AutoNumPy] public NDArray lstsq(NDArray a, NDArray b, string rcond = "warn") + => new NDArray(tf.linalg.lstsq(a, b)); + + [AutoNumPy] + public NDArray norm(NDArray a, Axis axis = null) { - return a; + if (a.dtype.is_integer()) + { + var float_a = math_ops.cast(a, dtype: tf.float32); + return new NDArray(tf.linalg.norm(float_a, axis: axis)); + } + + return new NDArray(tf.linalg.norm(a, axis: axis)); } } } diff --git a/src/TensorFlowNET.Core/Operations/linalg_ops.cs b/src/TensorFlowNET.Core/Operations/linalg_ops.cs index b6304899..024ea14d 100644 --- a/src/TensorFlowNET.Core/Operations/linalg_ops.cs +++ b/src/TensorFlowNET.Core/Operations/linalg_ops.cs @@ -52,6 +52,21 @@ namespace Tensorflow return _composite_impl(matrix, rhs, l2_regularizer: l2_regularizer); } + public Tensor norm(Tensor tensor, string ord = "euclidean", Axis axis = null, string name = null, bool keepdims = true) + { + var is_matrix_norm = axis != null && len(axis) == 2; + return tf_with(ops.name_scope(name, default_name: "norm", tensor), scope => + { + if (is_matrix_norm) + throw new NotImplementedException(""); + var result = math_ops.sqrt(math_ops.reduce_sum(tensor * math_ops.conj(tensor), axis, keepdims: true)); + + if(!keepdims) + result = array_ops.squeeze(result, axis); + return result; + }); + } + Tensor _composite_impl(Tensor matrix, Tensor rhs, Tensor l2_regularizer = null) { Shape matrix_shape = matrix.shape.dims.Skip(matrix.shape.ndim - 2).ToArray(); diff --git a/src/TensorFlowNET.Core/Operations/nn_impl.py.cs b/src/TensorFlowNET.Core/Operations/nn_impl.py.cs index 153c050b..7e2ed36f 100644 --- a/src/TensorFlowNET.Core/Operations/nn_impl.py.cs +++ b/src/TensorFlowNET.Core/Operations/nn_impl.py.cs @@ -109,6 +109,16 @@ namespace Tensorflow }); } + public static Tensor normalize(Tensor tensor, string ord = "euclidean", Axis axis = null, string name = null) + { + return tf_with(ops.name_scope(name, "normalize", tensor), scope => + { + var norm = tf.linalg.norm(tensor, ord: ord, axis: axis, name: name); + var normalized = tensor / norm; + return normalized; + }); + } + public static Tensor batch_normalization(Tensor x, Tensor mean, Tensor variance, diff --git a/test/TensorFlowNET.UnitTest/NumPy/LinearAlgebra.Test.cs b/test/TensorFlowNET.UnitTest/NumPy/LinearAlgebra.Test.cs index 81c5e2c3..d6beb259 100644 --- a/test/TensorFlowNET.UnitTest/NumPy/LinearAlgebra.Test.cs +++ b/test/TensorFlowNET.UnitTest/NumPy/LinearAlgebra.Test.cs @@ -19,5 +19,13 @@ namespace TensorFlowNET.UnitTest.NumPy { } + + [TestMethod] + public void norm() + { + var x = np.arange(9) - 4; + var y = x.reshape((3, 3)); + var norm = np.linalg.norm(y); + } } }