From 236be30b6dc650d4c9ad72f8d3d5e2a24695dd6b Mon Sep 17 00:00:00 2001 From: lilinus Date: Thu, 12 Dec 2024 09:28:29 +0100 Subject: [PATCH 01/11] Use IRootFunctions in Tensor.StdDev --- .../ref/System.Numerics.Tensors.netcore.cs | 2 +- .../Numerics/Tensors/netcore/TensorExtensions.cs | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs index c3a9f5be9ee36f..b60cdd7c2b17fb 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs @@ -487,7 +487,7 @@ public static void ResizeTo(scoped in System.Numerics.Tensors.Tensor tenso public static ref readonly System.Numerics.Tensors.TensorSpan StackAlongDimension(scoped System.ReadOnlySpan> tensors, in System.Numerics.Tensors.TensorSpan destination, int dimension) { throw null; } public static System.Numerics.Tensors.Tensor Stack(params scoped System.ReadOnlySpan> tensors) { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Stack(scoped in System.ReadOnlySpan> tensors, in System.Numerics.Tensors.TensorSpan destination) { throw null; } - public static T StdDev(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IFloatingPoint, System.Numerics.IPowerFunctions, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity { throw null; } + public static T StdDev(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IFloatingPoint, System.Numerics.IPowerFunctions, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IRootFunctions { throw null; } public static System.Numerics.Tensors.Tensor Subtract(in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.ReadOnlyTensorSpan y) where T : System.Numerics.ISubtractionOperators { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Subtract(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, scoped in System.Numerics.Tensors.ReadOnlyTensorSpan y, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.ISubtractionOperators { throw null; } public static System.Numerics.Tensors.Tensor Subtract(in System.Numerics.Tensors.ReadOnlyTensorSpan x, T y) where T : System.Numerics.ISubtractionOperators { throw null; } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs index 1274b20b8cf9eb..c0b08c707cef38 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs @@ -3512,7 +3512,7 @@ public static ref readonly TensorSpan StackAlongDimension(scoped ReadOnlyS /// The to take the standard deviation of. /// representing the standard deviation. public static T StdDev(in ReadOnlyTensorSpan x) - where T : IFloatingPoint, IPowerFunctions, IAdditionOperators, IAdditiveIdentity + where T : IFloatingPoint, IPowerFunctions, IAdditionOperators, IAdditiveIdentity, IRootFunctions { T mean = Average(x); Span span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength); @@ -3522,16 +3522,7 @@ public static T StdDev(in ReadOnlyTensorSpan x) TensorPrimitives.Pow((ReadOnlySpan)output, T.CreateChecked(2), output); T sum = TensorPrimitives.Sum((ReadOnlySpan)output); T variance = sum / T.CreateChecked(x._shape._memoryLength); - - if (typeof(T) == typeof(float)) - { - return T.CreateChecked(MathF.Sqrt(float.CreateChecked(variance))); - } - if (typeof(T) == typeof(double)) - { - return T.CreateChecked(Math.Sqrt(double.CreateChecked(variance))); - } - return T.Pow(variance, T.CreateChecked(0.5)); + return T.Sqrt(variance); } #endregion From 25ab78b6cc41d845d799f72106cb3f07624f0800 Mon Sep 17 00:00:00 2001 From: lilinus Date: Fri, 13 Dec 2024 11:10:18 +0100 Subject: [PATCH 02/11] Try fix api compat issue --- .../src/CompatibilitySuppressions.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml index ae2ea3d401a7b1..dff0e371e5ae43 100644 --- a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml @@ -253,4 +253,11 @@ lib/net9.0/System.Numerics.Tensors.dll true - \ No newline at end of file + + CP0021 + M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0})``0:System.Numerics.IRootFunctions{``0} + lib/net9.0/System.Numerics.Tensors.dll + lib/net9.0/System.Numerics.Tensors.dll + true + + From 76307a66b8ae1809710ff67d58fc2cde6fcd7860 Mon Sep 17 00:00:00 2001 From: lilinus Date: Fri, 13 Dec 2024 11:11:58 +0100 Subject: [PATCH 03/11] Replace Pow+Sum with SumOfSquares --- .../src/System/Numerics/Tensors/netcore/TensorExtensions.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs index c0b08c707cef38..9ea68199db8c4a 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs @@ -3519,8 +3519,7 @@ public static T StdDev(in ReadOnlyTensorSpan x) Span output = new T[x.FlattenedLength]; TensorPrimitives.Subtract(span, mean, output); TensorPrimitives.Abs(output, output); - TensorPrimitives.Pow((ReadOnlySpan)output, T.CreateChecked(2), output); - T sum = TensorPrimitives.Sum((ReadOnlySpan)output); + T sum = TensorPrimitives.SumOfSquares((ReadOnlySpan)output); T variance = sum / T.CreateChecked(x._shape._memoryLength); return T.Sqrt(variance); } From ae0f95b1b4213ea97c5578557a73fef3b08ea1ac Mon Sep 17 00:00:00 2001 From: lilinus Date: Fri, 13 Dec 2024 11:18:39 +0100 Subject: [PATCH 04/11] Drop IPowerFunctions constraint --- .../ref/System.Numerics.Tensors.netcore.cs | 2 +- .../src/System/Numerics/Tensors/netcore/TensorExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs index b60cdd7c2b17fb..9aaec4515e23a5 100644 --- a/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs +++ b/src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs @@ -487,7 +487,7 @@ public static void ResizeTo(scoped in System.Numerics.Tensors.Tensor tenso public static ref readonly System.Numerics.Tensors.TensorSpan StackAlongDimension(scoped System.ReadOnlySpan> tensors, in System.Numerics.Tensors.TensorSpan destination, int dimension) { throw null; } public static System.Numerics.Tensors.Tensor Stack(params scoped System.ReadOnlySpan> tensors) { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Stack(scoped in System.ReadOnlySpan> tensors, in System.Numerics.Tensors.TensorSpan destination) { throw null; } - public static T StdDev(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IFloatingPoint, System.Numerics.IPowerFunctions, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IRootFunctions { throw null; } + public static T StdDev(in System.Numerics.Tensors.ReadOnlyTensorSpan x) where T : System.Numerics.IFloatingPoint, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IRootFunctions { throw null; } public static System.Numerics.Tensors.Tensor Subtract(in System.Numerics.Tensors.ReadOnlyTensorSpan x, in System.Numerics.Tensors.ReadOnlyTensorSpan y) where T : System.Numerics.ISubtractionOperators { throw null; } public static ref readonly System.Numerics.Tensors.TensorSpan Subtract(scoped in System.Numerics.Tensors.ReadOnlyTensorSpan x, scoped in System.Numerics.Tensors.ReadOnlyTensorSpan y, in System.Numerics.Tensors.TensorSpan destination) where T : System.Numerics.ISubtractionOperators { throw null; } public static System.Numerics.Tensors.Tensor Subtract(in System.Numerics.Tensors.ReadOnlyTensorSpan x, T y) where T : System.Numerics.ISubtractionOperators { throw null; } diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs index 9ea68199db8c4a..d188b32841c265 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs @@ -3512,7 +3512,7 @@ public static ref readonly TensorSpan StackAlongDimension(scoped ReadOnlyS /// The to take the standard deviation of. /// representing the standard deviation. public static T StdDev(in ReadOnlyTensorSpan x) - where T : IFloatingPoint, IPowerFunctions, IAdditionOperators, IAdditiveIdentity, IRootFunctions + where T : IFloatingPoint, IAdditionOperators, IAdditiveIdentity, IRootFunctions { T mean = Average(x); Span span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength); From b41b499b2f38f10def56ee8670cd191a4d077029 Mon Sep 17 00:00:00 2001 From: lilinus Date: Tue, 17 Dec 2024 09:37:15 +0100 Subject: [PATCH 05/11] Try fix compatability supression --- .../src/CompatibilitySuppressions.xml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml index dff0e371e5ae43..b5530185ac5143 100644 --- a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml @@ -253,6 +253,13 @@ lib/net9.0/System.Numerics.Tensors.dll true + + CP0021 + M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0})``0:System.Numerics.IRootFunctions{``0} + lib/net8.0/System.Numerics.Tensors.dll + lib/net8.0/System.Numerics.Tensors.dll + true + CP0021 M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0})``0:System.Numerics.IRootFunctions{``0} @@ -260,4 +267,4 @@ lib/net9.0/System.Numerics.Tensors.dll true - + \ No newline at end of file From f4b265de088ada52d775bec54c5678cb12afd927 Mon Sep 17 00:00:00 2001 From: lilinus Date: Tue, 17 Dec 2024 10:07:02 +0100 Subject: [PATCH 06/11] Fix StdDev stride issue --- .../Tensors/netcore/TensorExtensions.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs index d188b32841c265..443441e9419b69 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs @@ -3515,11 +3515,10 @@ public static T StdDev(in ReadOnlyTensorSpan x) where T : IFloatingPoint, IAdditionOperators, IAdditiveIdentity, IRootFunctions { T mean = Average(x); - Span span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength); - Span output = new T[x.FlattenedLength]; - TensorPrimitives.Subtract(span, mean, output); - TensorPrimitives.Abs(output, output); - T sum = TensorPrimitives.SumOfSquares((ReadOnlySpan)output); + Tensor temp = CreateUninitialized(x.Lengths); + Subtract(x, mean, temp); + Abs(temp, temp); + T sum = SumOfSquares(temp); T variance = sum / T.CreateChecked(x._shape._memoryLength); return T.Sqrt(variance); } @@ -6654,6 +6653,19 @@ public static T Sum(scoped in ReadOnlyTensorSpan x) } #endregion + #region SumOfSquares + /// + /// Sums the squared elements of the specified tensor. + /// + /// Tensor to sum squares of + /// + internal static T SumOfSquares(scoped in ReadOnlyTensorSpan x) + where T : IAdditionOperators, IAdditiveIdentity, IMultiplyOperators + { + return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.SumOfSquares); + } + #endregion + #region Tan /// Computes the element-wise tangent of the value in the specified tensor. /// The to take the sin of. From fd1e3637ebacb01a2aa9089be9ef27e3e320a2b7 Mon Sep 17 00:00:00 2001 From: lilinus Date: Tue, 17 Dec 2024 11:05:16 +0100 Subject: [PATCH 07/11] Add regression test --- .../System.Numerics.Tensors/tests/TensorTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs index a418230aff14a0..71bb9ee4603116 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs @@ -1103,6 +1103,15 @@ public static void TensorStdDevTests() Tensor t0 = Tensor.Create((Enumerable.Range(0, 4).Select(i => (float)i)), [2, 2]); Assert.Equal(StdDev([0, 1, 2, 3]), Tensor.StdDev(t0), .1); + + // Test that non-contiguous calculations work + Tensor fourByFour = Tensor.Create([4, 4]); + fourByFour[[0, 0]] = 1f; + fourByFour[[0, 1]] = 1f; + fourByFour[[1, 0]] = 1f; + fourByFour[[1, 1]] = 1f; + ReadOnlyTensorSpan upperLeft = fourByFour.AsReadOnlyTensorSpan().Slice([0..2, 0..2]); + Assert.Equal(1f, Tensor.StdDev(upperLeft)); } public static float StdDev(float[] values) From 0d1e7c4e43247dc1d8bce35ee8fa69489df75e3f Mon Sep 17 00:00:00 2001 From: lilinus Date: Tue, 17 Dec 2024 11:05:42 +0100 Subject: [PATCH 08/11] fix test --- src/libraries/System.Numerics.Tensors/tests/TensorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs index 71bb9ee4603116..6d4d4298eb2ae3 100644 --- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs +++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs @@ -1111,7 +1111,7 @@ public static void TensorStdDevTests() fourByFour[[1, 0]] = 1f; fourByFour[[1, 1]] = 1f; ReadOnlyTensorSpan upperLeft = fourByFour.AsReadOnlyTensorSpan().Slice([0..2, 0..2]); - Assert.Equal(1f, Tensor.StdDev(upperLeft)); + Assert.Equal(0f, Tensor.StdDev(upperLeft)); } public static float StdDev(float[] values) From aef23417a25cab38ba4c92107a89710dae49a24b Mon Sep 17 00:00:00 2001 From: lilinus Date: Tue, 17 Dec 2024 11:23:45 +0100 Subject: [PATCH 09/11] Use FlattenedLength in StdDev --- .../src/System/Numerics/Tensors/netcore/TensorExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs index 443441e9419b69..f86d447f6f65d6 100644 --- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs +++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs @@ -3519,7 +3519,7 @@ public static T StdDev(in ReadOnlyTensorSpan x) Subtract(x, mean, temp); Abs(temp, temp); T sum = SumOfSquares(temp); - T variance = sum / T.CreateChecked(x._shape._memoryLength); + T variance = sum / T.CreateChecked(x.FlattenedLength); return T.Sqrt(variance); } #endregion From 85e8753387a63d941df74aef99936cd2504bf888 Mon Sep 17 00:00:00 2001 From: lilinus Date: Wed, 18 Dec 2024 14:07:58 +0100 Subject: [PATCH 10/11] Try add byref to api compat supressions --- .../System.Numerics.Tensors/src/CompatibilitySuppressions.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml index b5530185ac5143..94cc53cad9db40 100644 --- a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml @@ -255,14 +255,14 @@ CP0021 - M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0})``0:System.Numerics.IRootFunctions{``0} + M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@)``0:System.Numerics.IRootFunctions{``0} lib/net8.0/System.Numerics.Tensors.dll lib/net8.0/System.Numerics.Tensors.dll true CP0021 - M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0})``0:System.Numerics.IRootFunctions{``0} + M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@)``0:System.Numerics.IRootFunctions{``0} lib/net9.0/System.Numerics.Tensors.dll lib/net9.0/System.Numerics.Tensors.dll true From e9321339fbded69af7778d4082d08d3a3a5aa6ee Mon Sep 17 00:00:00 2001 From: lilinus Date: Wed, 18 Dec 2024 15:47:06 +0100 Subject: [PATCH 11/11] Try fix type constraint --- .../System.Numerics.Tensors/src/CompatibilitySuppressions.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml index 94cc53cad9db40..d05601550864ea 100644 --- a/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Numerics.Tensors/src/CompatibilitySuppressions.xml @@ -255,14 +255,14 @@ CP0021 - M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@)``0:System.Numerics.IRootFunctions{``0} + M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@)``0:T:System.Numerics.IRootFunctions{``0} lib/net8.0/System.Numerics.Tensors.dll lib/net8.0/System.Numerics.Tensors.dll true CP0021 - M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@)``0:System.Numerics.IRootFunctions{``0} + M:System.Numerics.Tensors.Tensor.StdDev``1(System.Numerics.Tensors.ReadOnlyTensorSpan{``0}@)``0:T:System.Numerics.IRootFunctions{``0} lib/net9.0/System.Numerics.Tensors.dll lib/net9.0/System.Numerics.Tensors.dll true