@@ -46,6 +46,17 @@ namespace Tensorflow | |||||
public Tensor divide_no_nan(Tensor a, Tensor b, string name = null) | public Tensor divide_no_nan(Tensor a, Tensor b, string name = null) | ||||
=> math_ops.div_no_nan(a, b); | => math_ops.div_no_nan(a, b); | ||||
/// <summary> | |||||
/// Computes the Euclidean norm of elements across dimensions of a tensor. | |||||
/// </summary> | |||||
/// <param name="input_tensor">The tensor to reduce. Should have numeric type.</param> | |||||
/// <param name="axis">The dimensions to reduce. If `None` (the default), reduces all dimensions.Must be in the range `[-rank(input_tensor), rank(input_tensor))`</param> | |||||
/// <param name="keepdims">If true, retains reduced dimensions with length 1.</param> | |||||
/// <param name="name">A name for the operation (optional).</param> | |||||
/// <returns>The reduced tensor, of the same dtype as the input_tensor.</returns> | |||||
public Tensor reduce_euclidean_norm(Tensor input_tensor, Axis? axis = null, bool keepdims = false, string name = null) | |||||
=> math_ops.reduce_euclidean_norm(input_tensor, axis: axis, keepdims: keepdims, name); | |||||
public Tensor square(Tensor x, string name = null) | public Tensor square(Tensor x, string name = null) | ||||
=> math_ops.square(x, name: name); | => math_ops.square(x, name: name); | ||||
@@ -587,6 +587,17 @@ namespace Tensorflow | |||||
return _may_reduce_to_scalar(keepdims, axis, max); | return _may_reduce_to_scalar(keepdims, axis, max); | ||||
} | } | ||||
public static Tensor reduce_euclidean_norm(Tensor input_tensor, Axis axis = null, bool keepdims = false, string name = null) | |||||
{ | |||||
var r = _ReductionDims(input_tensor, axis); | |||||
var distance = tf.Context.ExecuteOp("EuclideanNorm", name, | |||||
new ExecuteOpArgs(input_tensor, r).SetAttributes(new | |||||
{ | |||||
keep_dims = keepdims | |||||
})); | |||||
return _may_reduce_to_scalar(keepdims, axis, distance); | |||||
} | |||||
public static Tensor reduce_max(Tensor input_tensor, Axis axis = null, bool keepdims = false, string name = null) | public static Tensor reduce_max(Tensor input_tensor, Axis axis = null, bool keepdims = false, string name = null) | ||||
{ | { | ||||
var r = _ReductionDims(input_tensor, axis); | var r = _ReductionDims(input_tensor, axis); | ||||
@@ -1,6 +1,8 @@ | |||||
using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
using System; | |||||
using System.Linq; | using System.Linq; | ||||
using Tensorflow; | using Tensorflow; | ||||
using Tensorflow.NumPy; | |||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
namespace TensorFlowNET.UnitTest.ManagedAPI | namespace TensorFlowNET.UnitTest.ManagedAPI | ||||
@@ -57,5 +59,26 @@ namespace TensorFlowNET.UnitTest.ManagedAPI | |||||
var actual = erf.ToArray<float>(); | var actual = erf.ToArray<float>(); | ||||
Assert.IsTrue(Equal(expected, actual)); | Assert.IsTrue(Equal(expected, actual)); | ||||
} | } | ||||
[TestMethod] | |||||
public void ReduceEuclideanNorm() | |||||
{ | |||||
var x = tf.constant(new[,] { { 1, 2, 3 }, { 1, 1, 1 } }); | |||||
Assert.AreEqual(tf.math.reduce_euclidean_norm(x).numpy(), 4); | |||||
var y = tf.constant(new[,] { { 1, 2, 3 }, { 1, 1, 1 } }, dtype: tf.float32); | |||||
Assert.IsTrue(Equal(tf.math.reduce_euclidean_norm(y).numpy(), 4.1231055f)); | |||||
Assert.IsTrue(Equal(tf.math.reduce_euclidean_norm(y, 0).ToArray<float>(), | |||||
new float[] { np.sqrt(2f), np.sqrt(5f), np.sqrt(10f) })); | |||||
Assert.IsTrue(Equal(tf.math.reduce_euclidean_norm(y, 1).ToArray<float>(), | |||||
new float[] { np.sqrt(14f), np.sqrt(3f) })); | |||||
Assert.IsTrue(Equal(tf.math.reduce_euclidean_norm(y, 1, keepdims: true).ToArray<float>(), | |||||
new float[] { np.sqrt(14f), np.sqrt(3f) })); | |||||
Assert.AreEqual(tf.math.reduce_euclidean_norm(y, (0, 1)).numpy(), np.sqrt(17f)); | |||||
} | |||||
} | } | ||||
} | } |