dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.36k stars 4.74k forks source link

Tensor<T> and supporting types, part 2 #103611

Open tannergooding opened 5 months ago

tannergooding commented 5 months ago

This is a continuation of https://github.com/dotnet/runtime/issues/100924 and covers the various operation like APIs that do meaningful work with Tensor<T> and supporting types.

ReadOnlyTensorSpan and ReadOnlySpan have been abbreviated to ROTensorSpan and TensorSpan, respectively, to save roughly 3000 characters and fit in the comment length limit of GitHub

API Proposal -- Changes to already approve surface area

The new C# ref struct + interfaces work in C# 9 means that we can use [UnscopedRef] on interface members now:

 namespace System.Numerics.Tensors;

 public partial interface IReadOnlyTensor<TSelf, T>
 {
+    [UnscopedRef]
+    ROSpan<nint> Lengths { get;}

+    [UnscopedRef]
+    ROSpan<nint> Lengths { get;}

-    void GetLengths(scoped Span<nint> destination);
-    void GetStrides(scoped Span<nint> destination);
 }

API Proposal -- Parity with TensorPrimitives

These cover parity with what TensorPrimitives currently supports, but operating over the proper multi-dimensional types:

namespace System.Numerics.Tensors;

public static partial class Tensor
{
    // Other

    public static Tensor<T> CosineSimilarity<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;
    public static Tensor<T> CosineSimilarity<T>(in ROTensorSpan<T> x, T y) where T : IRootFunctions<T>;

    public static ref readonly TensorSpan<T> CosineSimilarity<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IRootFunctions<T>;
    public static ref readonly TensorSpan<T> CosineSimilarity<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static T Distance<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;
    public static T Distance<T>(in ROTensorSpan<T> x, T y) where T : IRootFunctions<T>;
    public static T Distance<T>(T x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;

    public static T Dot<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>, IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>;
    public static T Dot<T>(in ROTensorSpan<T> x, T y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>, IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>;

    public static T Norm<T>(in ROTensorSpan<T> x) where T : IRootFunctions<T>;

    public static T Product<T>(in ROTensorSpan<T> x) where T : IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>;

    public static Tensor<T> Sigmoid<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> Sigmoid<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> SoftMax<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> SoftMax<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static T Sum<T>(in ROTensorSpan<T> x) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;

    // IAdditionOperators

    public static Tensor<T> Add<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;
    public static Tensor<T> Add<T>(in ROTensorSpan<T> x, T y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;

    public static ref readonly TensorSpan<T> Add<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;
    public static ref readonly TensorSpan<T> Add<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;

    // IBinaryInteger

    public static Tensor<T> LeadingZeroCount<T>(in ROTensorSpan<T> x) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> LeadingZeroCount<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> PopCount<T>(in ROTensorSpan<T> x) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> PopCount<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> RotateLeft<T>(in ROTensorSpan<T> x, int rotateAmount) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> RotateLeft<T>(scoped in ROTensorSpan<T> x, int rotateAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> RotateRight<T>(in ROTensorSpan<T> x, int rotateAmount) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> RotateRight<T>(scoped in ROTensorSpan<T> x, int rotateAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> TrailingZeroCount<T>(in ROTensorSpan<T> x) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> TrailingZeroCount<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    // IBitwiseOperators

    public static Tensor<T> BitwiseAnd<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBitwiseOperators<T, T, T>;
    public static Tensor<T> BitwiseAnd<T>(in ROTensorSpan<T> x, T y) where T : IBitwiseOperators<T, T, T>;

    public static ref readonly TensorSpan<T> BitwiseAnd<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;
    public static ref readonly TensorSpan<T> BitwiseAnd<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    public static Tensor<T> BitwiseOr<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBitwiseOperators<T, T, T>;
    public static Tensor<T> BitwiseOr<T>(in ROTensorSpan<T> x, T y) where T : IBitwiseOperators<T, T, T>;

    public static ref readonly TensorSpan<T> BitwiseOr<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;
    public static ref readonly TensorSpan<T> BitwiseOr<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    public static Tensor<T> OnesComplement<T>(in ROTensorSpan<T> x) where T : IBitwiseOperators<T, T, T>;
    public static ref readonly TensorSpan<T> OnesComplement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    public static Tensor<T> Xor<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBitwiseOperators<T, T, T>;
    public static Tensor<T> Xor<T>(in ROTensorSpan<T> x, T y) where T : IBitwiseOperators<T, T, T>;

    public static ref readonly TensorSpan<T> Xor<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;
    public static ref readonly TensorSpan<T> Xor<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    // IComparisonOperators

    public static Tensor<bool> GreaterThan<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThan<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThan<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> GreaterThan<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThan<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThan<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static Tensor<bool> GreaterThanOrEqual<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThanOrEqual<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThanOrEqual<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> GreaterThanOrEqual<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThanOrEqual<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThanOrEqual<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanOrEqualAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanOrEqualAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static Tensor<bool> LessThan<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThan<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThan<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> LessThan<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThan<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThan<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static Tensor<bool> LessThanOrEqual<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThanOrEqual<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThanOrEqual<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> LessThanOrEqual<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThanOrEqual<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThanOrEqual<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanOrEqualAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanOrEqualAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    // IDivisionOperators

    public static Tensor<T> Divide<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IDivisionOperators<T, T, T>;
    public static Tensor<T> Divide<T>(in ROTensorSpan<T> x, T y) where T : IDivisionOperators<T, T, T>;
    public static Tensor<T> Divide<T>(T x, in ROTensorSpan<T> y) where T : IDivisionOperators<T, T, T>;

    public static ref readonly TensorSpan<T> Divide<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IDivisionOperators<T, T, T>;
    public static ref readonly TensorSpan<T> Divide<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IDivisionOperators<T, T, T>;
    public static ref readonly TensorSpan<T> Divide<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IDivisionOperators<T, T, T>;

    // IEqualityOperators

    public static Tensor<bool> Equals<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> Equals<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> Equals<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> Equals<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool EqualsAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool EqualsAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;

    public static bool EqualsAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool EqualsAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;

    // IExponentialFunctions

    public static Tensor<T> Exp<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> Exp<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> ExpM1<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> ExpM1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp2<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> Exp2<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp2M1<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> Exp2M1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp10<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> Exp10<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp10M1<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static ref readonly TensorSpan<T> Exp10M1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    // IFloatingPoint

    public static Tensor<T> Ceiling<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Ceiling<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Floor<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Floor<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Reciprocal<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Reciprocal<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x, int digits, MidpointRounding mode) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, int digits, MidpointRounding mode, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x, int digits) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, int digits, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x, MidpointRounding mode) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, MidpointRounding mode, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Truncate<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> Truncate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    // IFloatingPointIeee754

    public static Tensor<T> Atan2<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2<T>(in ROTensorSpan<T> x, T y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2<T>(T x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;

    public static ref readonly TensorSpan<T> Atan2<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Atan2<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Atan2<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Atan2Pi<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2Pi<T>(in ROTensorSpan<T> x, T y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2Pi<T>(T x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;

    public static ref readonly TensorSpan<T> Atan2Pi<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Atan2Pi<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Atan2Pi<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in ROTensorSpan<T> addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, T addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, T y, in ROTensorSpan<T> addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, T y, T addend) where T : IFloatingPointIeee754<T>;

    public static ref readonly TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, T addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, T y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, T y, T addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Ieee754Remainder<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Ieee754Remainder<T>(in ROTensorSpan<T> x, T y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Ieee754Remainder<T>(T x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;

    public static ref readonly TensorSpan<T> Ieee754Remainder<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Ieee754Remainder<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Ieee754Remainder<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<int> ILogB<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<int> ILogB<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, T amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, T y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, T y, T amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(T x, in ROTensorSpan<T> y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(T x, in ROTensorSpan<T> y, T amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(T x, T y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;

    public static ref readonly TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, T amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, T y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, T y, T amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Lerp<T>(T x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Lerp<T>(T x, scoped in ROTensorSpan<T> y, T amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> Lerp<T>(T x, T y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> ReciprocalEstimate<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> ReciprocalEstimate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> ReciprocalSqrtEstimate<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> ReciprocalSqrtEstimate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<int> ScaleB<T>(in ROTensorSpan<T> x, int n) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<int> ScaleB<T>(scoped in ROTensorSpan<T> x, int n, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    // IHyperbolicFunctions

    public static Tensor<T> Acosh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static ref readonly TensorSpan<T> Acosh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Asinh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static ref readonly TensorSpan<T> Asinh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Atanh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static ref readonly TensorSpan<T> Atanh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Cosh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static ref readonly TensorSpan<T> Cosh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Sinh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static ref readonly TensorSpan<T> Sinh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Tanh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static ref readonly TensorSpan<T> Tanh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    // ILogarithmicFunctions

    public static Tensor<T> Log<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> Log<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : ILogarithmicFunctions<T>;
    public static Tensor<T> Log<T>(in ROTensorSpan<T> x, T y) where T : ILogarithmicFunctions<T>;
    public static Tensor<T> Log<T>(T x, in ROTensorSpan<T> y) where T : ILogarithmicFunctions<T>;

    public static ref readonly TensorSpan<T> Log<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> Log<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> Log<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> LogP1<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> LogP1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log2<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> Log2<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log2P1<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> Log2P1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log10<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> Log10<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log10P1<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static ref readonly TensorSpan<T> Log10P1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    // IMultiplyOperators

    public static Tensor<T> Multiply<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;
    public static Tensor<T> Multiply<T>(in ROTensorSpan<T> x, T y) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;

    public static ref readonly TensorSpan<T> Multiply<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;
    public static ref readonly TensorSpan<T> Multiply<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;

    // INumber

    public static Tensor<T> CopySign<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> sign) where T : INumber<T>;
    public static Tensor<T> CopySign<T>(in ROTensorSpan<T> x, T sign) where T : INumber<T>;
    public static Tensor<T> CopySign<T>(T x, in ROTensorSpan<T> sign) where T : INumber<T>;

    public static ref readonly TensorSpan<T> CopySign<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> sign, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> CopySign<T>(scoped in ROTensorSpan<T> x, T sign, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> CopySign<T>(T x, scoped in ROTensorSpan<T> sign, in TensorSpan<T> destination) where T : INumber<T>;

    public static int IndexOfMax<T>(in ROTensorSpan<T> x) where T : INumber<T>;
    public static int IndexOfMaxNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static int IndexOfMin<T>(in ROTensorSpan<T> x) where T : INumber<T>;
    public static int IndexOfMinNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static T Max<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> Max<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> Max<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> Max<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Max<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MaxNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> MaxNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;
    public static Tensor<T> MaxNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> MaxNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> MaxNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T Min<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> Min<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> Min<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> Min<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Min<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MinNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> MinNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MinNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> MinNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> MinNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    // INumberBase

    public static Tensor<T> Abs<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;
    public static ref readonly TensorSpan<T> Abs<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : INumberBase<T>;

    public static Tensor<TTo> ConvertChecked<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    public static ref readonly TensorSpan<TTo> ConvertChecked<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;

    public static Tensor<TTo> ConvertSaturating<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    public static ref readonly TensorSpan<TTo> ConvertSaturating<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;

    public static Tensor<TTo> ConvertTruncating<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    public static ref readonly TensorSpan<TTo> ConvertTruncating<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;

    public static int IndexOfMaxMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;
    public static int IndexOfMaxMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static int IndexOfMinMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;
    public static int IndexOfMinMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static T MaxMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MaxMagnitude<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MaxMagnitude<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> MaxMagnitude<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> MaxMagnitude<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MaxMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MaxMagnitudeNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MaxMagnitudeNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> MaxMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> MaxMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MinMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MinMagnitude<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MinMagnitude<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> MinMagnitude<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> MinMagnitude<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MinMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MinMagnitudeNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MinMagnitudeNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static ref readonly TensorSpan<T> MinMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> MinMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in ROTensorSpan<T> addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, T addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, T y, in ROTensorSpan<T> addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, T y, T addend) where T : IFloatingPointIeee754<T>;

    public static ref readonly TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, T addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, T y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static ref readonly TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, T y, T addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    // IPowerFunctions

    public static Tensor<T> Pow<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IPowerFunctions<T>;
    public static Tensor<T> Pow<T>(in ROTensorSpan<T> x, T y) where T : IPowerFunctions<T>;
    public static Tensor<T> Pow<T>(T x, in ROTensorSpan<T> y) where T : IPowerFunctions<T>;

    public static ref readonly TensorSpan<T> Pow<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IPowerFunctions<T>;
    public static ref readonly TensorSpan<T> Pow<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IPowerFunctions<T>;
    public static ref readonly TensorSpan<T> Pow<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IPowerFunctions<T>;

    // IRootFunctions

    public static Tensor<T> Cbrt<T>(in ROTensorSpan<T> x) where T : IRootFunctions<T>;
    public static ref readonly TensorSpan<T> Cbrt<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static Tensor<T> Hypot<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;
    public static Tensor<T> Hypot<T>(in ROTensorSpan<T> x, T y) where T : IRootFunctions<T>;

    public static ref readonly TensorSpan<T> Hypot<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IRootFunctions<T>;
    public static ref readonly TensorSpan<T> Hypot<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static Tensor<T> RootN<T>(in ROTensorSpan<T> x, int n) where T : IRootFunctions<T>;
    public static ref readonly TensorSpan<T> RootN<T>(scoped in ROTensorSpan<T> x, int n, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static Tensor<T> Sqrt<T>(in ROTensorSpan<T> x) where T : IRootFunctions<T>;
    public static ref readonly TensorSpan<T> Sqrt<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    // IShiftOperators

    public static Tensor<T> ShiftLeft<T>(in ROTensorSpan<T> x, int shiftAmount) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> ShiftLeft<T>(scoped in ROTensorSpan<T> x, int shiftAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> ShiftRightArithmetic<T>(in ROTensorSpan<T> x, int shiftAmount) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> ShiftRightArithmetic<T>(scoped in ROTensorSpan<T> x, int shiftAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> ShiftRightLogical<T>(in ROTensorSpan<T> x, int shiftAmount) where T : IBinaryInteger<T>;
    public static ref readonly TensorSpan<T> ShiftRightLogical<T>(scoped in ROTensorSpan<T> x, int shiftAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    // ISubtractionOperators

    public static Tensor<T> Subtract<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : ISubtractionOperators<T, T, T>;
    public static Tensor<T> Subtract<T>(in ROTensorSpan<T> x, T y) where T : ISubtractionOperators<T, T, T>;
    public static Tensor<T> Subtract<T>(T x, in ROTensorSpan<T> y) where T : ISubtractionOperators<T, T, T>;

    public static ref readonly TensorSpan<T> Subtract<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ISubtractionOperators<T, T, T>;
    public static ref readonly TensorSpan<T> Subtract<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : ISubtractionOperators<T, T, T>;
    public static ref readonly TensorSpan<T> Subtract<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ISubtractionOperators<T, T, T>;

    // ITrigonometricFunctions

    public static Tensor<T> Acos<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> Acos<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> AcosPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> AcosPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Asin<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> Asin<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> AsinPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> AsinPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Atan<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> Atan<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> AtanPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> AtanPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Cos<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> Cos<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> CosPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> CosPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> DegreesToRadians<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> DegreesToRadians<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> RadiansToDegrees<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> RadiansToDegrees<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Sin<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> Sin<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static (Tensor<T> Sin, in Tensor<T> Cos) SinCos<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> SinCos<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> sinDestination, in TensorSpan<T> cosDestination) where T : ITrigonometricFunctions<T>;

    public static (Tensor<T> SinPi, in Tensor<T> CosPi) SinCosPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> SinCosPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> sinPiDestination, in TensorSpan<T> cosPiDestination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> SinPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> SinPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Tan<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> Tan<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> TanPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static ref readonly TensorSpan<T> TanPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    // IUnaryNegationOperators

    public static Tensor<T> Negate<T>(in ROTensorSpan<T> x) where T : IUnaryNegationOperators<T, T>;
    public static ref readonly TensorSpan<T> Negate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IUnaryNegationOperators<T, T>;
}

API Proposal -- New APIs for Tensor, TensorSpan, and TensorPrimitives

namespace System.Numerics.Tensors;

public static partial class Tensor
{
    public static Tensor<T> BitDecrement<T>(in ROTensorSpan<T> x) where T : IDecrementOperators<T, T>;
    public static ref readonly TensorSpan<T> BitDecrement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> BitIncrement<T>(in ROTensorSpan<T> x) where T : IIncrementOperators<T, T>;
    public static ref readonly TensorSpan<T> BitIncrement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> min, in ROTensorSpan<T> max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> min, T max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, T min, in ROTensorSpan<T> max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, T min, T max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(T x, in ROTensorSpan<T> min, in ROTensorSpan<T> max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(T x, in ROTensorSpan<T> min, T max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(T x, T min, scoped in ROTensorSpan<T> max) where T : INumber<T>;

    public static ref readonly TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> min, T max, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, T min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, T min, T max, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Clamp<T>(T x, scoped in ROTensorSpan<T> min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Clamp<T>(T x, scoped in ROTensorSpan<T> min, T max, in TensorSpan<T> destination) where T : INumber<T>;
    public static ref readonly TensorSpan<T> Clamp<T>(T x, T min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;

    public static Tensor<TTo> ConvertToInteger<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;
    public static ref readonly TensorSpan<TTo> ConvertToInteger<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;

    public static Tensor<TTo> ConvertToIntegerNative<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;
    public static ref readonly TensorSpan<TTo> ConvertToIntegerNative<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;

    public static (Tensor<T> Quotient, in Tensor<T> Remainder) DivRem<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBinaryInteger<T>;
    public static (Tensor<T> Quotient, in Tensor<T> Remainder) DivRem<T>(in ROTensorSpan<T> x, T y) where T : IBinaryInteger<T>;
    public static (Tensor<T> Quotient, in Tensor<T> Remainder) DivRem<T>(T x, in ROTensorSpan<T> y) where T : IBinaryInteger<T>;

    public static void DivRem<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in TensorSpan<T> quotientDestination, in TensorSpan<T> remainderDestination) where T : IBinaryInteger<T>;
    public static void DivRem<T>(in ROTensorSpan<T> x, T y, in TensorSpan<T> quotientDestination, in TensorSpan<T> remainderDestination) where T : IBinaryInteger<T>;
    public static void DivRem<T>(T x, in ROTensorSpan<T> y, in TensorSpan<T> quotientDestination, in TensorSpan<T> remainderDestination) where T : IBinaryInteger<T>;

    public static Tensor<T> Decrement<T>(in ROTensorSpan<T> x) where T : IDecrementOperators<T, T>;
    public static ref readonly TensorSpan<T> Decrement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IDecrementOperators<T, T>;

    public static Tensor<T> Increment<T>(in ROTensorSpan<T> x) where T : IIncrementOperators<T, T>;
    public static ref readonly TensorSpan<T> Increment<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IIncrementOperators<T, T>;

    public static T Mean<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;

    public static Tensor<T> Remainder<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IModulusOperators<T, T, T>;
    public static Tensor<T> Remainder<T>(in ROTensorSpan<T> x, T y) where T : IModulusOperators<T, T, T>;
    public static Tensor<T> Remainder<T>(T x, in ROTensorSpan<T> y) where T : IModulusOperators<T, T, T>;

    public static ref readonly TensorSpan<T> Remainder<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IModulusOperators<T, T, T>;
    public static ref readonly TensorSpan<T> Remainder<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IModulusOperators<T, T, T>;
    public static ref readonly TensorSpan<T> Remainder<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IModulusOperators<T, T, T>;

    public static Tensor<int> Sign<T>(in ROTensorSpan<T> x) where T : INumber<T>;
    public static ref readonly TensorSpan<int> Sign<T>(scoped in ROTensorSpan<T> x, in TensoreSpan<T> destination) where T : INumber<T>;

    public static T StdDev<T>(in ROTensorSpan<T> x) where T : IPowerFunctions<T>;

    // The following APIs could have Tensor<bool> and bool versions,
    // following the `*()`, `*All()` and `*Any()` pattern:
    //
    // IBinaryNumber
    // * IsPow2
    // INumberBase
    // * IsCanonical
    // * IsComplexNumber
    // * IsEvenInteger
    // * IsFinite
    // * IsImaginaryNumber
    // * IsInfinity
    // * IsInteger
    // * IsNaN
    // * IsNegative
    // * IsNegativeInfinity
    // * IsNormal
    // * IsOddInteger
    // * IsPositive
    // * IsPositiveInfinity
    // * IsRealNumber
    // * IsSubnormal
    // * IsZero
}

public static partial class TensorPrimitives
{
    public static void BitDecrement<T>(ROSpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;

    public static void BitIncrement<T>(ROSpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;

    public static void Clamp<T>(ROSpan<T> x, ROSpan<T> min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(ROSpan<T> x, ROSpan<T> min, T max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(ROSpan<T> x, T min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(ROSpan<T> x, T min, T max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(T x, ROSpan<T> min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(T x, ROSpan<T> min, T max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(T x, T min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;

    public static Span<TTo> ConvertToInteger<TFrom, TTo>(ROSpan<TFrom> source, Span<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;
    public static Span<TTo> ConvertToIntegerNative<TFrom, TTo>(ROSpan<TFrom> source, Span<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;

    public static void DivRem<T>(ROSpan<T> x, ROSpan<T> y, Span<T> quotientDestination, Span<T> remainderDestination) where T : IBinaryInteger<T>;
    public static void DivRem<T>(ROSpan<T> x, T y, Span<T> quotientDestination, Span<T> remainderDestination) where T : IBinaryInteger<T>;
    public static void DivRem<T>(T x, ROSpan<T> y, Span<T> quotientDestination, Span<T> remainderDestination) where T : IBinaryInteger<T>;

    public static void Decrement<T>(ROSpan<T> x, Span<T> destination) where T : IDecrementOperators<T, T>;

    public static void Increment<T>(ROSpan<T> x, Span<T> destination) where T : IIncrementOperators<T, T>;

    public static T Mean<T>(ROSpan<T> x) where T : IFloatingPoint<T>;

    public static void Remainder<T>(ROSpan<T> x, ROSpan<T> y, Span<T> destination) where T : IModulusOperators<T, T, T>;
    public static void Remainder<T>(ROSpan<T> x, T y, Span<T> destination) where T : IModulusOperators<T, T, T>;
    public static void Remainder<T>(T x, ROSpan<T> y, Span<T> destination) where T : IModulusOperators<T, T, T>;

    public static void Sign<T>(ROSpan<T> x, in Span<int> destination) where T : INumber<T>;

    public static T StdDev<T>(ROSpan<T> x) where T : IPowerFunctions<T>;
}

API Proposal -- APIs unique to Tensor and TensorSpan

These cover APIs that do not have an equivalent in TensorPrimitives, typically being functionality that is unique to multi-dimensional types:

namespace System.Numerics.Tensors;

public static partial class Tensor
{
    public static ROTensorSpan<T> AsROTensorSpan<T>(this T[]? array, params scoped ROSpan<nint> lengths);
    public static TensorSpan<T> AsTensorSpan<T>(this T[]? array, params scoped ROSpan<nint> lengths);

    public static Tensor<T> Broadcast<T>(in ROTensorSpan<T> x, ROSpan<nint> lengths);

    // This gets the lengths from lengthsSource
    public static Tensor<T> Broadcast<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> lengthsSource);

    public static void BroadcastTo<T>(this Tensor<T> x, in TensorSpan<T> destination);
    public static void BroadcastTo<T>(in this TensorSpan<T> x, in TensorSpan<T> destination);
    public static void BroadcastTo<T>(in this ROTensorSpan<T> x, in TensorSpan<T> destination);

    // The parameter order here feels off. Ideally tensors could be params
    // and we'd have overloads taking 2-3x ROTensorSpan<T>. Maybe we can
    // explode the overloads a bit to make this nicer?
    public static Tensor<T> Concatenate<T>(ROSpan<Tensor<T>> tensors, int axis = 0);
    public static ref readonly TensorSpan<T> Concatenate<T>(scoped ROSpan<Tensor<T>> tensors, in TensorSpan<T> destination, int axis = 0);

    public static Tensor<T> Create<T>(ROSpan<nint> lengths, bool pinned = false);
    public static Tensor<T> Create<T>(ROSpan<nint> lengths, ROSpan<nint> strides, bool pinned = false);
    public static Tensor<T> Create<T>(T[] values, ROSpan<nint> lengths);
    public static Tensor<T> Create<T>(T[] values, ROSpan<nint> lengths, ROSpan<nint> strides, bool isPinned = false);
    public static Tensor<T> Create<T>(IEnumerable<T> values, ROSpan<nint> lengths);
    public static Tensor<T> Create<T>(IEnumerable<T> values, ROSpan<nint> lengths, ROSpan<nint> strides, bool isPinned = false);

    public static Tensor<T> CreateAndFillGaussianNormalDistribution<T>(params ROSpan<nint> lengths) where T : IFloatingPoint<T>;
    public static Tensor<T> CreateAndFillUniformDistribution<T>(params ROSpan<nint> lengths) where T : IFloatingPoint<T>;

    public static Tensor<T> CreateUninitialized<T>(ROSpan<nint> lengths, bool pinned = false);
    public static Tensor<T> CreateUninitialized<T>(ROSpan<nint> lengths, ROSpan<nint> strides, bool pinned = false);

    public static ref readonly TensorSpan<T> FillGaussianNormalDistribution<T>(in TensorSpan<T> destination) where T : IFloatingPoint<T>;
    public static ref readonly TensorSpan<T> FillUniformDistribution<T>(in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    // Should this be some overload of SetSlice or similar?
    public static ref readonly TensorSpan<T> FilteredUpdate<T>(in this TensorSpan<T> x, scoped in ROTensorSpan<bool> filter, scoped in ROTensorSpan<T> values);
    public static ref readonly TensorSpan<T> FilteredUpdate<T>(in this TensorSpan<T> x, scoped in ROTensorSpan<bool> filter, T value);

    // Change order of the stride parameters
    public static Tensor<T> Permute<T>(this Tensor<T> x, params ROSpan<int> axis);
    public static TensorSpan<T> Permute<T>(in this TensorSpan<T> x, params scoped ROSpan<int> axis);
    public static ROTensorSpan<T> Permute<T>(in this ROTensorSpan<T> x, params scoped ROSpan<int> axis);

    // Change the lengths
    public static Tensor<T> Reshape<T>(this Tensor<T> x, params ROSpan<nint> lengths);
    public static TensorSpan<T> Reshape<T>(in this TensorSpan<T> x, params scoped ROSpan<nint> lengths);
    public static ROTensorSpan<T> Reshape<T>(in this ROTensorSpan<T> x, params scoped ROSpan<nint> lengths);

    public static Tensor<T> Resize<T>(Tensor<T> x, ROSpan<nint> lengths);

    public static void ResizeTo<T>(this Tensor<T> x, in TensorSpan<nint> destination);
    public static void ResizeTo<T>(in this TensorSpan<T> x, in TensorSpan<nint> destination);
    public static void ResizeTo<T>(in this ROTensorSpan<T> x, in TensorSpan<nint> destination);

    // Should this be expanded to avoid the optional axis parameter?
    public static Tensor<T> Reverse<T>(in ROTensorSpan<T> x, nint axis = -1);
    public static ref readonly TensorSpan<T> Reverse<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination, nint axis = -1);

    // These are distinct from EqualsAll in that they use IEquatable
    public static bool SequenceEqual<T>(this in ROTensorSpan<T> span, in ROTensorSpan<T> other) where T : IEquatable<T>?;
    public static bool SequenceEqual<T>(this in TensorSpan<T> span, in ROTensorSpan<T> other) where T : IEquatable<T>?;

    // The ordering of these parameters is slightly backwards so params can work for the ranges
    public static Tensor<T> SetSlice<T>(this Tensor<T> tensor, in ROTensorSpan<T> values, params ROSpan<NRange> ranges);
    public static ref readonly TensorSpan<T> SetSlice<T>(this TensorSpan<T> tensor, scoped in ROTensorSpan<T> values, params scoped ROSpan<NRange> ranges);

    public static Tensor<T>[] Split<T>(in ROTensorSpan<T> x, nint numSplits, nint axis);

    // Remove dimensions of length 1
    public static Tensor<T> Squeeze<T>(this Tensor<T> x, int axis = -1);
    public static TensorSpan<T> Squeeze<T>(in this TensorSpan<T> x, int axis = -1);
    public static ROTensorSpan<T> Squeeze<T>(in this ROTensorSpan<T> x, int axis = -1);

    public static Tensor<T> Stack<T>(ROSpan<Tensor<T>> tensors, int axis = 0);
    public static ref readonly TensorSpan<T> Stack<T>(scoped ROSpan<Tensor<T>> tensors, in TensorSpan<T> destination, int axis = 0);

    public static string ToString<T>(in this ROTensorSpan<T> span, params ROSpan<nint> maximumLengths);
    public static string ToString<T>(in this TensorSpan<T> span, params ROSpan<nint> maximumLengths);

    public static Tensor<T> Transpose<T>(in ROTensorSpan<T> x);
    public static ref readonly TensorSpan<T> Transpose<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination);

    public static bool TryBroadcastTo<T>(this Tensor<T> x, in TensorSpan<T> destination);
    public static bool TryBroadcastTo<T>(in this TensorSpan<T> x, in TensorSpan<T> destination);
    public static bool TryBroadcastTo<T>(in this ROTensorSpan<T> x, in TensorSpan<T> destination);

    // Adds dimension of length 1
    public static Tensor<T> Unsqueeze<T>(this Tensor<T> x, int axis);
    public static TensorSpan<T> Unsqueeze<T>(in this TensorSpan<T> x, int axis);
    public static ROTensorSpan<T> Unsqueeze<T>(in this ROTensorSpan<T> x, int axis);
}
JeffreySax commented 4 months ago

Exposing the internal methods that invoke Vector operations on spans (like InvokeSpanSpanIntoSpan) would be extremely useful. This implies exposing the supporting interfaces like IBinaryOperator<T> as well. So I realize it's a sizeable surface area and therefore a lot of work. But for people who do low-level performance-critical stuff, it would be worth it.

tannergooding commented 4 months ago

Exposing the internal methods that invoke Vector operations on spans (like InvokeSpanSpanIntoSpan) would be extremely useful. This implies exposing the supporting interfaces like IBinaryOperator as well. So I realize it's a sizeable surface area and therefore a lot of work. But for people who do low-level performance-critical stuff, it would be worth it.

This is something we're interested in long term, but it is out of scope for .NET 9

The random fill methods should at least have an (optional) seed so you can have reproducible results.

I imagine that rather they should take in a System.Random instead

Maybe Squeeze and Unsqueeze can be renamed to TrimAxes and ExpandAxes respectively, consistent with Permute. TrimDimensions is ambiguous because dimension is a synonym for length along an axis.

Trim is potentially confusing as it typically is used to mean remove from beginning and end. Where-as this is either removing a specific axis or all axes that have length 1.

Expand I think is similarly confusing, because really it's just inserting an axis of length 1.

Most axis arguments could be System.Index, counting back from Rank.

I agree most could have an Index overload. However, this would do the natural indexing where 0 is rank0 and ^1 is the last rank.

I agree that in many cases these could be two APIs instead of 1 that is overloaded by a magic sentinel.

Tensor.Permute: I would prefer PermuteAxes or PermuteDimensions or even PermuteIndices. It's not a general permutation of elements, but a very specific one.

I believe I had previously given similar feedback on this, CC. @michaelgsharp

gaviny82 commented 4 months ago

In the discussion for APIs part 1, Shape was renamed to Lengths because "length" is more intuitive to people without domain knowledge. However, "length" refers to the distance from origin (for vectors) and some kind of norm (for matrices and higher order tensors) in the context of linear algebra. It's also inconsistent with Reshape and parameter names in other APIs and comments.

I think it's important to determine the terminology for "the number of elements in a dimension" and "a dimension" of a tensor, otherwise we'll have confusing names like "length" and "dimension", while "rank" and "axis" refer to the total number of dimensions and a single dimension.

It's also important to balance the simplicity for beginners to scientific computation and accuracy of describing the concept to experts in this domain.

Below is a comparison of related APIs in other ecosystems:

.NET NumPy (Python) MATLAB
Rank ndim ndims (number of dimensions)
Lengths shape size
FlattenedLength size numel (number of elements)
Reshape reshape reshape
tannergooding commented 4 months ago

.NET has existing terminology that is used for many of these concepts and it is intentional that they remain consistent here in the new type.

The most important thing is to be self-consistent without our own .NET ecosystem.

Reshape is used because it is distinctly not Resize.

JeffreySax commented 4 months ago

The argument in Array.GetLength is called dimension, so maybe axis arguments should also be named dimension for consistency.

Expand I think is similarly confusing, because really it's just inserting an axis of length 1.

Unsqueeze is a terrible name. How about the lengthy but clear and descriptive InsertSingletonDimension, and likewise RemoveSingletonDimension instead of Squeeze?

Regarding TensorPrimitives: there are currently no operations on boolean spans. I would expect to see at least LogicalAnd, LogicalOr, LogicalNot, LogicalXor, All and Any. Many operations return bool spans/tensors, but there is no good way combine them.

Exposing the internal methods that invoke Vector operations on spans (like InvokeSpanSpanIntoSpan) would be extremely useful. This implies exposing the supporting interfaces like IBinaryOperator as well. So I realize it's a sizeable surface area and therefore a lot of work. But for people who do low-level performance-critical stuff, it would be worth it.

This is something we're interested in long term, but it is out of scope for .NET 9

Finally, two questions:

  1. How close is the Tensor API to being locked down?
  2. Does System.Numerics.Tensors follow the main .NET release cycle?
gaviny82 commented 4 months ago

.NET has existing terminology that is used for many of these concepts and it is intentional that they remain consistent here in the new type.

I agree it's important to be consistent within .NET, but tensors and arrays are fundamentally different things, although tensors are implemented by arrays. Tensors are mathematical objects that satisfy the properties while arrays are just contiguous values. The difference is only conceptual and their APIs can be unrelated. Is it really important to make the Tensor APIs exactly the same as Array even when they are confusing in the context of tensors?

The most important thing is to be self-consistent without our own .NET ecosystem.

Yes, we should not copy APIs from other ecosystems. I was just listing APIs in other ecosystems which are more mature in the field of numeric computation to show how they avoided this confusing name.

Reshape is used because it is distinctly not Resize.

Yes, Reshape is fine here.

How close is the Tensor API to being locked down? Does System.Numerics.Tensors follow the main .NET release cycle?

I'm also interested in these. Would the tensor/numerics library have its own release cycle, at least for the first version? It's important to get more feedback from developers doing scientific computation. Given that .NET is not as popular as other ecosystems in this domain, most people are not aware of this library at this stage.

It seems GA in .NET 9 is too early. Better to mark it as preview so that people will have more time to try this library. It's the foundation of everything in numerics and it's hard to introduce breaking changes once it goes GA.

tannergooding commented 4 months ago

Tensors are mathematical objects that satisfy the properties

This is not really true in the context of programming. Programming in general steals a lot of terminology from mathematics and skews it to be "ehh, close enough".

The standard collection type in C++ is called std::vector for much the same reason, because logically it is similar to a mathematical "vector", even though in practice that's not what it is and it doesn't support many of the operations and properties that a mathematical vector might.

Tensors are much the same way and while the original usage started out closer to the mathematical definition, the practical use across most languages is simply to mean "multi-dimensional array with operator support", thus having Scalar (zero-dimensional array), Vector (single-dimensional array), Matrix (two-dimensional array), and Tensor (n-dimensioned array) as the logical sequence of types that exist.

Is it really important to make the Tensor APIs exactly the same as Array even when they are confusing in the context of tensors?

The meanings here remain accurate to tensor as well. Rank is a slightly overloaded term that has meaning in linear algebra, set theory, graph theory, and in other scenarios. It also happens to have a meaning in programming and for Tensors in particular where it is the number of dimensions.

.NET has an existing history of using Rank to mean the number of dimensions and it is continuing to be used here. It is used in the broader domain outside of .NET (consider TensorFlow when used to talk about the number of dimensions/axes as well and some other APIs also use it in their own API names/terminology.

-- The ecosystem at large is entirely inconsistent with the terminology used and there is almost never a single name that everyone has unified towards, because everyone has their own ideas on what is "good" or not. .NET, for better or worse, chose the name Rank 20 years ago and it continues to be a good fit for the identical meaning here today.

The argument in Array.GetLength is called dimension, so maybe axis arguments should also be named dimension for consistency.

That's a good point, they should likely use the name dimension here as well.

Unsqueeze is a terrible name. How about the lengthy but clear and descriptive InsertSingletonDimension, and likewise RemoveSingletonDimension instead of Squeeze?

The alternatives here aren't much better IMO. Something along the lines of InsertDimension might be okay, but it would likely need further thought as well.

There also needs to be the consideration of how it applies to inserting many or removing all dimensions of length 1.

Regarding TensorPrimitives: there are currently no operations on boolean spans. I would expect to see at least LogicalAnd, LogicalOr, LogicalNot, LogicalXor, All and Any. Many operations return bool spans/tensors, but there is no good way combine them.

The names here would be BitwiseAnd, BitwiseOr, OnesComplement, and Xor given the existing naming terminology used by .NET

There is a very large surface area here and we're trying to cover the core concepts first and foremost and get to the other parts in subsequent proposals.

Operating on Tensor<bool> in the first place tends to be non-ideal as it allocates large additional amounts of memory and requires iterating over that memory many times. The better long term solution is going to be a predication system and potentially a new language feature around lambda binding to allow this all to be efficient, so that Tensor<bool> largely doesn't need to be instantiated in the first place.

How close is the Tensor API to being locked down?

It hasn't even gone to API review yet, so still a ways.

Does System.Numerics.Tensors follow the main .NET release cycle?

It is currently an out of band package and does not technically require shipping with the main release cycle, although it makes things a lot easier when it does.

It is not clear yet whether we will mark the API as stable or not for .NET 9, there are many aspects to the Tensor type that are straightforward and which have near zero risk. They are simply following already established names, signatures, and couldn't really change much outside of tiny nitpicks. There is then a much smaller subset of new terms and new signatures that are a bit less clear and which we will have a clearer view on after the first API review.

gaviny82 commented 4 months ago

Is it really important to make the Tensor APIs exactly the same as Array even when they are confusing in the context of tensors?

The meanings here remain accurate to tensor as well. Rank is a slightly overloaded term that has meaning in linear algebra, set theory, graph theory, and in other scenarios. It also happens to have a meaning in programming and for Tensors in particular where it is the number of dimensions.

Rank is totally fine and it makes sense for tensors.

Actually I mean the ambiguity between Lengths (for number of elements) and length as a norm/distance of a tensor/vector. Apologies for the confusion.

It is currently an out of band package and does not technically require shipping with the main release cycle, although it makes things a lot easier when it does.

Thanks for sharing the details. Looking forward to future improvements in the library.

tannergooding commented 4 months ago

Actually I mean the ambiguity between Lengths (for number of elements) and length as a norm/distance of a tensor/vector. Apologies for the confusion.

This is something that also comes up, much more prominently, for things like Vector2/3/4 and Vector64/128/256/512<T>, given that they are "1-dimensional" vectors of particular lengths. In those contexts, the use of Length is also something that can potentially cause issues with general language features oriented around collection expressions, index/range/slice, and other similar features (which uses the existence of a Length property as part of the heuristics to identify a potential collection type).

.NET uses the term Length for Array, Span, and other core types to mean the length of a dimension. It further uses it in the context of multi-dimensional arrays for each dimension. It also uses the term Count for some of the collection types, but they are their own category separate from the previous set of types that Tensor and TensorSpan will fit into.

So, this is one of those cases where there isn't strictly a single good name because there is a common term that is overloaded across math, programming, and other domains. But where Lengths then gets chosen because it is the clear convention in .NET for the set of types that Tensor is fitting into/extending as a form of general n-dimensional array + operator support for .NET. We don't really have a convention for using the term size or sizes for such types and count/counts doesn't fit into the general intent of these types.

Other ecosystems also live with such potential ambiguities. pytorch is an example where they expose size() and shape() as aliases to mean what we plan to expose as Lengths. They then have len() as a more general Python API that interplays with numpy and pytorch types and in the case of tensor returns the length of the first dimension. -- .NET doesn't tend to use aliases, so we get one name to expose here and that needs to fit in with our existing conventions where possible.

bartonjs commented 4 months ago

Video

Note that the abbreviation "RO" is being used in lieu of "ReadOnly" to reduce total message size (GitHub has per message size limits, who knew?)

namespace System.Numerics.Tensors
{
    public partial interface IReadOnlyTensor<TSelf, T>
    {
+       [UnscopedRef]
+       ReadOnlySpan<nint> Lengths { get;}

+       [UnscopedRef]
+       ReadOnlySpan<nint> Strides { get;}

-       void GetLengths(scoped Span<nint> destination);
-       void GetStrides(scoped Span<nint> destination);
    }
}
namespace System.Numerics.Tensors;

public static partial class Tensor
{
    // Other

    public static Tensor<T> CosineSimilarity<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;
    public static Tensor<T> CosineSimilarity<T>(in ROTensorSpan<T> x, T y) where T : IRootFunctions<T>;

    public static TensorSpan<T> CosineSimilarity<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IRootFunctions<T>;
    public static TensorSpan<T> CosineSimilarity<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static T Distance<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;
    public static T Distance<T>(in ROTensorSpan<T> x, T y) where T : IRootFunctions<T>;
    public static T Distance<T>(T x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;

    public static T Dot<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>, IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>;
    public static T Dot<T>(in ROTensorSpan<T> x, T y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>, IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>;

    public static T Norm<T>(in ROTensorSpan<T> x) where T : IRootFunctions<T>;

    public static T Product<T>(in ROTensorSpan<T> x) where T : IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>;

    public static Tensor<T> Sigmoid<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> Sigmoid<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> SoftMax<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> SoftMax<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static T Sum<T>(in ROTensorSpan<T> x) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;

    // IAdditionOperators

    public static Tensor<T> Add<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;
    public static Tensor<T> Add<T>(in ROTensorSpan<T> x, T y) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;

    public static TensorSpan<T> Add<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;
    public static TensorSpan<T> Add<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>;

    // IBinaryInteger

    public static Tensor<T> LeadingZeroCount<T>(in ROTensorSpan<T> x) where T : IBinaryInteger<T>;
    public static TensorSpan<T> LeadingZeroCount<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> PopCount<T>(in ROTensorSpan<T> x) where T : IBinaryInteger<T>;
    public static TensorSpan<T> PopCount<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> RotateLeft<T>(in ROTensorSpan<T> x, int rotateAmount) where T : IBinaryInteger<T>;
    public static TensorSpan<T> RotateLeft<T>(scoped in ROTensorSpan<T> x, int rotateAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> RotateRight<T>(in ROTensorSpan<T> x, int rotateAmount) where T : IBinaryInteger<T>;
    public static TensorSpan<T> RotateRight<T>(scoped in ROTensorSpan<T> x, int rotateAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> TrailingZeroCount<T>(in ROTensorSpan<T> x) where T : IBinaryInteger<T>;
    public static TensorSpan<T> TrailingZeroCount<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    // IBitwiseOperators

    public static Tensor<T> BitwiseAnd<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBitwiseOperators<T, T, T>;
    public static Tensor<T> BitwiseAnd<T>(in ROTensorSpan<T> x, T y) where T : IBitwiseOperators<T, T, T>;

    public static TensorSpan<T> BitwiseAnd<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;
    public static TensorSpan<T> BitwiseAnd<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    public static Tensor<T> BitwiseOr<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBitwiseOperators<T, T, T>;
    public static Tensor<T> BitwiseOr<T>(in ROTensorSpan<T> x, T y) where T : IBitwiseOperators<T, T, T>;

    public static TensorSpan<T> BitwiseOr<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;
    public static TensorSpan<T> BitwiseOr<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    public static Tensor<T> OnesComplement<T>(in ROTensorSpan<T> x) where T : IBitwiseOperators<T, T, T>;
    public static TensorSpan<T> OnesComplement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    public static Tensor<T> Xor<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBitwiseOperators<T, T, T>;
    public static Tensor<T> Xor<T>(in ROTensorSpan<T> x, T y) where T : IBitwiseOperators<T, T, T>;

    public static TensorSpan<T> Xor<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;
    public static TensorSpan<T> Xor<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IBitwiseOperators<T, T, T>;

    // IComparisonOperators

    public static Tensor<bool> GreaterThan<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThan<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThan<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> GreaterThan<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThan<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThan<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static Tensor<bool> GreaterThanOrEqual<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThanOrEqual<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> GreaterThanOrEqual<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> GreaterThanOrEqual<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThanOrEqual<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> GreaterThanOrEqual<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanOrEqualAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool GreaterThanOrEqualAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool GreaterThanOrEqualAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static Tensor<bool> LessThan<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThan<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThan<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> LessThan<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThan<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThan<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static Tensor<bool> LessThanOrEqual<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThanOrEqual<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static Tensor<bool> LessThanOrEqual<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static TensorSpan<bool> LessThanOrEqual<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThanOrEqual<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;
    public static TensorSpan<bool> LessThanOrEqual<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanOrEqualAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAll<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAll<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    public static bool LessThanOrEqualAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAny<T>(in ROTensorSpan<T> x, T y) where T : IComparisonOperators<T, T, bool>;
    public static bool LessThanOrEqualAny<T>(T x, in ROTensorSpan<T> y) where T : IComparisonOperators<T, T, bool>;

    // IDivisionOperators

    public static Tensor<T> Divide<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IDivisionOperators<T, T, T>;
    public static Tensor<T> Divide<T>(in ROTensorSpan<T> x, T y) where T : IDivisionOperators<T, T, T>;
    public static Tensor<T> Divide<T>(T x, in ROTensorSpan<T> y) where T : IDivisionOperators<T, T, T>;

    public static TensorSpan<T> Divide<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IDivisionOperators<T, T, T>;
    public static TensorSpan<T> Divide<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IDivisionOperators<T, T, T>;
    public static TensorSpan<T> Divide<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IDivisionOperators<T, T, T>;

    // IEqualityOperators

    public static Tensor<bool> Equals<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IEqualityOperators<T, bool>;
    public static Tensor<bool> Equals<T>(in ROTensorSpan<T> x, T y) where T : IEqualityOperators<T, bool>;

    public static TensorSpan<bool> Equals<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<bool> destination) where T : IEqualityOperators<T, bool>;
    public static TensorSpan<bool> Equals<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<bool> destination) where T : IEqualityOperators<T, bool>;

    public static bool EqualsAll<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IEqualityOperators<T, bool>;
    public static bool EqualsAll<T>(in ROTensorSpan<T> x, T y) where T : IEqualityOperators<T, bool>;

    public static bool EqualsAny<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IEqualityOperators<T, bool>;
    public static bool EqualsAny<T>(in ROTensorSpan<T> x, T y) where T : IEqualityOperators<T, bool>;

    // IExponentialFunctions

    public static Tensor<T> Exp<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> Exp<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> ExpM1<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> ExpM1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp2<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> Exp2<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp2M1<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> Exp2M1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp10<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> Exp10<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    public static Tensor<T> Exp10M1<T>(in ROTensorSpan<T> x) where T : IExponentialFunctions<T>;
    public static TensorSpan<T> Exp10M1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IExponentialFunctions<T>;

    // IFloatingPoint

    public static Tensor<T> Ceiling<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Ceiling<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Floor<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Floor<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Reciprocal<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Reciprocal<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x, int digits, MidpointRounding mode) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, int digits, MidpointRounding mode, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x, int digits) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, int digits, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Round<T>(in ROTensorSpan<T> x, MidpointRounding mode) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Round<T>(scoped in ROTensorSpan<T> x, MidpointRounding mode, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    public static Tensor<T> Truncate<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;
    public static TensorSpan<T> Truncate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPoint<T>;

    // IFloatingPointIeee754

    public static Tensor<T> Atan2<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2<T>(in ROTensorSpan<T> x, T y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2<T>(T x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;

    public static TensorSpan<T> Atan2<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Atan2<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Atan2<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Atan2Pi<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2Pi<T>(in ROTensorSpan<T> x, T y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Atan2Pi<T>(T x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;

    public static TensorSpan<T> Atan2Pi<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Atan2Pi<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Atan2Pi<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in ROTensorSpan<T> addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, T addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, T y, in ROTensorSpan<T> addend) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> FusedMultiplyAdd<T>(in ROTensorSpan<T> x, T y, T addend) where T : IFloatingPointIeee754<T>;

    public static TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, T addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, T y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> FusedMultiplyAdd<T>(scoped in ROTensorSpan<T> x, T y, T addend, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Ieee754Remainder<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Ieee754Remainder<T>(in ROTensorSpan<T> x, T y) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Ieee754Remainder<T>(T x, in ROTensorSpan<T> y) where T : IFloatingPointIeee754<T>;

    public static TensorSpan<T> Ieee754Remainder<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Ieee754Remainder<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Ieee754Remainder<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<int> ILogB<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<int> ILogB<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, T amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, T y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(in ROTensorSpan<T> x, T y, T amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(T x, in ROTensorSpan<T> y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(T x, in ROTensorSpan<T> y, T amount) where T : IFloatingPointIeee754<T>;
    public static Tensor<T> Lerp<T>(T x, T y, in ROTensorSpan<T> amount) where T : IFloatingPointIeee754<T>;

    public static TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, T amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, T y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Lerp<T>(scoped in ROTensorSpan<T> x, T y, T amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Lerp<T>(T x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Lerp<T>(T x, scoped in ROTensorSpan<T> y, T amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> Lerp<T>(T x, T y, scoped in ROTensorSpan<T> amount, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> ReciprocalEstimate<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> ReciprocalEstimate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> ReciprocalSqrtEstimate<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<T> ReciprocalSqrtEstimate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<int> ScaleB<T>(in ROTensorSpan<T> x, int n) where T : IFloatingPointIeee754<T>;
    public static TensorSpan<int> ScaleB<T>(scoped in ROTensorSpan<T> x, int n, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    // IHyperbolicFunctions

    public static Tensor<T> Acosh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static TensorSpan<T> Acosh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Asinh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static TensorSpan<T> Asinh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Atanh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static TensorSpan<T> Atanh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Cosh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static TensorSpan<T> Cosh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Sinh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static TensorSpan<T> Sinh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    public static Tensor<T> Tanh<T>(in ROTensorSpan<T> x) where T : IHyperbolicFunctions<T>;
    public static TensorSpan<T> Tanh<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IHyperbolicFunctions<T>;

    // ILogarithmicFunctions

    public static Tensor<T> Log<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> Log<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : ILogarithmicFunctions<T>;
    public static Tensor<T> Log<T>(in ROTensorSpan<T> x, T y) where T : ILogarithmicFunctions<T>;
    public static Tensor<T> Log<T>(T x, in ROTensorSpan<T> y) where T : ILogarithmicFunctions<T>;

    public static TensorSpan<T> Log<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> Log<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> Log<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> LogP1<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> LogP1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log2<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> Log2<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log2P1<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> Log2P1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log10<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> Log10<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    public static Tensor<T> Log10P1<T>(in ROTensorSpan<T> x) where T : ILogarithmicFunctions<T>;
    public static TensorSpan<T> Log10P1<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ILogarithmicFunctions<T>;

    // IMultiplyOperators

    public static Tensor<T> Multiply<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;
    public static Tensor<T> Multiply<T>(in ROTensorSpan<T> x, T y) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;

    public static TensorSpan<T> Multiply<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;
    public static TensorSpan<T> Multiply<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>;

    // INumber

    public static Tensor<T> CopySign<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> sign) where T : INumber<T>;
    public static Tensor<T> CopySign<T>(in ROTensorSpan<T> x, T sign) where T : INumber<T>;
    public static Tensor<T> CopySign<T>(T x, in ROTensorSpan<T> sign) where T : INumber<T>;

    public static TensorSpan<T> CopySign<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> sign, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> CopySign<T>(scoped in ROTensorSpan<T> x, T sign, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> CopySign<T>(T x, scoped in ROTensorSpan<T> sign, in TensorSpan<T> destination) where T : INumber<T>;

    public static int IndexOfMax<T>(in ROTensorSpan<T> x) where T : INumber<T>;
    public static int IndexOfMaxNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static int IndexOfMin<T>(in ROTensorSpan<T> x) where T : INumber<T>;
    public static int IndexOfMinNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static T Max<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> Max<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> Max<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static TensorSpan<T> Max<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Max<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MaxNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> MaxNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;
    public static Tensor<T> MaxNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;

    public static TensorSpan<T> MaxNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MaxNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T Min<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> Min<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> Min<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static TensorSpan<T> Min<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Min<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MinNumber<T>(in ROTensorSpan<T> x) where T : INumber<T>;

    public static Tensor<T> MinNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MinNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static TensorSpan<T> MinNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MinNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    // INumberBase

    public static Tensor<T> Abs<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;
    public static TensorSpan<T> Abs<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : INumberBase<T>;

    public static Tensor<TTo> ConvertChecked<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    public static TensorSpan<TTo> ConvertChecked<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;

    public static Tensor<TTo> ConvertSaturating<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    public static TensorSpan<TTo> ConvertSaturating<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;

    public static Tensor<TTo> ConvertTruncating<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;
    public static TensorSpan<TTo> ConvertTruncating<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : INumberBase<TFrom> where TTo : INumberBase<TTo>;

    public static int IndexOfMaxMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;
    public static int IndexOfMaxMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static int IndexOfMinMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;
    public static int IndexOfMinMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static T MaxMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MaxMagnitude<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MaxMagnitude<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static TensorSpan<T> MaxMagnitude<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MaxMagnitude<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MaxMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MaxMagnitudeNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MaxMagnitudeNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static TensorSpan<T> MaxMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MaxMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MinMagnitude<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MinMagnitude<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MinMagnitude<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static TensorSpan<T> MinMagnitude<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MinMagnitude<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static T MinMagnitudeNumber<T>(in ROTensorSpan<T> x) where T : INumberBase<T>;

    public static Tensor<T> MinMagnitudeNumber<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : INumber<T>;
    public static Tensor<T> MinMagnitudeNumber<T>(in ROTensorSpan<T> x, T y) where T : INumber<T>;

    public static TensorSpan<T> MinMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MinMagnitudeNumber<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : INumber<T>;

    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in ROTensorSpan<T> addend) where T : INumber<T>;
    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, T addend) where T : INumber<T>;
    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, T y, in ROTensorSpan<T> addend) where T : INumber<T>;
    public static Tensor<T> MultiplyAddEstimate<T>(in ROTensorSpan<T> x, T y, T addend) where T : INumber<T>;

    public static TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, T addend, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, T y, scoped in ROTensorSpan<T> addend, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> MultiplyAddEstimate<T>(scoped in ROTensorSpan<T> x, T y, T addend, in TensorSpan<T> destination) where T : INumber<T>;

    // IPowerFunctions

    public static Tensor<T> Pow<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IPowerFunctions<T>;
    public static Tensor<T> Pow<T>(in ROTensorSpan<T> x, T y) where T : IPowerFunctions<T>;
    public static Tensor<T> Pow<T>(T x, in ROTensorSpan<T> y) where T : IPowerFunctions<T>;

    public static TensorSpan<T> Pow<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IPowerFunctions<T>;
    public static TensorSpan<T> Pow<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IPowerFunctions<T>;
    public static TensorSpan<T> Pow<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IPowerFunctions<T>;

    // IRootFunctions

    public static Tensor<T> Cbrt<T>(in ROTensorSpan<T> x) where T : IRootFunctions<T>;
    public static TensorSpan<T> Cbrt<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static Tensor<T> Hypot<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IRootFunctions<T>;
    public static Tensor<T> Hypot<T>(in ROTensorSpan<T> x, T y) where T : IRootFunctions<T>;

    public static TensorSpan<T> Hypot<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IRootFunctions<T>;
    public static TensorSpan<T> Hypot<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static Tensor<T> RootN<T>(in ROTensorSpan<T> x, int n) where T : IRootFunctions<T>;
    public static TensorSpan<T> RootN<T>(scoped in ROTensorSpan<T> x, int n, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    public static Tensor<T> Sqrt<T>(in ROTensorSpan<T> x) where T : IRootFunctions<T>;
    public static TensorSpan<T> Sqrt<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IRootFunctions<T>;

    // IShiftOperators

    public static Tensor<T> ShiftLeft<T>(in ROTensorSpan<T> x, int shiftAmount) where T : IBinaryInteger<T>;
    public static TensorSpan<T> ShiftLeft<T>(scoped in ROTensorSpan<T> x, int shiftAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> ShiftRightArithmetic<T>(in ROTensorSpan<T> x, int shiftAmount) where T : IBinaryInteger<T>;
    public static TensorSpan<T> ShiftRightArithmetic<T>(scoped in ROTensorSpan<T> x, int shiftAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    public static Tensor<T> ShiftRightLogical<T>(in ROTensorSpan<T> x, int shiftAmount) where T : IBinaryInteger<T>;
    public static TensorSpan<T> ShiftRightLogical<T>(scoped in ROTensorSpan<T> x, int shiftAmount, in TensorSpan<T> destination) where T : IBinaryInteger<T>;

    // ISubtractionOperators

    public static Tensor<T> Subtract<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : ISubtractionOperators<T, T, T>;
    public static Tensor<T> Subtract<T>(in ROTensorSpan<T> x, T y) where T : ISubtractionOperators<T, T, T>;
    public static Tensor<T> Subtract<T>(T x, in ROTensorSpan<T> y) where T : ISubtractionOperators<T, T, T>;

    public static TensorSpan<T> Subtract<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ISubtractionOperators<T, T, T>;
    public static TensorSpan<T> Subtract<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : ISubtractionOperators<T, T, T>;
    public static TensorSpan<T> Subtract<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : ISubtractionOperators<T, T, T>;

    // ITrigonometricFunctions

    public static Tensor<T> Acos<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> Acos<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> AcosPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> AcosPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Asin<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> Asin<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> AsinPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> AsinPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Atan<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> Atan<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> AtanPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> AtanPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Cos<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> Cos<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> CosPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> CosPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> DegreesToRadians<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> DegreesToRadians<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> RadiansToDegrees<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> RadiansToDegrees<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Sin<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> Sin<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static (Tensor<T> Sin, Tensor<T> Cos) SinCos<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static (TensorSpan<T> Sin, TensorSpan<T> Cos) SinCos<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> sinDestination, in TensorSpan<T> cosDestination) where T : ITrigonometricFunctions<T>;

    public static (Tensor<T> SinPi, Tensor<T> CosPi) SinCosPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static (TensorSpan<T> Sin, TensorSpan<T> Cos) SinCosPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> sinPiDestination, in TensorSpan<T> cosPiDestination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> SinPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> SinPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> Tan<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> Tan<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    public static Tensor<T> TanPi<T>(in ROTensorSpan<T> x) where T : ITrigonometricFunctions<T>;
    public static TensorSpan<T> TanPi<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : ITrigonometricFunctions<T>;

    // IUnaryNegationOperators

    public static Tensor<T> Negate<T>(in ROTensorSpan<T> x) where T : IUnaryNegationOperators<T, T>;
    public static TensorSpan<T> Negate<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IUnaryNegationOperators<T, T>;
}
namespace System.Numerics.Tensors;

public static partial class Tensor
{
    public static Tensor<T> BitDecrement<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T, T>;
    public static TensorSpan<T> BitDecrement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> BitIncrement<T>(in ROTensorSpan<T> x) where T : IFloatingPointIeee754<T, T>;
    public static TensorSpan<T> BitIncrement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IFloatingPointIeee754<T>;

    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> min, in ROTensorSpan<T> max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> min, T max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, T min, in ROTensorSpan<T> max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(in ROTensorSpan<T> x, T min, T max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(T x, in ROTensorSpan<T> min, in ROTensorSpan<T> max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(T x, in ROTensorSpan<T> min, T max) where T : INumber<T>;
    public static Tensor<T> Clamp<T>(T x, T min, scoped in ROTensorSpan<T> max) where T : INumber<T>;

    public static TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> min, T max, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, T min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Clamp<T>(scoped in ROTensorSpan<T> x, T min, T max, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Clamp<T>(T x, scoped in ROTensorSpan<T> min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Clamp<T>(T x, scoped in ROTensorSpan<T> min, T max, in TensorSpan<T> destination) where T : INumber<T>;
    public static TensorSpan<T> Clamp<T>(T x, T min, scoped in ROTensorSpan<T> max, in TensorSpan<T> destination) where T : INumber<T>;

    public static Tensor<TTo> ConvertToInteger<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;
    public static TensorSpan<TTo> ConvertToInteger<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;

    public static Tensor<TTo> ConvertToIntegerNative<TFrom, TTo>(in ROTensorSpan<TFrom> source) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;
    public static TensorSpan<TTo> ConvertToIntegerNative<TFrom, TTo>(scoped in ROTensorSpan<TFrom> source, in TensorSpan<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;

    public static (Tensor<T> Quotient, Tensor<T> Remainder) DivRem<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IBinaryInteger<T>;
    public static (Tensor<T> Quotient, Tensor<T> Remainder) DivRem<T>(in ROTensorSpan<T> x, T y) where T : IBinaryInteger<T>;
    public static (Tensor<T> Quotient, Tensor<T> Remainder) DivRem<T>(T x, in ROTensorSpan<T> y) where T : IBinaryInteger<T>;

    public static (TensorSpan<T> Quotient, TensorSpan<T> Remainder) DivRem<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y, in TensorSpan<T> quotientDestination, in TensorSpan<T> remainderDestination) where T : IBinaryInteger<T>;
    public static (TensorSpan<T> Quotient, TensorSpan<T> Remainder) DivRem<T>(in ROTensorSpan<T> x, T y, in TensorSpan<T> quotientDestination, in TensorSpan<T> remainderDestination) where T : IBinaryInteger<T>;
    public static (TensorSpan<T> Quotient, TensorSpan<T> Remainder) DivRem<T>(T x, in ROTensorSpan<T> y, in TensorSpan<T> quotientDestination, in TensorSpan<T> remainderDestination) where T : IBinaryInteger<T>;

    public static Tensor<T> Decrement<T>(in ROTensorSpan<T> x) where T : IDecrementOperators<T, T>;
    public static TensorSpan<T> Decrement<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IDecrementOperators<T, T>;

    public static Tensor<T> Increment<T>(in ROTensorSpan<T> x) where T : IIncrementOperators<T, T>;
    public static TensorSpan<T> Increment<T>(scoped in ROTensorSpan<T> x, in TensorSpan<T> destination) where T : IIncrementOperators<T, T>;

    public static T Mean<T>(in ROTensorSpan<T> x) where T : IFloatingPoint<T>;

    public static Tensor<T> Remainder<T>(in ROTensorSpan<T> x, in ROTensorSpan<T> y) where T : IModulusOperators<T, T, T>;
    public static Tensor<T> Remainder<T>(in ROTensorSpan<T> x, T y) where T : IModulusOperators<T, T, T>;
    public static Tensor<T> Remainder<T>(T x, in ROTensorSpan<T> y) where T : IModulusOperators<T, T, T>;

    public static TensorSpan<T> Remainder<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IModulusOperators<T, T, T>;
    public static TensorSpan<T> Remainder<T>(scoped in ROTensorSpan<T> x, T y, in TensorSpan<T> destination) where T : IModulusOperators<T, T, T>;
    public static TensorSpan<T> Remainder<T>(T x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IModulusOperators<T, T, T>;

    public static Tensor<int> Sign<T>(in ROTensorSpan<T> x) where T : INumber<T>;
    public static TensorSpan<int> Sign<T>(scoped in ROTensorSpan<T> x, in TensoreSpan<T> destination) where T : INumber<T>;

    public static T StdDev<T>(in ROTensorSpan<T> x) where T : IPowerFunctions<T>;
}

public static partial class TensorPrimitives
{
    public static void BitDecrement<T>(ROSpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;

    public static void BitIncrement<T>(ROSpan<T> x, Span<T> destination) where T : IFloatingPointIeee754<T>;

    public static void Clamp<T>(ROSpan<T> x, ROSpan<T> min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(ROSpan<T> x, ROSpan<T> min, T max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(ROSpan<T> x, T min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(ROSpan<T> x, T min, T max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(T x, ROSpan<T> min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(T x, ROSpan<T> min, T max, Span<T> destination) where T : INumber<T>;
    public static void Clamp<T>(T x, T min, ROSpan<T> max, Span<T> destination) where T : INumber<T>;

    public static Span<TTo> ConvertToInteger<TFrom, TTo>(ROSpan<TFrom> source, Span<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;
    public static Span<TTo> ConvertToIntegerNative<TFrom, TTo>(ROSpan<TFrom> source, Span<TTo> destination) where TFrom : IFloatingPoint<TFrom> where TTo : IBinaryInteger<TTo>;

    public static void DivRem<T>(ROSpan<T> x, ROSpan<T> y, Span<T> quotientDestination, Span<T> remainderDestination) where T : IBinaryInteger<T>;
    public static void DivRem<T>(ROSpan<T> x, T y, Span<T> quotientDestination, Span<T> remainderDestination) where T : IBinaryInteger<T>;
    public static void DivRem<T>(T x, ROSpan<T> y, Span<T> quotientDestination, Span<T> remainderDestination) where T : IBinaryInteger<T>;

    public static void Decrement<T>(ROSpan<T> x, Span<T> destination) where T : IDecrementOperators<T, T>;

    public static void Increment<T>(ROSpan<T> x, Span<T> destination) where T : IIncrementOperators<T, T>;

    public static void Remainder<T>(ROSpan<T> x, ROSpan<T> y, Span<T> destination) where T : IModulusOperators<T, T, T>;
    public static void Remainder<T>(ROSpan<T> x, T y, Span<T> destination) where T : IModulusOperators<T, T, T>;
    public static void Remainder<T>(T x, ROSpan<T> y, Span<T> destination) where T : IModulusOperators<T, T, T>;

    public static void Sign<T>(ROSpan<T> x, in Span<int> destination) where T : INumber<T>;

    public static T StdDev<T>(ROSpan<T> x) where T : IPowerFunctions<T>;
}
gaviny82 commented 4 months ago

for things like Vector2/3/4 and Vector64/128/256/512

general language features oriented around collection expressions, index/range/slice

Vector2/3/4 have been in System.Numerics for a long time and they use Length() and LengthSquared() as the 2-norm of the vector. Using "length" as the number of elements in System.Numerics.Tensor is already breaking the consistency.

Vector64/128/256/512<T> for SIMD and other language features are at a lower level, where "length" is indeed the best terminology describing this property.

It also uses the term Count for some of the collection types, but they are their own category separate from the previous set of types that Tensor and TensorSpan will fit into.

It's impossible to find a universal term that applies to everything that is like an array or implemented by an array, but for Tensor, it's designed specifically for math and numerical algorithms and I think it can have its own name Size like the exceptions for collections in System.Collections.

Tensor is fitting into/extending as a form of general n-dimensional array + operator support for .NET. We don't really have a convention for using the term size or sizes

This means Tensor is simply an extension of System.Array. I thought it was a new type optimized for numerics, since it's in the System.Numerics namespace and we also have Tensor.Resize*.

pytorch is an example where they expose size() and shape() as aliases to mean what we plan to expose as Lengths.

I think shape() as an alias is for parity with NumPy. "Size" is better than "shape" given that reshape() means creating a new tensor while resize() changes its own size. As far as I know, no other ecosystem uses "length" for tensors specifically.

To summarize, in my opinion, calling the number of elements "lengths" in Tensor is not a good idea because:

  1. Ambiguous between "length" as a norm and number of elements and "length" as a norm (Euclidean distance) is very common in numerical applications
  2. Inconsistent with existing types in System.Numerics
  3. We have Tensor.Resize*

Finally, I would accept "Lengths" with clear documentation. It's the trade-off between its meaning, consistency, design patterns and so many factors. Thank you for explaining the detailed decision process.

colejohnson66 commented 4 months ago

@gaviny82 "Shape" was the initial proposal, but part 1's second review renamed it to "Lengths". (Video)

gaviny82 commented 4 months ago

@gaviny82 "Shape" was the initial proposal, but part 1's second review renamed it to "Lengths". (Video)

I was aware of this change, and I agree "Shape" might not be a good name.

I just feel "Lengths" is much worse than "Shape" in the context of math as discussed above. It's also inconsistent with other APIs in System.Numerics (e.g. Vector3.Length()). I'm not sure what Resize does, but "Size", "Dimensions" ... could be alternative names.

Neme12 commented 1 month ago

Wouldn't the methods that are supposedly non-allocating and write to a destination span while returning a sliced destination span, e.g.

public static TensorSpan<T> CosineSimilarity<T>(scoped in ROTensorSpan<T> x, scoped in ROTensorSpan<T> y, in TensorSpan<T> destination) where T : IRootFunctions<T>;

still have to allocate the lengths array (and maybe strides?) of the returned span? Are we not worried about this allocation? Or should they accept a Span<nint> newLengths parameter that the caller can stackalloc? Or maybe take destination by ref and simply update the destination span in place, while reusing it's inner spans?

tannergooding commented 1 month ago

There is an inline buffer that is used for the most common lengths. We will indeed have to allocate if you go beyond this (more than 5 dimensions), but that should be exceedingly rare and acceptable in such situations.

Due to how lifetimes work, particularly in ref structs, there isn't really a good or "safe" API design that would allow a custom buffer to be easily provided to guarantee allocation free in all scenarios.