Skip to content

Commit e2174aa

Browse files
committed
Add missing Max/Min scalar overloads
1 parent 83a2b22 commit e2174aa

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

src/libraries/System.Numerics.Tensors/ref/System.Numerics.Tensors.netcore.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,16 @@ public static void Log10P1<T>(System.ReadOnlySpan<T> x, System.Span<T> destinati
7979
public static void Log10<T>(System.ReadOnlySpan<T> x, System.Span<T> destination) where T : System.Numerics.ILogarithmicFunctions<T> { }
8080
public static T MaxMagnitude<T>(System.ReadOnlySpan<T> x) where T : System.Numerics.INumberBase<T> { throw null; }
8181
public static void MaxMagnitude<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, System.Span<T> destination) where T : System.Numerics.INumberBase<T> { }
82+
public static void MaxMagnitude<T>(System.ReadOnlySpan<T> x, T y, System.Span<T> destination) where T : System.Numerics.INumberBase<T> { }
8283
public static T Max<T>(System.ReadOnlySpan<T> x) where T : System.Numerics.INumber<T> { throw null; }
8384
public static void Max<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, System.Span<T> destination) where T : System.Numerics.INumber<T> { }
85+
public static void Max<T>(System.ReadOnlySpan<T> x, T y, System.Span<T> destination) where T : System.Numerics.INumber<T> { }
8486
public static T MinMagnitude<T>(System.ReadOnlySpan<T> x) where T : System.Numerics.INumberBase<T> { throw null; }
8587
public static void MinMagnitude<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, System.Span<T> destination) where T : System.Numerics.INumberBase<T> { }
88+
public static void MinMagnitude<T>(System.ReadOnlySpan<T> x, T y, System.Span<T> destination) where T : System.Numerics.INumberBase<T> { }
8689
public static T Min<T>(System.ReadOnlySpan<T> x) where T : System.Numerics.INumber<T> { throw null; }
8790
public static void Min<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, System.Span<T> destination) where T : System.Numerics.INumber<T> { }
91+
public static void Min<T>(System.ReadOnlySpan<T> x, T y, System.Span<T> destination) where T : System.Numerics.INumber<T> { }
8892
public static void MultiplyAdd<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, System.ReadOnlySpan<T> addend, System.Span<T> destination) where T : System.Numerics.IAdditionOperators<T, T, T>, System.Numerics.IMultiplyOperators<T, T, T> { }
8993
public static void MultiplyAdd<T>(System.ReadOnlySpan<T> x, System.ReadOnlySpan<T> y, T addend, System.Span<T> destination) where T : System.Numerics.IAdditionOperators<T, T, T>, System.Numerics.IMultiplyOperators<T, T, T> { }
9094
public static void MultiplyAdd<T>(System.ReadOnlySpan<T> x, T y, System.ReadOnlySpan<T> addend, System.Span<T> destination) where T : System.Numerics.IAdditionOperators<T, T, T>, System.Numerics.IMultiplyOperators<T, T, T> { }

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorPrimitives.T.cs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,29 @@ public static void Max<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destinat
13531353
where T : INumber<T> =>
13541354
InvokeSpanSpanIntoSpan<T, MaxPropagateNaNOperator<T>>(x, y, destination);
13551355

1356+
/// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
1357+
/// <param name="x">The first tensor, represented as a span.</param>
1358+
/// <param name="y">The second tensor, represented as a scalar.</param>
1359+
/// <param name="destination">The destination tensor, represented as a span.</param>
1360+
/// <exception cref="ArgumentException">Destination is too short.</exception>
1361+
/// <exception cref="ArgumentException"><paramref name="x"/> and <paramref name="destination"/> reference overlapping memory locations and do not begin at the same location.</exception>
1362+
/// <remarks>
1363+
/// <para>
1364+
/// This method effectively computes <c><paramref name="destination" />[i] = <typeparamref name="T"/>.Max(<paramref name="x" />[i], <paramref name="y" />)</c>.
1365+
/// </para>
1366+
/// <para>
1367+
/// The determination of the maximum element matches the IEEE 754:2019 `maximum` function. If either value is equal to <see cref="IFloatingPointIeee754{TSelf}.NaN"/>,
1368+
/// that value is stored as the result. Positive 0 is considered greater than negative 0.
1369+
/// </para>
1370+
/// <para>
1371+
/// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different
1372+
/// operating systems or architectures.
1373+
/// </para>
1374+
/// </remarks>
1375+
public static void Max<T>(ReadOnlySpan<T> x, T y, Span<T> destination)
1376+
where T : INumber<T> =>
1377+
InvokeSpanScalarIntoSpan<T, MaxPropagateNaNOperator<T>>(x, y, destination);
1378+
13561379
/// <summary>Searches for the number with the largest magnitude in the specified tensor.</summary>
13571380
/// <param name="x">The tensor, represented as a span.</param>
13581381
/// <returns>The element in <paramref name="x"/> with the largest magnitude (absolute value).</returns>
@@ -1391,6 +1414,23 @@ public static void MaxMagnitude<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T>
13911414
where T : INumberBase<T> =>
13921415
InvokeSpanSpanIntoSpan<T, MaxMagnitudePropagateNaNOperator<T>>(x, y, destination);
13931416

1417+
/// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
1418+
/// <param name="x">The first tensor, represented as a span.</param>
1419+
/// <param name="y">The second tensor, represented as a scalar.</param>
1420+
/// <param name="destination">The destination tensor, represented as a span.</param>
1421+
/// <exception cref="ArgumentException">Destination is too short.</exception>
1422+
/// <exception cref="ArgumentException"><paramref name="x"/> and <paramref name="destination"/> reference overlapping memory locations and do not begin at the same location.</exception>
1423+
/// <remarks>This method effectively computes <c><paramref name="destination" />[i] = <typeparamref name="T"/>.MaxMagnitude(<paramref name="x" />[i], <paramref name="y" />)</c>.</remarks>
1424+
/// <remarks>
1425+
/// <para>
1426+
/// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different
1427+
/// operating systems or architectures.
1428+
/// </para>
1429+
/// </remarks>
1430+
public static void MaxMagnitude<T>(ReadOnlySpan<T> x, T y, Span<T> destination)
1431+
where T : INumberBase<T> =>
1432+
InvokeSpanScalarIntoSpan<T, MaxMagnitudePropagateNaNOperator<T>>(x, y, destination);
1433+
13941434
/// <summary>Searches for the smallest number in the specified tensor.</summary>
13951435
/// <param name="x">The tensor, represented as a span.</param>
13961436
/// <returns>The minimum element in <paramref name="x"/>.</returns>
@@ -1434,6 +1474,29 @@ public static void Min<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T> destinat
14341474
where T : INumber<T> =>
14351475
InvokeSpanSpanIntoSpan<T, MinPropagateNaNOperator<T>>(x, y, destination);
14361476

1477+
/// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
1478+
/// <param name="x">The first tensor, represented as a span.</param>
1479+
/// <param name="y">The second tensor, represented as a scalar.</param>
1480+
/// <param name="destination">The destination tensor, represented as a span.</param>
1481+
/// <exception cref="ArgumentException">Destination is too short.</exception>
1482+
/// <exception cref="ArgumentException"><paramref name="x"/> and <paramref name="destination"/> reference overlapping memory locations and do not begin at the same location.</exception>
1483+
/// <remarks>
1484+
/// <para>
1485+
/// This method effectively computes <c><paramref name="destination" />[i] = <typeparamref name="T"/>.Max(<paramref name="x" />[i], <paramref name="y" />)</c>.
1486+
/// </para>
1487+
/// <para>
1488+
/// The determination of the maximum element matches the IEEE 754:2019 `maximum` function. If either value is equal to <see cref="IFloatingPointIeee754{TSelf}.NaN"/>,
1489+
/// that value is stored as the result. Positive 0 is considered greater than negative 0.
1490+
/// </para>
1491+
/// <para>
1492+
/// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different
1493+
/// operating systems or architectures.
1494+
/// </para>
1495+
/// </remarks>
1496+
public static void Min<T>(ReadOnlySpan<T> x, T y, Span<T> destination)
1497+
where T : INumber<T> =>
1498+
InvokeSpanScalarIntoSpan<T, MinPropagateNaNOperator<T>>(x, y, destination);
1499+
14371500
/// <summary>Searches for the number with the smallest magnitude in the specified tensor.</summary>
14381501
/// <param name="x">The tensor, represented as a span.</param>
14391502
/// <returns>The element in <paramref name="x"/> with the smallest magnitude (absolute value).</returns>
@@ -1477,6 +1540,28 @@ public static void MinMagnitude<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, Span<T>
14771540
where T : INumberBase<T> =>
14781541
InvokeSpanSpanIntoSpan<T, MinMagnitudePropagateNaNOperator<T>>(x, y, destination);
14791542

1543+
/// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
1544+
/// <param name="x">The first tensor, represented as a span.</param>
1545+
/// <param name="y">The second tensor, represented as a scalar.</param>
1546+
/// <param name="destination">The destination tensor, represented as a span.</param>
1547+
/// <exception cref="ArgumentException">Destination is too short.</exception>
1548+
/// <exception cref="ArgumentException"><paramref name="x"/> and <paramref name="destination"/> reference overlapping memory locations and do not begin at the same location.</exception>
1549+
/// <remarks>This method effectively computes <c><paramref name="destination" />[i] = <typeparamref name="T"/>.MinMagnitude(<paramref name="x" />[i], <paramref name="y" />)</c>.</remarks>
1550+
/// <remarks>
1551+
/// <para>
1552+
/// The determination of the maximum magnitude matches the IEEE 754:2019 `minimumMagnitude` function. If either value is equal to <see cref="IFloatingPointIeee754{TSelf}.NaN"/>,
1553+
/// that value is stored as the result. If the two values have the same magnitude and one is positive and the other is negative,
1554+
/// the negative value is considered to have the smaller magnitude.
1555+
/// </para>
1556+
/// <para>
1557+
/// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different
1558+
/// operating systems or architectures.
1559+
/// </para>
1560+
/// </remarks>
1561+
public static void MinMagnitude<T>(ReadOnlySpan<T> x, T y, Span<T> destination)
1562+
where T : INumberBase<T> =>
1563+
InvokeSpanScalarIntoSpan<T, MinMagnitudePropagateNaNOperator<T>>(x, y, destination);
1564+
14801565
/// <summary>Computes the element-wise product of numbers in the specified tensors.</summary>
14811566
/// <param name="x">The first tensor, represented as a span.</param>
14821567
/// <param name="y">The second tensor, represented as a span.</param>

src/libraries/System.Numerics.Tensors/tests/TensorPrimitives.Generic.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,10 @@ public static IEnumerable<object[]> SpanScalarDestinationFunctionsToTest()
369369
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Ieee754Remainder), new Func<T, T, T>(T.Ieee754Remainder) };
370370
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Pow), new Func<T, T, T>(T.Pow) };
371371
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Log), new Func<T, T, T>(T.Log) };
372+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Max), new Func<T, T, T>(T.Max) };
373+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.MaxMagnitude), new Func<T, T, T>(T.MaxMagnitude) };
374+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Min), new Func<T, T, T>(T.Min) };
375+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.MinMagnitude), new Func<T, T, T>(T.MinMagnitude) };
372376
}
373377

374378
[Theory]
@@ -1299,6 +1303,10 @@ public static IEnumerable<object[]> SpanScalarDestinationFunctionsToTest()
12991303
{
13001304
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.BitwiseAnd), new Func<T, T, T>((x, y) => x & y) };
13011305
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.BitwiseOr), new Func<T, T, T>((x, y) => x | y) };
1306+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Max), new Func<T, T, T>(T.Max) };
1307+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.MaxMagnitude), new Func<T, T, T>(T.MaxMagnitude) };
1308+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Min), new Func<T, T, T>(T.Min) };
1309+
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.MinMagnitude), new Func<T, T, T>(T.MinMagnitude) };
13021310
yield return new object[] { new SpanScalarDestinationDelegate<T, T, T>(TensorPrimitives.Xor), new Func<T, T, T>((x, y) => x ^ y) };
13031311
}
13041312

0 commit comments

Comments
 (0)