File: System\Numerics\Tensors\netcore\TensorExtensions.cs
Web Access
Project: src\src\libraries\System.Numerics.Tensors\src\System.Numerics.Tensors.csproj (System.Numerics.Tensors)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Buffers;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Security.Cryptography;
using System.Runtime.Serialization;
using System.Diagnostics.CodeAnalysis;
 
#pragma warning disable CS8601 // Possible null reference assignment.
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
 
namespace System.Numerics.Tensors
{
    /// <summary>
    /// Provides methods for tensor operations.
    /// </summary>
    [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
    public static partial class Tensor
    {
        #region AsReadOnlySpan
        /// <summary>
        /// Extension method to more easily create a TensorSpan from an array.
        /// </summary>
        /// <typeparam name="T">The type of the elements in the array</typeparam>
        /// <param name="array">The <see cref="Array"/> with the data</param>
        /// <param name="lengths">The shape for the <see cref="TensorSpan{T}"/></param>
        /// <returns></returns>
        public static ReadOnlyTensorSpan<T> AsReadOnlyTensorSpan<T>(this T[]? array, params scoped ReadOnlySpan<nint> lengths) => new(array, 0, lengths, default);
        #endregion
 
        #region AsTensorSpan
        /// <summary>
        /// Extension method to more easily create a TensorSpan from an array.
        /// </summary>
        /// <typeparam name="T">The type of the elements in the array</typeparam>
        /// <param name="array">The <see cref="Array"/> with the data</param>
        /// <param name="lengths">The shape for the <see cref="TensorSpan{T}"/></param>
        /// <returns></returns>
        public static TensorSpan<T> AsTensorSpan<T>(this T[]? array, params scoped ReadOnlySpan<nint> lengths) => new(array, 0, lengths, default);
        #endregion
 
        #region Average
        /// <summary>
        /// Returns the average of the elements in the <paramref name="x"/> tensor.
        /// </summary>
        /// <param name="x">The <see cref="TensorSpan{T}"/> to take the mean of.</param>
        /// <returns><typeparamref name="T"/> representing the mean.</returns>
        public static T Average<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPoint<T>
        {
            T sum = Sum(x);
            return T.CreateChecked(sum / T.CreateChecked(x.FlattenedLength));
        }
        #endregion
 
        #region Broadcast
        /// <summary>
        /// Broadcast the data from <paramref name="source"/> to the smallest broadcastable shape compatible with <paramref name="lengthsSource"/>. Creates a new <see cref="Tensor{T}"/> and allocates new memory.
        /// </summary>
        /// <param name="source">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="lengthsSource">Other <see cref="Tensor{T}"/> to make shapes broadcastable.</param>
        public static Tensor<T> Broadcast<T>(scoped in ReadOnlyTensorSpan<T> source, scoped in ReadOnlyTensorSpan<T> lengthsSource)
        {
            return Broadcast(source, lengthsSource.Lengths);
        }
 
        /// <summary>
        /// Broadcast the data from <paramref name="source"/> to the new shape <paramref name="lengths"/>. Creates a new <see cref="Tensor{T}"/> and allocates new memory.
        /// If the shape of the <paramref name="source"/> is not compatible with the new shape, an exception is thrown.
        /// </summary>
        /// <param name="source">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="lengths"><see cref="ReadOnlySpan{T}"/> of the desired new shape.</param>
        /// <exception cref="ArgumentException">Thrown when the shapes are not broadcast compatible.</exception>
        public static Tensor<T> Broadcast<T>(scoped in ReadOnlyTensorSpan<T> source, scoped ReadOnlySpan<nint> lengths)
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(source.Lengths, lengths);
 
            ReadOnlyTensorSpan<T> intermediate = LazyBroadcast(source, newSize);
            Tensor<T> output = Tensor.CreateUninitialized<T>(intermediate.Lengths);
            intermediate.FlattenTo(MemoryMarshal.CreateSpan(ref output._values[0], (int)output.FlattenedLength));
            return output;
        }
        #endregion
 
        #region BroadcastTo
        /// <summary>
        /// Broadcast the data from <paramref name="source"/> to <paramref name="destination"/>.
        /// </summary>
        /// <param name="source">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static void BroadcastTo<T>(this Tensor<T> source, in TensorSpan<T> destination)
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(source.Lengths, destination.Lengths);
            if (!destination.Lengths.SequenceEqual(newSize))
                ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible();
 
            ReadOnlyTensorSpan<T> intermediate = LazyBroadcast(source, newSize);
            intermediate.FlattenTo(MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength));
        }
 
        /// <summary>
        /// Broadcast the data from <paramref name="source"/> to <paramref name="destination"/>.
        /// </summary>
        /// <param name="source">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="destination">Other <see cref="TensorSpan{T}"/> to make shapes broadcastable.</param>
        public static void BroadcastTo<T>(in this TensorSpan<T> source, in TensorSpan<T> destination)
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(source.Lengths, destination.Lengths);
            if (!destination.Lengths.SequenceEqual(newSize))
                ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible();
 
            ReadOnlyTensorSpan<T> intermediate = LazyBroadcast(source, newSize);
            intermediate.FlattenTo(MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength));
        }
 
        /// <summary>
        /// Broadcast the data from <paramref name="source"/> to <paramref name="destination"/>.
        /// </summary>
        /// <param name="source">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static void BroadcastTo<T>(in this ReadOnlyTensorSpan<T> source, in TensorSpan<T> destination)
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(source.Lengths, destination.Lengths);
            if (!destination.Lengths.SequenceEqual(newSize))
                ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible();
 
            ReadOnlyTensorSpan<T> intermediate = LazyBroadcast(source, newSize);
            intermediate.FlattenTo(MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength));
        }
 
        // Lazy/non-copy broadcasting, internal only for now.
        /// <summary>
        /// Broadcast the data from <paramref name="input"/> to the new shape <paramref name="shape"/>. Creates a new <see cref="Tensor{T}"/>
        /// but no memory is allocated. It manipulates the strides to achieve this affect.
        /// If the shape of the <paramref name="input"/> is not compatible with the new shape, an exception is thrown.
        /// </summary>
        /// <param name="input">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="shape"><see cref="ReadOnlySpan{T}"/> of the desired new shape.</param>
        /// <exception cref="ArgumentException">Thrown when the shapes are not broadcast compatible.</exception>
        internal static TensorSpan<T> LazyBroadcast<T>(in TensorSpan<T> input, ReadOnlySpan<nint> shape)
        {
            if (input.Lengths.SequenceEqual(shape))
                return new TensorSpan<T>(ref input._reference, shape, input.Strides, input._shape._memoryLength);
 
            if (!TensorHelpers.IsBroadcastableTo(input.Lengths, shape))
                ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible();
 
            nint newSize = TensorSpanHelpers.CalculateTotalLength(shape);
 
            if (newSize == input.FlattenedLength)
                return Reshape(input, shape);
 
            nint[] intermediateShape = TensorHelpers.GetIntermediateShape(input.Lengths, shape.Length);
            nint[] strides = new nint[shape.Length];
 
            nint stride = 1;
 
            for (int i = strides.Length - 1; i >= 0; i--)
            {
                if ((intermediateShape[i] == 1 && shape[i] != 1) || (intermediateShape[i] == 1 && shape[i] == 1))
                    strides[i] = 0;
                else
                {
                    strides[i] = stride;
                    stride *= intermediateShape[i];
                }
            }
 
            TensorSpan<T> output = new TensorSpan<T>(ref input._reference, shape, strides, input._shape._memoryLength);
 
            return output;
        }
 
        // Lazy/non-copy broadcasting, internal only for now.
        /// <summary>
        /// Broadcast the data from <paramref name="input"/> to the new shape <paramref name="shape"/>. Creates a new <see cref="Tensor{T}"/>
        /// but no memory is allocated. It manipulates the strides to achieve this affect.
        /// If the shape of the <paramref name="input"/> is not compatible with the new shape, an exception is thrown.
        /// </summary>
        /// <param name="input">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="shape"><see cref="ReadOnlySpan{T}"/> of the desired new shape.</param>
        /// <exception cref="ArgumentException">Thrown when the shapes are not broadcast compatible.</exception>
        internal static ReadOnlyTensorSpan<T> LazyBroadcast<T>(in ReadOnlyTensorSpan<T> input, ReadOnlySpan<nint> shape)
        {
            if (input.Lengths.SequenceEqual(shape))
                return new TensorSpan<T>(ref input._reference, shape, input.Strides, input._shape._memoryLength);
 
            if (!TensorHelpers.IsBroadcastableTo(input.Lengths, shape))
                ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible();
 
            nint newSize = TensorSpanHelpers.CalculateTotalLength(shape);
 
            if (newSize == input.FlattenedLength)
                return Reshape(input, shape);
 
            nint[] intermediateShape = TensorHelpers.GetIntermediateShape(input.Lengths, shape.Length);
            nint[] strides = new nint[shape.Length];
 
            nint stride = 1;
 
            for (int i = strides.Length - 1; i >= 0; i--)
            {
                if ((intermediateShape[i] == 1 && shape[i] != 1) || (intermediateShape[i] == 1 && shape[i] == 1))
                    strides[i] = 0;
                else
                {
                    strides[i] = stride;
                    stride *= intermediateShape[i];
                }
            }
 
            TensorSpan<T> output = new TensorSpan<T>(ref input._reference, shape, strides, input._shape._memoryLength);
 
            return output;
        }
 
        // Lazy/non-copy broadcasting, internal only for now.
        /// <summary>
        /// Broadcast the data from <paramref name="input"/> to the new shape <paramref name="lengths"/>. Creates a new <see cref="Tensor{T}"/>
        /// but no memory is allocated. It manipulates the strides to achieve this affect.
        /// If the shape of the <paramref name="input"/> is not compatible with the new shape, an exception is thrown.
        /// </summary>
        /// <param name="input">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="lengths"><see cref="ReadOnlySpan{T}"/> of the desired new shape.</param>
        /// <exception cref="ArgumentException">Thrown when the shapes are not broadcast compatible.</exception>
        internal static Tensor<T> LazyBroadcast<T>(Tensor<T> input, ReadOnlySpan<nint> lengths)
        {
            if (input.Lengths.SequenceEqual(lengths))
                return new Tensor<T>(input._values, lengths, false);
 
            if (!TensorHelpers.IsBroadcastableTo(input.Lengths, lengths))
                ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible();
 
            nint newSize = TensorSpanHelpers.CalculateTotalLength(lengths);
 
            if (newSize == input.FlattenedLength)
                return Reshape(input, lengths);
 
            nint[] intermediateShape = TensorHelpers.GetIntermediateShape(input.Lengths, lengths.Length);
            nint[] strides = new nint[lengths.Length];
 
            nint stride = 1;
 
            for (int i = strides.Length - 1; i >= 0; i--)
            {
                if ((intermediateShape[i] == 1 && lengths[i] != 1) || (intermediateShape[i] == 1 && lengths[i] == 1))
                    strides[i] = 0;
                else
                {
                    strides[i] = stride;
                    stride *= intermediateShape[i];
                }
            }
 
            Tensor<T> output = new Tensor<T>(input._values, lengths, strides);
 
            return output;
        }
        #endregion
 
        #region Concatenate
        /// <summary>
        /// Join a sequence of tensors along an existing axis.
        /// </summary>
        /// <param name="tensors">The tensors must have the same shape, except in the dimension corresponding to axis (the first, by default).</param>
        public static Tensor<T> Concatenate<T>(params scoped ReadOnlySpan<Tensor<T>> tensors)
        {
            return ConcatenateOnDimension(0, tensors);
        }
 
        /// <summary>
        /// Join a sequence of tensors along an existing axis.
        /// </summary>
        /// <param name="tensors">The tensors must have the same shape, except in the dimension corresponding to axis (the first, by default).</param>
        /// <param name="dimension">The axis along which the tensors will be joined. If axis is -1, arrays are flattened before use. Default is 0.</param>
        public static Tensor<T> ConcatenateOnDimension<T>(int dimension, params scoped ReadOnlySpan<Tensor<T>> tensors)
        {
            if (tensors.Length < 2)
                ThrowHelper.ThrowArgument_ConcatenateTooFewTensors();
 
            if (dimension < -1 || dimension > tensors[0].Rank)
                ThrowHelper.ThrowArgument_InvalidAxis();
 
            // Calculate total space needed.
            nint totalLength = 0;
            for (int i = 0; i < tensors.Length; i++)
                totalLength += TensorSpanHelpers.CalculateTotalLength(tensors[i].Lengths);
 
            nint sumOfAxis = 0;
            // If axis != -1, make sure all dimensions except the one to concatenate on match.
            if (dimension != -1)
            {
                sumOfAxis = tensors[0].Lengths[dimension];
                for (int i = 1; i < tensors.Length; i++)
                {
                    if (tensors[0].Rank != tensors[i].Rank)
                        ThrowHelper.ThrowArgument_InvalidConcatenateShape();
                    for (int j = 0; j < tensors[0].Rank; j++)
                    {
                        if (j != dimension)
                        {
                            if (tensors[0].Lengths[j] != tensors[i].Lengths[j])
                                ThrowHelper.ThrowArgument_InvalidConcatenateShape();
                        }
                    }
                    sumOfAxis += tensors[i].Lengths[dimension];
                }
            }
 
            Tensor<T> tensor;
            if (dimension == -1)
            {
                tensor = Tensor.Create<T>([totalLength]);
            }
            else
            {
                nint[] lengths = new nint[tensors[0].Rank];
                tensors[0].Lengths.CopyTo(lengths);
                lengths[dimension] = sumOfAxis;
                tensor = Tensor.Create<T>(lengths);
            }
 
            ConcatenateOnDimension(dimension, tensors, tensor);
            return tensor;
        }
 
        /// <summary>
        /// Join a sequence of tensors along an existing axis.
        /// </summary>
        /// <param name="tensors">The tensors must have the same shape, except in the dimension corresponding to axis (the first, by default).</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Concatenate<T>(scoped ReadOnlySpan<Tensor<T>> tensors, in TensorSpan<T> destination)
        {
            return ref ConcatenateOnDimension(0, tensors, destination);
        }
 
        /// <summary>
        /// Join a sequence of tensors along an existing axis.
        /// </summary>
        /// <param name="tensors">The tensors must have the same shape, except in the dimension corresponding to axis (the first, by default).</param>
        /// <param name="dimension">The axis along which the tensors will be joined. If axis is -1, arrays are flattened before use. Default is 0.</param>
        /// <param name="destination"></param>
 
        public static ref readonly TensorSpan<T> ConcatenateOnDimension<T>(int dimension, scoped ReadOnlySpan<Tensor<T>> tensors, in TensorSpan<T> destination)
        {
            if (tensors.Length < 2)
                ThrowHelper.ThrowArgument_ConcatenateTooFewTensors();
 
            if (dimension < -1 || dimension > tensors[0].Rank)
                ThrowHelper.ThrowArgument_InvalidAxis();
 
            // Calculate total space needed.
            nint totalLength = 0;
            for (int i = 0; i < tensors.Length; i++)
                totalLength += TensorSpanHelpers.CalculateTotalLength(tensors[i].Lengths);
 
            nint sumOfAxis = 0;
            // If axis != -1, make sure all dimensions except the one to concatenate on match.
            if (dimension != -1)
            {
                sumOfAxis = tensors[0].Lengths[dimension];
                for (int i = 1; i < tensors.Length; i++)
                {
                    if (tensors[0].Rank != tensors[i].Rank)
                        ThrowHelper.ThrowArgument_InvalidConcatenateShape();
                    for (int j = 0; j < tensors[0].Rank; j++)
                    {
                        if (j != dimension)
                        {
                            if (tensors[0].Lengths[j] != tensors[i].Lengths[j])
                                ThrowHelper.ThrowArgument_InvalidConcatenateShape();
                        }
                    }
                    sumOfAxis += tensors[i].Lengths[dimension];
                }
 
                // Make sure the destination tensor has the correct shape.
                nint[] lengths = new nint[tensors[0].Rank];
                tensors[0].Lengths.CopyTo(lengths);
                lengths[dimension] = sumOfAxis;
 
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, lengths))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
            }
            Span<T> dstSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)totalLength);
            nint valuesCopied = 0;
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (tensors[0].Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(tensors[0].Rank);
                curIndex = curIndexArray.AsSpan(0, tensors[0].Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[tensors[0].Rank];
            }
            curIndex.Clear();
 
            nint srcIndex;
            nint copyLength;
 
            while (valuesCopied < totalLength)
            {
                for (int i = 0; i < tensors.Length; i++)
                {
                    srcIndex = TensorSpanHelpers.ComputeLinearIndex(curIndex, tensors[i].Strides, tensors[i].Lengths);
                    copyLength = CalculateCopyLength(tensors[i].Lengths, dimension);
                    Span<T> srcSpan = MemoryMarshal.CreateSpan(ref tensors[i]._values[srcIndex], (int)copyLength);
                    TensorSpanHelpers.Memmove(dstSpan, srcSpan, copyLength, valuesCopied);
                    valuesCopied += copyLength;
                }
                TensorSpanHelpers.AdjustIndexes(dimension - 1, 1, curIndex, tensors[0].Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        private static nint CalculateCopyLength(ReadOnlySpan<nint> lengths, int startingAxis)
        {
            // When starting axis is -1 we want all the data at once same as if starting axis is 0
            if (startingAxis == -1)
                startingAxis = 0;
            nint length = 1;
            for (int i = startingAxis; i < lengths.Length; i++)
            {
                length *= lengths[i];
            }
            return length;
        }
        #endregion
 
        #region Equals
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> for equality. If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size
        /// before they are compared. It returns a <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <returns>A <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not.</returns>
        public static Tensor<bool> Equals<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IEqualityOperators<T, T, bool>
        {
            Tensor<bool> result;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                result = Tensor.Create<bool>(x.Lengths, false);
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                result = Tensor.Create<bool>(newSize, false);
            }
 
            Equals(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> for equality. If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size
        /// before they are compared. It returns a <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="destination"></param>
        /// <returns>A <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> Equals<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IEqualityOperators<T, T, bool>
        {
            scoped ReadOnlyTensorSpan<T> left;
            scoped ReadOnlyTensorSpan<T> right;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = x;
                right = y;
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, newSize))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = LazyBroadcast(x, newSize);
                right = LazyBroadcast(y, newSize);
            }
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (right.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(right.Rank);
                curIndex = curIndexArray.AsSpan(0, right.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[right.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < left.FlattenedLength; i++)
            {
                destination[curIndex] = left[curIndex] == right[curIndex];
                TensorSpanHelpers.AdjustIndexes(right.Rank - 1, 1, curIndex, right.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> for equality. If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size
        /// before they are compared. It returns a <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second value to compare.</param>
        /// <returns>A <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not.</returns>
        public static Tensor<bool> Equals<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IEqualityOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(x.Lengths, false);
            Equals(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> for equality. If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size
        /// before they are compared. It returns a <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second value to compare.</param>
        /// <param name="destination"></param>
        /// <returns>A <see cref="TensorSpan{Boolean}"/> where the value is true if the elements are equal and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> Equals<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<bool> destination)
            where T : IEqualityOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                destination[curIndex] = x[curIndex] == y;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
        #endregion
 
        #region EqualsAll
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are equal to <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are eqaul to <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are equal to <paramref name="y"/>.</returns>
        public static bool EqualsAll<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IEqualityOperators<T, T, bool>
        {
 
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedLeft.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Rank);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] != broadcastedRight[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are equal to <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are eqaul to <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are equal to <paramref name="y"/>.</returns>
        public static bool EqualsAll<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IEqualityOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] != y)
                    return false;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
        #endregion
 
        #region EqualsAny
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are equal to <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are equal to <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are equal to <paramref name="y"/>.</returns>
        public static bool EqualsAny<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IEqualityOperators<T, T, bool>
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedRight.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Lengths.Length);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Lengths.Length];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] == broadcastedRight[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are equal to <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are equal to <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are equal to <paramref name="y"/>.</returns>
        public static bool EqualsAny<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IEqualityOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] == y)
                    return true;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
        #endregion
 
        #region FilteredUpdate
        /// <summary>
        /// Updates the <paramref name="tensor"/> tensor with the <paramref name="value"/> where the <paramref name="filter"/> is true.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="filter">Input filter where if the index is true then it will update the <paramref name="tensor"/>.</param>
        /// <param name="value">Value to update in the <paramref name="tensor"/>.</param>
        public static ref readonly TensorSpan<T> FilteredUpdate<T>(in this TensorSpan<T> tensor, scoped in ReadOnlyTensorSpan<bool> filter, T value)
        {
            if (filter.Lengths.Length != tensor.Lengths.Length)
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(filter));
 
            Span<T> srcSpan = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor._shape._memoryLength);
            Span<bool> filterSpan = MemoryMarshal.CreateSpan(ref filter._reference, (int)tensor._shape._memoryLength);
 
            for (int i = 0; i < filterSpan.Length; i++)
            {
                if (filterSpan[i])
                {
                    srcSpan[i] = value;
                }
            }
 
            return ref tensor;
        }
 
        /// <summary>
        /// Updates the <paramref name="tensor"/> tensor with the <paramref name="values"/> where the <paramref name="filter"/> is true.
        /// If dimensions are not the same an exception is thrown.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="filter">Input filter where if the index is true then it will update the <paramref name="tensor"/>.</param>
        /// <param name="values">Values to update in the <paramref name="tensor"/>.</param>
        public static ref readonly TensorSpan<T> FilteredUpdate<T>(in this TensorSpan<T> tensor, scoped in ReadOnlyTensorSpan<bool> filter, scoped in ReadOnlyTensorSpan<T> values)
        {
            if (filter.Lengths.Length != tensor.Lengths.Length)
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(filter));
            if (values.Rank != 1)
                ThrowHelper.ThrowArgument_1DTensorRequired(nameof(values));
 
            Span<T> dstSpan = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor._shape._memoryLength);
            Span<bool> filterSpan = MemoryMarshal.CreateSpan(ref filter._reference, (int)tensor._shape._memoryLength);
            Span<T> valuesSpan = MemoryMarshal.CreateSpan(ref values._reference, (int)values._shape._memoryLength);
 
            int index = 0;
            for (int i = 0; i < filterSpan.Length; i++)
            {
                if (filterSpan[i])
                {
                    dstSpan[i] = valuesSpan[index++];
                }
            }
 
            return ref tensor;
        }
        #endregion
 
        #region GreaterThan
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static Tensor<bool> GreaterThan<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                result = Tensor.Create<bool>(x.Lengths, false);
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                result = Tensor.Create<bool>(newSize, false);
            }
 
            GreaterThan(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="destination"></param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static ref readonly TensorSpan<bool> GreaterThan<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped ReadOnlyTensorSpan<T> left;
            scoped ReadOnlyTensorSpan<T> right;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = x;
                right = y;
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, newSize))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = LazyBroadcast(x, newSize);
                right = LazyBroadcast(y, newSize);
            }
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (right.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(right.Rank);
                curIndex = curIndexArray.AsSpan(0, right.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[right.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < left.FlattenedLength; i++)
            {
                destination[curIndex] = left[curIndex] > right[curIndex];
                TensorSpanHelpers.AdjustIndexes(right.Rank - 1, 1, curIndex, right.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="ReadOnlyTensorSpan{T}"/> to see which elements are greater than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> GreaterThan<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(x.Lengths, false);
            GreaterThan(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="ReadOnlyTensorSpan{T}"/> to see which elements are greater than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> GreaterThan<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                destination[curIndex] = x[curIndex] > y;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares <paramref name="x"/> to see which elements are greater than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> GreaterThan<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(y.Lengths, false);
            GreaterThan(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares <paramref name="x"/> to see which elements are greater than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> GreaterThan<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, y.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                destination[curIndex] = x > y[curIndex];
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
        #endregion
 
        #region GreaterThanOrEqual
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are greater than or equal to <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static Tensor<bool> GreaterThanOrEqual<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                result = Tensor.Create<bool>(x.Lengths, false);
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                result = Tensor.Create<bool>(newSize, false);
            }
 
            GreaterThanOrEqual(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are greater than or equal to <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="destination"></param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static ref readonly TensorSpan<bool> GreaterThanOrEqual<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped ReadOnlyTensorSpan<T> left;
            scoped ReadOnlyTensorSpan<T> right;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = x;
                right = y;
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, newSize))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = LazyBroadcast(x, newSize);
                right = LazyBroadcast(y, newSize);
            }
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (right.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(right.Rank);
                curIndex = curIndexArray.AsSpan(0, right.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[right.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < left.FlattenedLength; i++)
            {
                destination[curIndex] = left[curIndex] >= right[curIndex];
                TensorSpanHelpers.AdjustIndexes(right.Rank - 1, 1, curIndex, right.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="ReadOnlyTensorSpan{T}"/> to see which elements are greater than or equal to <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> GreaterThanOrEqual<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(x.Lengths, false);
            GreaterThanOrEqual(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="ReadOnlyTensorSpan{T}"/> to see which elements are greater than or equal to <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> GreaterThanOrEqual<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                destination[curIndex] = x[curIndex] >= y;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares <paramref name="x"/> to see which elements are greater than or equal to <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> GreaterThanOrEqual<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(y.Lengths, false);
            GreaterThanOrEqual(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares <paramref name="x"/> to see which elements are greater than or equal to <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are greater than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> GreaterThanOrEqual<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, y.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                destination[curIndex] = x >= y[curIndex];
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
        #endregion
 
        #region GreaterThanAny
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanAny<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedRight.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Lengths.Length);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Lengths.Length];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] > broadcastedRight[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanAny<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] > y)
                    return true;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="y"/> are greater than <paramref name="x"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are greater than <paramref name="x"/>.
        /// </summary>
        /// <param name="y">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="x">Value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are greater than <paramref name="x"/>.</returns>
        public static bool GreaterThanAny<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                if (x > y[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
        #endregion
 
        #region GreaterThanOrEqualAny
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanOrEqualAny<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedRight.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Lengths.Length);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Lengths.Length];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] >= broadcastedRight[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanOrEqualAny<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] >= y)
                    return true;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="y"/> are greater than <paramref name="x"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are greater than <paramref name="x"/>.
        /// </summary>
        /// <param name="y">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="x">Value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are greater than <paramref name="x"/>.</returns>
        public static bool GreaterThanOrEqualAny<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                if (x >= y[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
        #endregion
 
        #region GreaterThanAll
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanAll<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
 
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedLeft.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Rank);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] <= broadcastedRight[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanAll<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] <= y)
                    return false;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="y"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanAll<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                if (x <= y[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
        #endregion
 
        #region GreaterThanOrEqualAll
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanOrEqualAll<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
 
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedLeft.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Rank);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] < broadcastedRight[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanOrEqualAll<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] < y)
                    return false;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="y"/> are greater than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are greater than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are greater than <paramref name="y"/>.</returns>
        public static bool GreaterThanOrEqualAll<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                if (x < y[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
        #endregion
 
        #region LessThan
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static Tensor<bool> LessThan<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                result = Tensor.Create<bool>(x.Lengths, false);
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                result = Tensor.Create<bool>(newSize, false);
            }
 
            LessThan(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="destination"></param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static ref readonly TensorSpan<bool> LessThan<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped ReadOnlyTensorSpan<T> left;
            scoped ReadOnlyTensorSpan<T> right;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = x;
                right = y;
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, newSize))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = LazyBroadcast(x, newSize);
                right = LazyBroadcast(y, newSize);
            }
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (right.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(right.Rank);
                curIndex = curIndexArray.AsSpan(0, right.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[right.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < left.FlattenedLength; i++)
            {
                destination[curIndex] = left[curIndex] < right[curIndex];
                TensorSpanHelpers.AdjustIndexes(right.Rank - 1, 1, curIndex, right.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> LessThan<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(x.Lengths, false);
            LessThan(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> LessThan<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                destination[curIndex] = x[curIndex] < y;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> LessThan<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(y.Lengths, false);
            LessThan(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> LessThan<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, y.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                destination[curIndex] = x < y[curIndex];
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
        #endregion
 
        #region LessThanOrEqual
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static Tensor<bool> LessThanOrEqual<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                result = Tensor.Create<bool>(x.Lengths, false);
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                result = Tensor.Create<bool>(newSize, false);
            }
 
            LessThanOrEqual(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see which elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="destination"></param>
        /// <returns>A <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/> and
        /// false if they are not.</returns>
        public static ref readonly TensorSpan<bool> LessThanOrEqual<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped ReadOnlyTensorSpan<T> left;
            scoped ReadOnlyTensorSpan<T> right;
            if (TensorHelpers.AreLengthsTheSame(x, y))
            {
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = x;
                right = y;
            }
            else
            {
                nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
                if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, newSize))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
                left = LazyBroadcast(x, newSize);
                right = LazyBroadcast(y, newSize);
            }
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (right.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(right.Rank);
                curIndex = curIndexArray.AsSpan(0, right.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[right.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < left.FlattenedLength; i++)
            {
                destination[curIndex] = left[curIndex] <= right[curIndex];
                TensorSpanHelpers.AdjustIndexes(right.Rank - 1, 1, curIndex, right.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> LessThanOrEqual<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(x.Lengths, false);
            LessThanOrEqual(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> LessThanOrEqual<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, x.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                destination[curIndex] = x[curIndex] <= y;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static Tensor<bool> LessThanOrEqual<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            Tensor<bool> result = Tensor.Create<bool>(y.Lengths, false);
            LessThanOrEqual(x, y, result);
            return result;
        }
 
        /// <summary>
        /// Compares the elements of a <see cref="Tensor{T}"/> to see which elements are less than <paramref name="y"/>.
        /// It returns a <see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not."/>
        /// </summary>
        /// <param name="x"><see cref="Tensor{T}"/> to compare.</param>
        /// <param name="y"><typeparamref name="T"/> to compare against <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        /// <returns><see cref="Tensor{Boolean}"/> where the value is true if the elements in <paramref name="x"/> are less than <paramref name="y"/>
        /// and false if they are not.</returns>
        public static ref readonly TensorSpan<bool> LessThanOrEqual<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<bool> destination)
            where T : IComparisonOperators<T, T, bool>
        {
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, y.Lengths))
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                destination[curIndex] = x <= y[curIndex];
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return ref destination;
        }
        #endregion
 
        #region LessThanAny
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanAny<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
 
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedRight.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Lengths.Length);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Lengths.Length];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] < broadcastedRight[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanAny<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] < y)
                    return true;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="y"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First value to compare.</param>
        /// <param name="y">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanAny<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                if (x < y[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
        #endregion
 
        #region LessThanOrEqualAny
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanOrEqualAny<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
 
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedRight.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Lengths.Length);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Lengths.Length];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] <= broadcastedRight[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanOrEqualAny<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] <= y)
                    return true;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if any elements of <paramref name="y"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First value to compare.</param>
        /// <param name="y">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if any elements in <paramref name="y"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanOrEqualAny<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i <= y.FlattenedLength; i++)
            {
                if (x <= y[curIndex])
                    return true;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return false;
        }
        #endregion
 
        #region LessThanAll
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanAll<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedRight.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Lengths.Length);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Lengths.Length];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] >= broadcastedRight[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanAll<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] >= y)
                    return false;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="y"/> are less than <paramref name="x"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are less than <paramref name="x"/>.
        /// </summary>
        /// <param name="y">First value to compare.</param>
        /// <param name="x">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are less than <paramref name="x"/>.</returns>
        public static bool LessThanAll<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                if (x >= y[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
        #endregion
 
        #region LessThanOrEqualAll
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second <see cref="ReadOnlyTensorSpan{T}"/> to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanOrEqualAll<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(x.Lengths, y.Lengths);
            ReadOnlyTensorSpan<T> broadcastedLeft = LazyBroadcast(x, newSize);
            ReadOnlyTensorSpan<T> broadcastedRight = LazyBroadcast(y, newSize);
 
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (broadcastedRight.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(broadcastedRight.Lengths.Length);
                curIndex = curIndexArray.AsSpan(0, broadcastedRight.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[broadcastedRight.Lengths.Length];
            }
            curIndex.Clear();
 
            for (int i = 0; i < broadcastedLeft.FlattenedLength; i++)
            {
                if (broadcastedLeft[curIndex] > broadcastedRight[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(broadcastedRight.Rank - 1, 1, curIndex, broadcastedRight.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="x"/> are less than <paramref name="y"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.
        /// </summary>
        /// <param name="x">First <see cref="ReadOnlyTensorSpan{T}"/> to compare.</param>
        /// <param name="y">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="x"/> are less than <paramref name="y"/>.</returns>
        public static bool LessThanOrEqualAll<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (x.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(x.Rank);
                curIndex = curIndexArray.AsSpan(0, x.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[x.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < x.FlattenedLength; i++)
            {
                if (x[curIndex] > y)
                    return false;
                TensorSpanHelpers.AdjustIndexes(x.Rank - 1, 1, curIndex, x.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
 
        /// <summary>
        /// Compares the elements of two <see cref="ReadOnlyTensorSpan{T}"/> to see if all elements of <paramref name="y"/> are less than <paramref name="x"/>.
        /// If the shapes are not the same, the tensors are broadcasted to the smallest broadcastable size before they are compared.
        /// It returns a <see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are less than <paramref name="x"/>.
        /// </summary>
        /// <param name="y">First value to compare.</param>
        /// <param name="x">Second value to compare against.</param>
        /// <returns><see cref="bool"/> where the value is true if all elements in <paramref name="y"/> are less than <paramref name="x"/>.</returns>
        public static bool LessThanOrEqualAll<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IComparisonOperators<T, T, bool>
        {
            scoped Span<nint> curIndex;
            nint[]? curIndexArray;
 
            if (y.Rank > TensorShape.MaxInlineRank)
            {
                curIndexArray = ArrayPool<nint>.Shared.Rent(y.Rank);
                curIndex = curIndexArray.AsSpan(0, y.Rank);
            }
            else
            {
                curIndexArray = null;
                curIndex = stackalloc nint[y.Rank];
            }
            curIndex.Clear();
 
            for (int i = 0; i < y.FlattenedLength; i++)
            {
                if (x > y[curIndex])
                    return false;
                TensorSpanHelpers.AdjustIndexes(y.Rank - 1, 1, curIndex, y.Lengths);
            }
 
            if (curIndexArray != null)
                ArrayPool<nint>.Shared.Return(curIndexArray);
 
            return true;
        }
        #endregion
 
        #region Permute
 
        /// <summary>
        /// Swaps the dimensions of the <paramref name="tensor"/> tensor according to the <paramref name="dimensions"/> parameter.
        /// If <paramref name="tensor"/> is a 1D tensor, it will return <paramref name="tensor"/>. Otherwise it creates a new <see cref="Tensor{T}"/>
        /// with the new axis ordering by allocating new memory.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/></param>
        /// <param name="dimensions"><see cref="ReadOnlySpan{T}"/> with the new axis ordering.</param>
        public static Tensor<T> PermuteDimensions<T>(this Tensor<T> tensor, params ReadOnlySpan<int> dimensions)
        {
            if (tensor.Rank == 1)
            {
                return tensor;
            }
            else
            {
                T[] values = tensor.IsPinned ? GC.AllocateArray<T>((int)tensor._flattenedLength) : (new T[tensor._flattenedLength]);
                nint[] lengths = new nint[tensor.Rank];
                Tensor<T> outTensor;
                TensorSpan<T> ospan;
                TensorSpan<T> ispan;
                ReadOnlySpan<int> permutation;
 
                if (dimensions.IsEmpty)
                {
                    int[] tempPermutation = new int[tensor.Rank];
                    for (int i = 0; i < tensor.Rank; i++)
                    {
                        lengths[i] = tensor._lengths[tensor.Rank - 1 - i];
                        tempPermutation[i] = tensor.Rank - 1 - i;
                    }
 
                    permutation = tempPermutation;
                }
                else
                {
                    if (dimensions.Length != tensor.Lengths.Length)
                        ThrowHelper.ThrowArgument_PermuteAxisOrder();
                    for (int i = 0; i < lengths.Length; i++)
                        lengths[i] = tensor.Lengths[dimensions[i]];
                    permutation = dimensions.ToArray();
                }
                outTensor = new Tensor<T>(values, lengths, Array.Empty<nint>(), tensor._isPinned);
 
                ospan = outTensor.AsTensorSpan();
                ispan = tensor.AsTensorSpan();
 
                scoped Span<nint> indexes;
                nint[]? indicesArray;
                scoped Span<nint> permutedIndices;
                nint[]? permutedIndicesArray;
                if (outTensor.Rank > 6)
                {
                    indicesArray = ArrayPool<nint>.Shared.Rent(outTensor.Rank);
                    indexes = indicesArray.AsSpan(0, outTensor.Rank);
                    indexes.Clear();
 
                    permutedIndicesArray = ArrayPool<nint>.Shared.Rent(outTensor.Rank);
                    permutedIndices = permutedIndicesArray.AsSpan(0, outTensor.Rank);
                    permutedIndices.Clear();
                }
                else
                {
                    indicesArray = null;
                    indexes = stackalloc nint[outTensor.Rank];
                    permutedIndicesArray = null;
                    permutedIndices = stackalloc nint[outTensor.Rank];
                }
 
                for (int i = 0; i < tensor._flattenedLength; i++)
                {
                    TensorHelpers.PermuteIndices(indexes, permutedIndices, permutation);
                    ospan[permutedIndices] = ispan[indexes];
                    TensorSpanHelpers.AdjustIndexes(outTensor.Rank - 1, 1, indexes, tensor._lengths);
                }
 
                if (indicesArray != null && permutedIndicesArray != null)
                {
                    ArrayPool<nint>.Shared.Return(indicesArray);
                    ArrayPool<nint>.Shared.Return(permutedIndicesArray);
                }
 
                return outTensor;
            }
        }
        #endregion
 
        #region Reshape
        /// <summary>
        /// Reshapes the <paramref name="tensor"/> tensor to the specified <paramref name="lengths"/>. If one of the lengths is -1, it will be calculated automatically.
        /// Does not change the length of the underlying memory nor does it allocate new memory. If the new shape is not compatible with the old shape,
        /// an exception is thrown.
        /// </summary>
        /// <param name="tensor"><see cref="Tensor{T}"/> you want to reshape.</param>
        /// <param name="lengths"><see cref="ReadOnlySpan{T}"/> with the new dimensions.</param>
        public static Tensor<T> Reshape<T>(this Tensor<T> tensor, params ReadOnlySpan<nint> lengths)
        {
            if (tensor.Lengths.SequenceEqual(lengths))
                return tensor;
 
            if (!TensorHelpers.IsContiguousAndDense<T>(tensor) && !tensor.Strides.Contains(0))
            {
                ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense();
            }
 
            nint[] arrLengths = lengths.ToArray();
            // Calculate wildcard info.
            if (lengths.Contains(-1))
            {
                if (lengths.Count(-1) > 1)
                    ThrowHelper.ThrowArgument_OnlyOneWildcard();
                nint tempTotal = tensor._flattenedLength;
                for (int i = 0; i < lengths.Length; i++)
                {
                    if (lengths[i] != -1)
                    {
                        tempTotal /= lengths[i];
                    }
                }
                arrLengths[lengths.IndexOf(-1)] = tempTotal;
 
            }
 
            nint tempLinear = TensorSpanHelpers.CalculateTotalLength(arrLengths);
            if (tempLinear != tensor.FlattenedLength)
                ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
 
            nint[] strides;
 
            // If we contain a 0 stride we can only add dimensions of length 1.
            if (tensor.Strides.Contains(0))
            {
                List<nint> origStrides = new List<nint>(tensor.Strides.ToArray());
                int lengthOffset = 0;
                for (int i = 0; i < arrLengths.Length; i++)
                {
                    if (lengthOffset < tensor.Rank && arrLengths[i] == tensor.Lengths[lengthOffset])
                        lengthOffset++;
                    else if (arrLengths[i] == 1)
                    {
                        if (lengthOffset == tensor.Rank)
                            origStrides.Add(tensor.Strides[lengthOffset - 1]);
                        else
                            origStrides.Insert(i, tensor.Strides[i] * tensor.Lengths[i]);
                    }
                    else
                        ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
                }
                strides = origStrides.ToArray();
            }
            else
                strides = TensorSpanHelpers.CalculateStrides(arrLengths);
 
            return new Tensor<T>(tensor._values, arrLengths, strides);
        }
 
        /// <summary>
        /// Reshapes the <paramref name="tensor"/> tensor to the specified <paramref name="lengths"/>. If one of the lengths is -1, it will be calculated automatically.
        /// Does not change the length of the underlying memory nor does it allocate new memory. If the new shape is not compatible with the old shape,
        /// an exception is thrown.
        /// </summary>
        /// <param name="tensor"><see cref="TensorSpan{T}"/> you want to reshape.</param>
        /// <param name="lengths"><see cref="ReadOnlySpan{T}"/> with the new dimensions.</param>
        public static TensorSpan<T> Reshape<T>(in this TensorSpan<T> tensor, params scoped ReadOnlySpan<nint> lengths)
        {
            if (tensor.Lengths.SequenceEqual(lengths))
                return tensor;
 
            if (!TensorHelpers.IsContiguousAndDense<T>(tensor) && !tensor.Strides.Contains(0))
            {
                ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense();
            }
 
            nint[] arrLengths = lengths.ToArray();
            // Calculate wildcard info.
            if (lengths.Contains(-1))
            {
                if (lengths.Count(-1) > 1)
                    ThrowHelper.ThrowArgument_OnlyOneWildcard();
                nint tempTotal = tensor.FlattenedLength;
                for (int i = 0; i < lengths.Length; i++)
                {
                    if (lengths[i] != -1)
                    {
                        tempTotal /= lengths[i];
                    }
                }
                arrLengths[lengths.IndexOf(-1)] = tempTotal;
 
            }
 
            nint tempLinear = TensorSpanHelpers.CalculateTotalLength(arrLengths);
            if (tempLinear != tensor.FlattenedLength)
                ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
 
            nint[] strides;
 
            // If we contain a 0 stride we can only add dimensions of length 1.
            if (tensor.Strides.Contains(0))
            {
                List<nint> origStrides = new List<nint>(tensor.Strides.ToArray());
                int lengthOffset = 0;
                for (int i = 0; i < arrLengths.Length; i++)
                {
                    if (lengthOffset < tensor.Rank && arrLengths[i] == tensor.Lengths[lengthOffset])
                    {
                        lengthOffset++;
                    }
                    else if (arrLengths[i] == 1)
                    {
                        if (lengthOffset == tensor.Rank)
                            origStrides.Add(tensor.Strides[lengthOffset - 1]);
                        else
                            origStrides.Insert(i, tensor.Strides[i] * tensor.Lengths[i]);
                    }
                    else
                        ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
                }
                strides = origStrides.ToArray();
            }
            else
                strides = TensorSpanHelpers.CalculateStrides(arrLengths);
 
            TensorSpan<T> output = new TensorSpan<T>(ref tensor._reference, arrLengths, strides, tensor._shape._memoryLength);
            return output;
        }
 
        /// <summary>
        /// Reshapes the <paramref name="tensor"/> tensor to the specified <paramref name="lengths"/>. If one of the lengths is -1, it will be calculated automatically.
        /// Does not change the length of the underlying memory nor does it allocate new memory. If the new shape is not compatible with the old shape,
        /// an exception is thrown.
        /// </summary>
        /// <param name="tensor"><see cref="TensorSpan{T}"/> you want to reshape.</param>
        /// <param name="lengths"><see cref="ReadOnlySpan{T}"/> with the new dimensions.</param>
        public static ReadOnlyTensorSpan<T> Reshape<T>(in this ReadOnlyTensorSpan<T> tensor, params scoped ReadOnlySpan<nint> lengths)
        {
            if (tensor.Lengths.SequenceEqual(lengths))
                return tensor;
 
            if (!TensorHelpers.IsContiguousAndDense<T>(tensor) && !tensor.Strides.Contains(0))
            {
                ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense();
            }
 
            nint[] arrLengths = lengths.ToArray();
            // Calculate wildcard info.
            if (lengths.Contains(-1))
            {
                if (lengths.Count(-1) > 1)
                    ThrowHelper.ThrowArgument_OnlyOneWildcard();
                nint tempTotal = tensor.FlattenedLength;
                for (int i = 0; i < lengths.Length; i++)
                {
                    if (lengths[i] != -1)
                    {
                        tempTotal /= lengths[i];
                    }
                }
                arrLengths[lengths.IndexOf(-1)] = tempTotal;
 
            }
 
            nint tempLinear = TensorSpanHelpers.CalculateTotalLength(arrLengths);
            if (tempLinear != tensor.FlattenedLength)
                ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
 
            nint[] strides;
 
            // If we contain a 0 stride we can only add dimensions of length 1.
            if (tensor.Strides.Contains(0))
            {
                List<nint> origStrides = new List<nint>(tensor.Strides.ToArray());
                int lengthOffset = 0;
                for (int i = 0; i < arrLengths.Length; i++)
                {
                    if (lengthOffset < tensor.Rank && arrLengths[i] == tensor.Lengths[lengthOffset])
                        lengthOffset++;
                    else if (arrLengths[i] == 1)
                    {
                        if (lengthOffset == tensor.Rank)
                            origStrides.Add(tensor.Strides[lengthOffset - 1]);
                        else
                            origStrides.Insert(i, tensor.Strides[i] * tensor.Lengths[i]);
                    }
                    else
                        ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
                }
                strides = origStrides.ToArray();
            }
            else
                strides = TensorSpanHelpers.CalculateStrides(arrLengths);
 
            ReadOnlyTensorSpan<T> output = new ReadOnlyTensorSpan<T>(ref tensor._reference, arrLengths, strides, tensor._shape._memoryLength);
            return output;
        }
        #endregion
 
        #region Resize
        /// <summary>
        /// Creates a new <see cref="Tensor{T}"/>, allocates new memory, and copies the data from <paramref name="tensor"/>. If the final shape is smaller all data after
        /// that point is ignored.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="lengths"><see cref="ReadOnlySpan{T}"/> of the desired new shape.</param>
        public static Tensor<T> Resize<T>(Tensor<T> tensor, ReadOnlySpan<nint> lengths)
        {
            nint newSize = TensorSpanHelpers.CalculateTotalLength(lengths);
            T[] values = tensor.IsPinned ? GC.AllocateArray<T>((int)newSize) : (new T[newSize]);
            Tensor<T> output = new Tensor<T>(values, lengths, false);
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref tensor.AsTensorSpan()._reference, (int)tensor._values.Length);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref output.AsTensorSpan()._reference, (int)output.FlattenedLength);
            if (newSize > tensor._values.Length)
                TensorSpanHelpers.Memmove(ospan, span, tensor._values.Length);
            else
                TensorSpanHelpers.Memmove(ospan, span, newSize);
 
            return output;
        }
 
        /// <summary>
        /// Copies the data from <paramref name="tensor"/>. If the final shape is smaller all data after that point is ignored.
        /// If the final shape is bigger it is filled with 0s.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="destination">Destination <see cref="TensorSpan{T}"/> with the desired new shape.</param>
        public static void ResizeTo<T>(scoped in Tensor<T> tensor, in TensorSpan<T> destination)
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref tensor._values[0], tensor._values.Length);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            if (destination._shape._memoryLength > tensor._values.Length)
                TensorSpanHelpers.Memmove(ospan, span, tensor._values.Length);
            else
                TensorSpanHelpers.Memmove(ospan, span, destination._shape._memoryLength);
        }
 
        /// <summary>
        /// Copies the data from <paramref name="tensor"/>. If the final shape is smaller all data after that point is ignored.
        /// If the final shape is bigger it is filled with 0s.
        /// </summary>
        /// <param name="tensor">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="destination">Destination <see cref="TensorSpan{T}"/> with the desired new shape.</param>
        public static void ResizeTo<T>(scoped in TensorSpan<T> tensor, in TensorSpan<T> destination)
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            if (destination._shape._memoryLength > tensor._shape._memoryLength)
                TensorSpanHelpers.Memmove(ospan, span, tensor._shape._memoryLength);
            else
                TensorSpanHelpers.Memmove(ospan, span, destination._shape._memoryLength);
        }
 
        /// <summary>
        /// Copies the data from <paramref name="tensor"/>. If the final shape is smaller all data after that point is ignored.
        /// If the final shape is bigger it is filled with 0s.
        /// </summary>
        /// <param name="tensor">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination">Destination <see cref="TensorSpan{T}"/> with the desired new shape.</param>
        public static void ResizeTo<T>(scoped in ReadOnlyTensorSpan<T> tensor, in TensorSpan<T> destination)
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            if (destination._shape._memoryLength > tensor._shape._memoryLength)
                TensorSpanHelpers.Memmove(ospan, span, tensor._shape._memoryLength);
            else
                TensorSpanHelpers.Memmove(ospan, span, destination._shape._memoryLength);
        }
        #endregion
 
        #region Reverse
        /// <summary>
        /// Reverse the order of elements in the <paramref name="tensor"/>. The shape of the tensor is preserved, but the elements are reordered.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        public static Tensor<T> Reverse<T>(in ReadOnlyTensorSpan<T> tensor)
        {
            Tensor<T> output = Tensor.Create<T>(tensor.Lengths);
            ReverseDimension(tensor, output, -1);
 
            return output;
        }
 
        /// <summary>
        /// Reverse the order of elements in the <paramref name="tensor"/> along the given dimension. The shape of the tensor is preserved, but the elements are reordered.
        /// <paramref name="dimension"/> defaults to -1 when not provided, which reverses the entire tensor.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="dimension">dimension along which to reverse over. -1 will reverse over all of the dimensions of the left tensor.</param>
        public static Tensor<T> ReverseDimension<T>(in ReadOnlyTensorSpan<T> tensor, int dimension)
        {
            Tensor<T> output = Tensor.Create<T>(tensor.Lengths);
            ReverseDimension(tensor, output, dimension);
 
            return output;
        }
 
        /// <summary>
        /// Reverse the order of elements in the <paramref name="tensor"/>. The shape of the tensor is preserved, but the elements are reordered.
        /// </summary>
        /// <param name="tensor">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Reverse<T>(scoped in ReadOnlyTensorSpan<T> tensor, in TensorSpan<T> destination)
        {
            return ref ReverseDimension(tensor, destination, -1);
        }
 
        /// <summary>
        /// Reverse the order of elements in the <paramref name="tensor"/> along the given axis. The shape of the tensor is preserved, but the elements are reordered.
        /// <paramref name="dimension"/> defaults to -1 when not provided, which reverses the entire span.
        /// </summary>
        /// <param name="tensor">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        /// <param name="dimension">dimension along which to reverse over. -1 will reverse over all of the dimensions of the left tensor.</param>
        public static ref readonly TensorSpan<T> ReverseDimension<T>(scoped in ReadOnlyTensorSpan<T> tensor, in TensorSpan<T> destination, int dimension)
        {
            if (dimension == -1)
            {
                nint index = tensor._shape._memoryLength - 1;
                Span<T> inputSpan = MemoryMarshal.CreateSpan(ref tensor._reference, (int)tensor._shape._memoryLength);
                Span<T> outputSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
                for (int i = 0; i <= tensor._shape._memoryLength / 2; i++)
                {
                    outputSpan[i] = inputSpan[(int)index];
                    outputSpan[(int)index--] = inputSpan[i];
                }
            }
            else
            {
                nint copyLength = 1;
                for (nint i = dimension; i < tensor.Lengths.Length; i++)
                {
                    copyLength *= tensor.Lengths[(int)i];
                }
                copyLength /= tensor.Lengths[(int)dimension];
 
                scoped Span<nint> oIndices;
                nint[]? oIndicesArray;
                scoped Span<nint> iIndices;
                nint[]? iIndicesArray;
                if (tensor.Rank > 6)
                {
                    oIndicesArray = ArrayPool<nint>.Shared.Rent(tensor.Rank);
                    oIndices = oIndicesArray.AsSpan(0, tensor.Rank);
                    oIndices.Clear();
 
                    iIndicesArray = ArrayPool<nint>.Shared.Rent(tensor.Rank);
                    iIndices = iIndicesArray.AsSpan(0, tensor.Rank);
                    iIndices.Clear();
                }
                else
                {
                    oIndicesArray = null;
                    oIndices = stackalloc nint[tensor.Rank];
                    iIndicesArray = null;
                    iIndices = stackalloc nint[tensor.Rank];
                }
 
                iIndices[(int)dimension] = tensor.Lengths[(int)dimension] - 1;
                nint copiedValues = 0;
                ReadOnlyTensorSpan<T> islice = tensor.Slice(tensor.Lengths);
 
                while (copiedValues < tensor.FlattenedLength)
                {
                    TensorSpanHelpers.Memmove(ref Unsafe.Add(ref destination._reference, TensorSpanHelpers.ComputeLinearIndex(oIndices, tensor.Strides, tensor.Lengths)), ref Unsafe.Add(ref islice._reference, TensorSpanHelpers.ComputeLinearIndex(iIndices, islice.Strides, islice.Lengths)), copyLength);
                    TensorSpanHelpers.AdjustIndexes((int)dimension, 1, oIndices, tensor.Lengths);
                    TensorSpanHelpers.AdjustIndexesDown((int)dimension, 1, iIndices, tensor.Lengths);
                    copiedValues += copyLength;
                }
 
                if (oIndicesArray != null && iIndicesArray != null)
                {
                    ArrayPool<nint>.Shared.Return(oIndicesArray);
                    ArrayPool<nint>.Shared.Return(iIndicesArray);
                }
            }
 
            return ref destination;
        }
        #endregion
 
        #region SequenceEqual
        /// <summary>
        /// Determines whether two sequences are equal by comparing the elements using IEquatable{T}.Equals(T).
        /// </summary>
        public static bool SequenceEqual<T>(this scoped in TensorSpan<T> tensor, scoped in ReadOnlyTensorSpan<T> other)
            where T : IEquatable<T>?
        {
            return tensor.FlattenedLength == other.FlattenedLength
                && tensor._shape._memoryLength == other._shape._memoryLength
                && tensor.Lengths.SequenceEqual(other.Lengths)
                && MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape._memoryLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape._memoryLength));
        }
 
        /// <summary>
        /// Determines whether two sequences are equal by comparing the elements using IEquatable{T}.Equals(T).
        /// </summary>
        public static bool SequenceEqual<T>(this scoped in ReadOnlyTensorSpan<T> tensor, scoped in ReadOnlyTensorSpan<T> other)
            where T : IEquatable<T>?
        {
            return tensor.FlattenedLength == other.FlattenedLength
                && tensor._shape._memoryLength == other._shape._memoryLength
                && tensor.Lengths.SequenceEqual(other.Lengths)
                && MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape._memoryLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape._memoryLength));
        }
        #endregion
 
        #region SetSlice
        /// <summary>
        /// Sets a slice of the given <paramref name="tensor"/> with the provided <paramref name="values"/> for the given <paramref name="ranges"/>
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="values">The values you want to set in the <paramref name="tensor"/>.</param>
        /// <param name="ranges">The ranges you want to set.</param>
        public static Tensor<T> SetSlice<T>(this Tensor<T> tensor, in ReadOnlyTensorSpan<T> values, params ReadOnlySpan<NRange> ranges)
        {
            SetSlice((TensorSpan<T>)tensor, values, ranges);
 
            return tensor;
        }
 
        /// <summary>
        /// Sets a slice of the given <paramref name="tensor"/> with the provided <paramref name="values"/> for the given <paramref name="ranges"/>
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="values">The values you want to set in the <paramref name="tensor"/>.</param>
        /// <param name="ranges">The ranges you want to set.</param>
        public static ref readonly TensorSpan<T> SetSlice<T>(this in TensorSpan<T> tensor, scoped in ReadOnlyTensorSpan<T> values, params scoped ReadOnlySpan<NRange> ranges)
        {
            TensorSpan<T> srcSpan;
            if (ranges == ReadOnlySpan<NRange>.Empty)
            {
                if (!TensorHelpers.IsBroadcastableTo(values.Lengths, tensor.Lengths))
                    ThrowHelper.ThrowArgument_SetSliceNoRange(nameof(values));
                srcSpan = tensor;
            }
            else
                srcSpan = tensor.Slice(ranges);
 
            if (!TensorHelpers.IsContiguousAndDense<T>(srcSpan))
                ThrowHelper.ThrowArgument_SetSliceInvalidShapes(nameof(values));
 
            if (!TensorHelpers.IsBroadcastableTo(values.Lengths, srcSpan.Lengths))
                ThrowHelper.ThrowArgument_SetSliceInvalidShapes(nameof(values));
 
            values.CopyTo(srcSpan);
 
            return ref tensor;
        }
        #endregion
 
        #region Split
        /// <summary>
        /// Split a <see cref="Tensor{T}"/> into <paramref name="splitCount"/> along the given <paramref name="dimension"/>. If the tensor cannot be split
        /// evenly on the given <paramref name="dimension"/> an exception is thrown.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="splitCount">How many times to split the <paramref name="tensor"/></param>
        /// <param name="dimension">The axis to split on.</param>
        public static Tensor<T>[] Split<T>(scoped in ReadOnlyTensorSpan<T> tensor, int splitCount, nint dimension)
        {
            if (tensor.Lengths[(int)dimension] % splitCount != 0)
                ThrowHelper.ThrowArgument_SplitNotSplitEvenly();
 
            Tensor<T>[] outputs = new Tensor<T>[splitCount];
 
            nint totalToCopy = tensor.FlattenedLength / splitCount;
            nint copyLength = 1;
            for (nint i = dimension; i < tensor.Lengths.Length; i++)
            {
                copyLength *= tensor.Lengths[(int)i];
            }
            copyLength /= splitCount;
            nint[] newShape = tensor.Lengths.ToArray();
            newShape[(int)dimension] = newShape[(int)dimension] / splitCount;
 
            scoped Span<nint> oIndices;
            nint[]? oIndicesArray;
            scoped Span<nint> iIndices;
            nint[]? iIndicesArray;
            if (tensor.Rank > 6)
            {
                oIndicesArray = ArrayPool<nint>.Shared.Rent(tensor.Rank);
                oIndices = oIndicesArray.AsSpan(0, tensor.Rank);
                oIndices.Clear();
 
                iIndicesArray = ArrayPool<nint>.Shared.Rent(tensor.Rank);
                iIndices = iIndicesArray.AsSpan(0, tensor.Rank);
                iIndices.Clear();
            }
            else
            {
                oIndicesArray = null;
                oIndices = stackalloc nint[tensor.Rank];
                iIndicesArray = null;
                iIndices = stackalloc nint[tensor.Rank];
            }
 
            for (int i = 0; i < outputs.Length; i++)
            {
                T[] values = new T[(int)totalToCopy];
                outputs[i] = new Tensor<T>(values, newShape);
                oIndices.Clear();
                iIndices.Clear();
 
                iIndices[(int)dimension] = i;
                ReadOnlyTensorSpan<T> islice = tensor.Slice(tensor.Lengths);
                TensorSpan<T> oslice = outputs[i].AsTensorSpan().Slice(outputs[i]._lengths);
 
                nint copiedValues = 0;
                while (copiedValues < totalToCopy)
                {
                    TensorSpanHelpers.Memmove(ref Unsafe.Add(ref oslice._reference, TensorSpanHelpers.ComputeLinearIndex(oIndices, outputs[0].Strides, outputs[0].Lengths)), ref Unsafe.Add(ref islice._reference, TensorSpanHelpers.ComputeLinearIndex(iIndices, islice.Strides, islice.Lengths)), copyLength);
                    TensorSpanHelpers.AdjustIndexes((int)dimension, 1, oIndices, outputs[i]._lengths);
                    TensorSpanHelpers.AdjustIndexes((int)dimension - 1, 1, iIndices, tensor.Lengths);
                    copiedValues += copyLength;
                }
            }
 
            if (oIndicesArray != null && iIndicesArray != null)
            {
                ArrayPool<nint>.Shared.Return(oIndicesArray);
                ArrayPool<nint>.Shared.Return(iIndicesArray);
            }
 
            return outputs;
        }
        #endregion
 
        #region Squeeze
        /// <summary>
        /// Removes all dimensions of length one from the <paramref name="tensor"/>.
        /// </summary>
        /// <param name="tensor">The <see cref="Tensor{T}"/> to remove all dimensions of length 1.</param>
        public static Tensor<T> Squeeze<T>(this Tensor<T> tensor)
        {
            return SqueezeDimension(tensor, -1);
        }
 
        /// <summary>
        /// Removes axis of length one from the <paramref name="tensor"/> for the given <paramref name="dimension"/>.
        /// If the dimension is not of length one it will throw an exception.
        /// </summary>
        /// <param name="tensor">The <see cref="Tensor{T}"/> to remove dimension of length 1.</param>
        /// <param name="dimension">The dimension to remove.</param>
        public static Tensor<T> SqueezeDimension<T>(this Tensor<T> tensor, int dimension)
        {
            if (dimension >= tensor.Rank)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            nint[] lengths;
            nint[] strides;
 
            List<nint> tempLengths = new List<nint>();
            if (dimension == -1)
            {
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (tensor.Lengths[i] != 1)
                    {
                        tempLengths.Add(tensor.Lengths[i]);
                    }
                }
                lengths = tempLengths.ToArray();
                strides = TensorSpanHelpers.CalculateStrides(lengths);
            }
            else
            {
                if (tensor.Lengths[dimension] != 1)
                {
                    ThrowHelper.ThrowArgument_InvalidSqueezeAxis();
                }
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (i != dimension)
                    {
                        tempLengths.Add(tensor.Lengths[i]);
                    }
                }
                lengths = tempLengths.ToArray();
                strides = TensorSpanHelpers.CalculateStrides(lengths);
            }
 
            return new Tensor<T>(tensor._values, lengths, strides);
        }
 
        /// <summary>
        /// Removes all dimensions of length one from the <paramref name="tensor"/>.
        /// </summary>
        /// <param name="tensor">The <see cref="TensorSpan{T}"/> to remove all dimensions of length 1.</param>
        public static TensorSpan<T> Squeeze<T>(in this TensorSpan<T> tensor)
        {
            return SqueezeDimension(tensor, -1);
        }
 
        /// <summary>
        /// Removes axis of length one from the <paramref name="tensor"/> for the given <paramref name="dimension"/>.
        /// If the dimension is not of length one it will throw an exception.
        /// </summary>
        /// <param name="tensor">The <see cref="TensorSpan{T}"/> to remove dimension of length 1.</param>
        /// <param name="dimension">The dimension to remove.</param>
        public static TensorSpan<T> SqueezeDimension<T>(in this TensorSpan<T> tensor, int dimension)
        {
            if (dimension >= tensor.Rank)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            nint[] lengths;
            nint[] strides;
 
            List<nint> tempLengths = new List<nint>();
            if (dimension == -1)
            {
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (tensor.Lengths[i] != 1)
                    {
                        tempLengths.Add(tensor.Lengths[i]);
                    }
                }
                lengths = tempLengths.ToArray();
                strides = TensorSpanHelpers.CalculateStrides(lengths);
            }
            else
            {
                if (tensor.Lengths[dimension] != 1)
                {
                    ThrowHelper.ThrowArgument_InvalidSqueezeAxis();
                }
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (i != dimension)
                    {
                        tempLengths.Add(tensor.Lengths[i]);
                    }
                }
                lengths = tempLengths.ToArray();
                strides = TensorSpanHelpers.CalculateStrides(lengths);
            }
 
            return new TensorSpan<T>(ref tensor._reference, lengths, strides, tensor._shape._memoryLength);
        }
 
        /// <summary>
        /// Removes all dimensions of length one from the <paramref name="tensor"/>.
        /// </summary>
        /// <param name="tensor">The <see cref="ReadOnlyTensorSpan{T}"/> to remove all dimensions of length 1.</param>
        public static ReadOnlyTensorSpan<T> Squeeze<T>(in this ReadOnlyTensorSpan<T> tensor)
        {
            return SqueezeDimension(tensor, -1);
        }
 
        /// <summary>
        /// Removes axis of length one from the <paramref name="tensor"/> for the given <paramref name="dimension"/>.
        /// If the dimension is not of length one it will throw an exception.
        /// </summary>
        /// <param name="tensor">The <see cref="ReadOnlyTensorSpan{T}"/> to remove dimension of length 1.</param>
        /// <param name="dimension">The dimension to remove.</param>
        public static ReadOnlyTensorSpan<T> SqueezeDimension<T>(in this ReadOnlyTensorSpan<T> tensor, int dimension)
        {
            if (dimension >= tensor.Rank)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            nint[] lengths;
            nint[] strides;
 
            List<nint> tempLengths = new List<nint>();
            if (dimension == -1)
            {
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (tensor.Lengths[i] != 1)
                    {
                        tempLengths.Add(tensor.Lengths[i]);
                    }
                }
                lengths = tempLengths.ToArray();
                strides = TensorSpanHelpers.CalculateStrides(lengths);
            }
            else
            {
                if (tensor.Lengths[dimension] != 1)
                {
                    ThrowHelper.ThrowArgument_InvalidSqueezeAxis();
                }
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (i != dimension)
                    {
                        tempLengths.Add(tensor.Lengths[i]);
                    }
                }
                lengths = tempLengths.ToArray();
                strides = TensorSpanHelpers.CalculateStrides(lengths);
            }
 
            return new ReadOnlyTensorSpan<T>(ref tensor._reference, lengths, strides, tensor._shape._memoryLength);
        }
        #endregion
 
        #region Stack
        /// <summary>
        /// Join multiple <see cref="Tensor{T}"/> along a new dimension that is added at position 0. All tensors must have the same shape.
        /// </summary>
        /// <param name="tensors">Input <see cref="Tensor{T}"/>.</param>
        public static Tensor<T> Stack<T>(params ReadOnlySpan<Tensor<T>> tensors)
        {
            return StackAlongDimension(0, tensors);
        }
 
        /// <summary>
        /// Join multiple <see cref="Tensor{T}"/> along a new dimension. The axis parameter specifies the index of the new dimension. All tensors must have the same shape.
        /// </summary>
        /// <param name="tensors">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="dimension">Index of where the new dimension will be.</param>
        public static Tensor<T> StackAlongDimension<T>(int dimension, params ReadOnlySpan<Tensor<T>> tensors)
        {
            if (tensors.Length < 2)
                ThrowHelper.ThrowArgument_StackTooFewTensors();
 
            for (int i = 1; i < tensors.Length; i++)
            {
                if (!TensorHelpers.AreLengthsTheSame<T>(tensors[0], tensors[i]))
                    ThrowHelper.ThrowArgument_StackShapesNotSame();
            }
 
            if (dimension < 0)
                dimension = tensors[0].Rank - dimension;
 
            Tensor<T>[] outputs = new Tensor<T>[tensors.Length];
            for (int i = 0; i < tensors.Length; i++)
            {
                outputs[i] = Tensor.Unsqueeze(tensors[i], dimension);
            }
            return Tensor.ConcatenateOnDimension<T>(dimension, outputs);
        }
 
        /// <summary>
        /// Join multiple <see cref="Tensor{T}"/> along a new dimension that is added at position 0. All tensors must have the same shape.
        /// </summary>
        /// <param name="tensors">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Stack<T>(scoped in ReadOnlySpan<Tensor<T>> tensors, in TensorSpan<T> destination)
        {
            return ref StackAlongDimension(tensors, destination, 0);
        }
 
        /// <summary>
        /// Join multiple <see cref="Tensor{T}"/> along a new dimension. The axis parameter specifies the index of the new dimension. All tensors must have the same shape.
        /// </summary>
        /// <param name="tensors">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="destination"></param>
        /// <param name="dimension">Index of where the new dimension will be.</param>
        public static ref readonly TensorSpan<T> StackAlongDimension<T>(scoped ReadOnlySpan<Tensor<T>> tensors, in TensorSpan<T> destination, int dimension)
        {
            if (tensors.Length < 2)
                ThrowHelper.ThrowArgument_StackTooFewTensors();
 
            for (int i = 1; i < tensors.Length; i++)
            {
                if (!TensorHelpers.AreLengthsTheSame<T>(tensors[0], tensors[i]))
                    ThrowHelper.ThrowArgument_StackShapesNotSame();
            }
 
            if (dimension < 0)
                dimension = tensors[0].Rank - dimension;
 
            Tensor<T>[] outputs = new Tensor<T>[tensors.Length];
            for (int i = 0; i < tensors.Length; i++)
            {
                outputs[i] = Tensor.Unsqueeze(tensors[i], dimension);
            }
            return ref Tensor.ConcatenateOnDimension<T>(dimension, tensors, destination);
        }
        #endregion
 
        #region StdDev
        /// <summary>
        /// Returns the standard deviation of the elements in the <paramref name="x"/> tensor.
        /// </summary>
        /// <param name="x">The <see cref="TensorSpan{T}"/> to take the standard deviation of.</param>
        /// <returns><typeparamref name="T"/> representing the standard deviation.</returns>
        public static T StdDev<T>(in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPoint<T>, IPowerFunctions<T>, IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>
        {
            T mean = Average(x);
            Span<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> output = new T[x.FlattenedLength];
            TensorPrimitives.Subtract(span, mean, output);
            TensorPrimitives.Abs(output, output);
            TensorPrimitives.Pow((ReadOnlySpan<T>)output, T.CreateChecked(2), output);
            T sum = TensorPrimitives.Sum((ReadOnlySpan<T>)output);
            T variance = sum / T.CreateChecked(x._shape._memoryLength);
 
            if (typeof(T) == typeof(float))
            {
                return T.CreateChecked(MathF.Sqrt(float.CreateChecked(variance)));
            }
            if (typeof(T) == typeof(double))
            {
                return T.CreateChecked(Math.Sqrt(double.CreateChecked(variance)));
            }
            return T.Pow(variance, T.CreateChecked(0.5));
        }
        #endregion
 
        #region ToString
        /// <summary>
        /// Creates a <see cref="string"/> representation of the <see cref="TensorSpan{T}"/>."/>
        /// </summary>
        /// <param name="tensor">The <see cref="TensorSpan{T}"/> you want to represent as a string.</param>
        /// <param name="maximumLengths">Maximum Length of each dimension</param>
        /// <returns>A <see cref="string"/> representation of the <paramref name="tensor"/></returns>
        public static string ToString<T>(this in TensorSpan<T> tensor, params ReadOnlySpan<nint> maximumLengths) =>
            ((ReadOnlyTensorSpan<T>)tensor).ToString(maximumLengths);
 
        /// <summary>
        /// Creates a <see cref="string"/> representation of the <see cref="ReadOnlyTensorSpan{T}"/>."/>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tensor">The <see cref="ReadOnlyTensorSpan{T}"/> you want to represent as a string.</param>
        /// <param name="maximumLengths">Maximum Length of each dimension</param>
        public static string ToString<T>(this in ReadOnlyTensorSpan<T> tensor, params ReadOnlySpan<nint> maximumLengths)
        {
            StringBuilder sb = new();
            ToString(in tensor, sb, maximumLengths);
            return sb.ToString();
        }
 
        internal static void ToString<T>(this in ReadOnlyTensorSpan<T> tensor, StringBuilder sb, params ReadOnlySpan<nint> maximumLengths)
        {
            if (maximumLengths.Length != tensor.Rank)
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(tensor));
 
            scoped Span<nint> curIndexes;
            nint[]? curIndexesArray;
            if (tensor.Rank > 6)
            {
                curIndexesArray = ArrayPool<nint>.Shared.Rent(tensor.Rank);
                curIndexes = curIndexesArray.AsSpan(0, tensor.Rank);
                curIndexes.Clear();
            }
            else
            {
                curIndexesArray = null;
                curIndexes = stackalloc nint[tensor.Rank];
            }
 
            nint copiedValues = 0;
 
            T[] values = new T[tensor.Lengths[tensor.Rank - 1]];
            while (copiedValues < tensor.FlattenedLength)
            {
                var sp = new ReadOnlyTensorSpan<T>(ref Unsafe.Add(ref tensor._reference, TensorSpanHelpers.ComputeLinearIndex(curIndexes, tensor.Strides, tensor.Lengths)), [tensor.Lengths[tensor.Rank - 1]], [1], tensor.Lengths[tensor.Rank - 1]);
                sb.Append('{');
                sp.FlattenTo(values);
                sb.Append(string.Join(",", values));
                sb.AppendLine("}");
 
                TensorSpanHelpers.AdjustIndexes(tensor.Rank - 2, 1, curIndexes, tensor.Lengths);
                copiedValues += tensor.Lengths[tensor.Rank - 1];
            }
 
            if (curIndexesArray != null)
                ArrayPool<nint>.Shared.Return(curIndexesArray);
        }
 
        /// <summary>
        /// Creates a <see cref="string"/> representation of the <see cref="Tensor{T}"/>."/>
        /// </summary>
        /// <param name="tensor">The <see cref="Span{T}"/> you want to represent as a string.</param>
        /// <param name="maximumLengths">Maximum Length of each dimension</param>
        /// <returns>A <see cref="string"/> representation of the <paramref name="tensor"/></returns>
        public static string ToString<T>(this Tensor<T> tensor, params ReadOnlySpan<nint> maximumLengths) => ((ReadOnlyTensorSpan<T>)tensor).ToString(maximumLengths);
 
        #endregion
 
        #region Transpose
        /// <summary>
        /// Swaps the last two dimensions of the <paramref name="tensor"/> tensor.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        public static Tensor<T> Transpose<T>(Tensor<T> tensor)
        {
            if (tensor.Lengths.Length < 2)
                ThrowHelper.ThrowArgument_TransposeTooFewDimensions();
 
            Span<int> dimension = tensor.Rank <= TensorShape.MaxInlineRank ? stackalloc int[tensor.Rank] : new int[tensor.Rank];
            TensorSpanHelpers.FillRange(dimension);
 
            int temp = dimension[tensor.Rank - 1];
            dimension[tensor.Rank - 1] = dimension[tensor.Rank - 2];
            dimension[tensor.Rank - 2] = temp;
 
            return PermuteDimensions(tensor, dimension);
        }
        #endregion
 
        #region TryBroadcastTo
        /// <summary>
        /// Broadcast the data from <paramref name="tensor"/> to the smallest broadcastable shape compatible with <paramref name="destination"/> and stores it in <paramref name="destination"/>
        /// If the shapes are not compatible, false is returned.
        /// </summary>
        /// <param name="tensor">Input <see cref="Tensor{T}"/>.</param>
        /// <param name="destination">Destination <see cref="TensorSpan{T}"/>.</param>
        public static bool TryBroadcastTo<T>(this Tensor<T> tensor, in TensorSpan<T> destination)
        {
            return TryBroadcastTo((ReadOnlyTensorSpan<T>)tensor, destination);
        }
 
        /// <summary>
        /// Broadcast the data from <paramref name="tensor"/> to the smallest broadcastable shape compatible with <paramref name="destination"/> and stores it in <paramref name="destination"/>
        /// If the shapes are not compatible, false is returned.
        /// </summary>
        /// <param name="tensor">Input <see cref="TensorSpan{T}"/>.</param>
        /// <param name="destination">Destination <see cref="TensorSpan{T}"/>.</param>
        public static bool TryBroadcastTo<T>(in this TensorSpan<T> tensor, in TensorSpan<T> destination)
        {
            return TryBroadcastTo((ReadOnlyTensorSpan<T>)tensor, destination);
        }
 
        /// <summary>
        /// Broadcast the data from <paramref name="tensor"/> to the smallest broadcastable shape compatible with <paramref name="destination"/> and stores it in <paramref name="destination"/>
        /// If the shapes are not compatible, false is returned.
        /// </summary>
        /// <param name="tensor">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination">Destination <see cref="TensorSpan{T}"/>.</param>
        public static bool TryBroadcastTo<T>(in this ReadOnlyTensorSpan<T> tensor, in TensorSpan<T> destination)
        {
            if (!TensorHelpers.IsBroadcastableTo(tensor.Lengths, destination.Lengths))
                return false;
 
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(tensor.Lengths, destination.Lengths);
            if (!TensorHelpers.AreLengthsTheSame(destination.Lengths, newSize))
                return false;
 
            LazyBroadcast(tensor, newSize).CopyTo(destination);
            return true;
        }
        #endregion
 
        #region Unsqueeze
        /// <summary>
        /// Insert a new dimension of length 1 that will appear at the dimension position.
        /// </summary>
        /// <param name="tensor">The <see cref="Tensor{T}"/> to add a dimension of length 1.</param>
        /// <param name="dimension">The index of the dimension to add.</param>
        public static Tensor<T> Unsqueeze<T>(this Tensor<T> tensor, int dimension)
        {
            if (dimension > tensor.Lengths.Length)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
            if (dimension < 0)
                dimension = tensor.Rank - dimension;
 
            Span<nint> lengths = tensor._lengths.Length + 1 <= TensorShape.MaxInlineRank ?
                stackalloc nint[tensor._lengths.Length + 1] :
                new nint[tensor._lengths.Length + 1];
            tensor._lengths.AsSpan(0, dimension).CopyTo(lengths);
            tensor._lengths.AsSpan(dimension).CopyTo(lengths.Slice(dimension + 1));
            lengths[dimension] = 1;
 
            Span<nint> strides = tensor.Strides.Length + 1 <= TensorShape.MaxInlineRank ?
                stackalloc nint[tensor.Strides.Length + 1] :
                new nint[tensor.Strides.Length + 1];
            if (dimension == tensor.Rank)
            {
                tensor.Strides.CopyTo(strides);
                strides[dimension] = tensor.Strides[dimension - 1];
            }
            else
            {
                tensor.Strides.Slice(0, dimension).CopyTo(strides);
                tensor.Strides.Slice(dimension).CopyTo(strides.Slice(dimension + 1));
                strides[dimension] = tensor.Strides[dimension] * tensor.Lengths[dimension];
            }
 
            return new Tensor<T>(tensor._values, lengths, strides);
        }
 
        /// <summary>
        /// Insert a new dimension of length 1 that will appear at the dimension position.
        /// </summary>
        /// <param name="tensor">The <see cref="TensorSpan{T}"/> to add a dimension of length 1.</param>
        /// <param name="dimension">The index of the dimension to add.</param>
        public static TensorSpan<T> Unsqueeze<T>(in this TensorSpan<T> tensor, int dimension)
        {
            if (dimension > tensor.Lengths.Length)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
            if (dimension < 0)
                dimension = tensor.Rank - dimension;
 
            Span<nint> lengths = tensor.Lengths.Length + 1 <= TensorShape.MaxInlineRank ?
                stackalloc nint[tensor.Lengths.Length + 1] :
                new nint[tensor.Lengths.Length + 1];
            tensor.Lengths.Slice(0, dimension).CopyTo(lengths);
            tensor.Lengths.Slice(dimension).CopyTo(lengths.Slice(dimension + 1));
            lengths[dimension] = 1;
 
            Span<nint> strides = tensor.Strides.Length + 1 <= TensorShape.MaxInlineRank ?
                stackalloc nint[tensor.Strides.Length + 1] :
                new nint[tensor.Strides.Length + 1];
            if (dimension == tensor.Rank)
            {
                tensor.Strides.CopyTo(strides);
                strides[dimension] = tensor.Strides[dimension - 1];
            }
            else
            {
                tensor.Strides.Slice(0, dimension).CopyTo(strides);
                tensor.Strides.Slice(dimension).CopyTo(strides.Slice(dimension + 1));
                strides[dimension] = tensor.Strides[dimension] * tensor.Lengths[dimension];
            }
 
            return new TensorSpan<T>(ref tensor._reference, lengths, strides, tensor._shape._memoryLength);
        }
 
        /// <summary>
        /// Insert a new dimension of length 1 that will appear at the dimension position.
        /// </summary>
        /// <param name="tensor">The <see cref="ReadOnlyTensorSpan{T}"/> to add a dimension of length 1.</param>
        /// <param name="dimension">The index of the dimension to add.</param>
        public static ReadOnlyTensorSpan<T> Unsqueeze<T>(in this ReadOnlyTensorSpan<T> tensor, int dimension)
        {
            if (dimension > tensor.Lengths.Length)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
            if (dimension < 0)
                dimension = tensor.Rank - dimension;
 
            Span<nint> lengths = tensor.Lengths.Length + 1 <= TensorShape.MaxInlineRank ?
                stackalloc nint[tensor.Lengths.Length + 1] :
                new nint[tensor.Lengths.Length + 1];
            tensor.Lengths.Slice(0, dimension).CopyTo(lengths);
            tensor.Lengths.Slice(dimension).CopyTo(lengths.Slice(dimension + 1));
            lengths[dimension] = 1;
 
            Span<nint> strides = tensor.Strides.Length + 1 <= TensorShape.MaxInlineRank ?
                stackalloc nint[tensor.Strides.Length + 1] :
                new nint[tensor.Strides.Length + 1];
            if (dimension == tensor.Rank)
            {
                tensor.Strides.CopyTo(strides);
                strides[dimension] = tensor.Strides[dimension - 1];
            }
            else
            {
                tensor.Strides.Slice(0, dimension).CopyTo(strides);
                tensor.Strides.Slice(dimension).CopyTo(strides.Slice(dimension + 1));
                strides[dimension] = tensor.Strides[dimension] * tensor.Lengths[dimension];
            }
 
            return new ReadOnlyTensorSpan<T>(ref tensor._reference, lengths, strides, tensor._shape._memoryLength);
        }
        #endregion
 
        #region TensorPrimitives
        #region Abs
        /// <summary>
        /// Takes the absolute value of each element of the <see cref="Tensor{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the abs of.</param>
        public static Tensor<T> Abs<T>(in ReadOnlyTensorSpan<T> x)
            where T : INumberBase<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Abs(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the absolute value of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="TensorSpan{T}"/> to take the abs of.</param>
        /// <param name="destination">The <see cref="TensorSpan{T}"/> destination.</param>
        public static ref readonly TensorSpan<T> Abs<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : INumberBase<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Abs);
        }
        #endregion
 
        #region Acos
        /// <summary>
        /// Takes the inverse cosine of each element of the <see cref="Tensor{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Acos<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Acos(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse cosine of each element of the <see cref="Tensor{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="TensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Acos<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Acos);
        }
        #endregion
 
        #region Acosh
        /// <summary>
        /// Takes the inverse hyperbolic cosine of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Acosh<T>(in ReadOnlyTensorSpan<T> x)
            where T : IHyperbolicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Acosh(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse hyperbolic cosine of each element of the <see cref="TensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="TensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Acosh<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IHyperbolicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Acosh);
        }
        #endregion
 
        #region AcosPi
        /// <summary>
        /// Takes the inverse hyperbolic cosine divided by pi of each element of the <see cref="Tensor{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> AcosPi<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            AcosPi(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse hyperbolic cosine divided by pi of each element of the <see cref="TensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> AcosPi<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.AcosPi);
        }
        #endregion
 
        #region Add
        /// <summary>
        /// Adds each element of <paramref name="x"/> to each element of <paramref name="y"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> of values to add.</param>
        /// <param name="y">The second <see cref="ReadOnlyTensorSpan{T}"/> of values to add.</param>
        public static Tensor<T> Add<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Add(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Adds <paramref name="y"/> to each element of <paramref name="x"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> of values to add.</param>
        /// <param name="y">The <typeparamref name="T"/> to add to each element of <paramref name="x"/>.</param>
        public static Tensor<T> Add<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Add(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Adds each element of <paramref name="x"/> to each element of <paramref name="y"/> and returns a new <see cref="ReadOnlyTensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> of values to add.</param>
        /// <param name="y">The second <see cref="ReadOnlyTensorSpan{T}"/> of values to add.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Add<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Add);
        }
 
        /// <summary>
        /// Adds <paramref name="y"/> to each element of <paramref name="x"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> of values to add.</param>
        /// <param name="y">The <typeparamref name="T"/> to add to each element of <paramref name="x"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Add<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Add);
        }
        #endregion
 
        #region Asin
        /// <summary>
        /// Takes the inverse sin of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Asin<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Asin(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse sin of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Asin<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Asin);
        }
        #endregion
 
        #region Asinh
        /// <summary>
        /// Takes the inverse hyperbolic sine of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Asinh<T>(in ReadOnlyTensorSpan<T> x)
            where T : IHyperbolicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Asinh(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse hyperbolic sine of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Asinh<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IHyperbolicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Asinh);
        }
        #endregion
 
        #region AsinPi
        /// <summary>
        /// Takes the inverse hyperbolic sine divided by pi of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> AsinPi<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            AsinPi(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse hyperbolic sine divided by pi of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> AsinPi<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.AsinPi);
        }
        #endregion
 
        #region Atan
        /// <summary>
        /// Takes the arc tangent of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/></param>
        public static Tensor<T> Atan<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Atan(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the arc tangent of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atan<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Atan);
        }
        #endregion
 
        #region Atan2
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Atan2<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Atan2(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atan2<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Atan2);
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Atan2<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
 
            Atan2(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atan2<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Atan2);
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Atan2<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output = Tensor.Create<T>(y.Lengths);
 
            Atan2(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atan2<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperTInSpanInSpanOut(x, y, destination, TensorPrimitives.Atan2);
        }
        #endregion
 
        #region Atan2Pi
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/>, divides each element by pi, and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Atan2Pi<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Atan2Pi(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/>, divides each element by pi, and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atan2Pi<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Atan2Pi);
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/>, divides each element by pi, and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Atan2Pi<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
 
            Atan2Pi(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/>, divides each element by pi, and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atan2Pi<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Atan2Pi);
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/>, divides each element by pi, and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Atan2Pi<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output = Tensor.Create<T>(y.Lengths);
 
            Atan2Pi(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Takes the arc tangent of the two input <see cref="ReadOnlyTensorSpan{T}"/>, divides each element by pi, and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atan2Pi<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperTInSpanInSpanOut(x, y, destination, TensorPrimitives.Atan2Pi);
 
        }
        #endregion
 
        #region Atanh
        /// <summary>
        /// Takes the inverse hyperbolic tangent of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Atanh<T>(in ReadOnlyTensorSpan<T> x)
            where T : IHyperbolicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Atanh(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse hyperbolic tangent of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Atanh<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IHyperbolicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Atanh);
        }
        #endregion
 
        #region AtanPi
        /// <summary>
        /// Takes the inverse hyperbolic tangent divided by pi of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The input<see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> AtanPi<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            AtanPi(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the inverse hyperbolic tangent divided by pi of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The input<see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> AtanPi<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.AtanPi);
        }
        #endregion
 
        #region BitwiseAnd
        /// <summary>
        /// Computes the element-wise bitwise and of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> BitwiseAnd<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IBitwiseOperators<T, T, T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            BitwiseAnd(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise bitwise and of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> BitwiseAnd<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IBitwiseOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.BitwiseAnd);
        }
 
        /// <summary>
        /// Computes the element-wise bitwise and of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second value.</param>
        public static Tensor<T> BitwiseAnd<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IBitwiseOperators<T, T, T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
 
            BitwiseAnd(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise bitwise and of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second value.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> BitwiseAnd<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IBitwiseOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.BitwiseAnd);
        }
        #endregion
 
        #region BitwiseOr
        /// <summary>
        /// Computes the element-wise bitwise of of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> BitwiseOr<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IBitwiseOperators<T, T, T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            BitwiseOr(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise bitwise of of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> BitwiseOr<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IBitwiseOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.BitwiseOr);
        }
 
        /// <summary>
        /// Computes the element-wise bitwise or of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second value.</param>
        public static Tensor<T> BitwiseOr<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IBitwiseOperators<T, T, T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
 
            BitwiseOr(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise bitwise or of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second value.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> BitwiseOr<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IBitwiseOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.BitwiseOr);
        }
        #endregion
 
        #region CubeRoot
        /// <summary>
        /// Computes the element-wise cube root of the input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Cbrt<T>(in ReadOnlyTensorSpan<T> x)
            where T : IRootFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Cbrt(x, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise cube root of the input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Cbrt<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IRootFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Cbrt);
        }
        #endregion
 
        #region Ceiling
        /// <summary>
        /// Computes the element-wise ceiling of the input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Ceiling<T>(in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Ceiling(x, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise ceiling of the input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Ceiling<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Ceiling);
        }
        #endregion
 
        #region ConvertChecked
        /// <summary>
        /// Copies <paramref name="source"/> to a new <see cref="ReadOnlyTensorSpan{TTO}"/> converting each <typeparamref name="TFrom"/>
        /// value to a <typeparamref name="TTo"/> value.
        /// </summary>
        /// <param name="source">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<TTo> ConvertChecked<TFrom, TTo>(in ReadOnlyTensorSpan<TFrom> source)
            where TFrom : IEquatable<TFrom>, IEqualityOperators<TFrom, TFrom, bool>, INumberBase<TFrom>
            where TTo : INumberBase<TTo>
        {
            Tensor<TTo> output = Tensor.Create<TTo>(source.Lengths);
 
            ConvertChecked<TFrom, TTo>(source, output);
            return output;
        }
 
        /// <summary>
        /// Copies <paramref name="source"/> to a new <see cref="TensorSpan{TTo}"/> converting each <typeparamref name="TFrom"/>
        /// value to a <typeparamref name="TTo"/> value.
        /// </summary>
        /// <param name="source">The input <see cref="TensorSpan{TFrom}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<TTo> ConvertChecked<TFrom, TTo>(scoped in ReadOnlyTensorSpan<TFrom> source, in TensorSpan<TTo> destination)
            where TFrom : IEquatable<TFrom>, IEqualityOperators<TFrom, TFrom, bool>, INumberBase<TFrom>
            where TTo : INumberBase<TTo>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(source, destination, TensorPrimitives.ConvertChecked);
        }
        #endregion
 
        #region ConvertSaturating
        /// <summary>
        /// Copies <paramref name="source"/> to a new <see cref="ReadOnlyTensorSpan{TTO}"/> converting each <typeparamref name="TFrom"/>
        /// value to a <typeparamref name="TTo"/> value.
        /// </summary>
        /// <param name="source">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<TTo> ConvertSaturating<TFrom, TTo>(in ReadOnlyTensorSpan<TFrom> source)
            where TFrom : IEquatable<TFrom>, IEqualityOperators<TFrom, TFrom, bool>, INumberBase<TFrom>
            where TTo : INumberBase<TTo>
        {
            Tensor<TTo> output = Tensor.Create<TTo>(source.Lengths);
 
            ConvertSaturating<TFrom, TTo>(source, output);
            return output;
        }
 
        /// <summary>
        /// Copies <paramref name="source"/> to a new <see cref="TensorSpan{TTo}"/> converting each <typeparamref name="TFrom"/>
        /// value to a <typeparamref name="TTo"/> value.
        /// </summary>
        /// <param name="source">The input <see cref="TensorSpan{TFrom}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<TTo> ConvertSaturating<TFrom, TTo>(scoped in ReadOnlyTensorSpan<TFrom> source, in TensorSpan<TTo> destination)
            where TFrom : IEquatable<TFrom>, IEqualityOperators<TFrom, TFrom, bool>, INumberBase<TFrom>
            where TTo : INumberBase<TTo>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(source, destination, TensorPrimitives.ConvertSaturating);
        }
        #endregion
 
        #region ConvertTruncating
        /// <summary>
        /// Copies <paramref name="source"/> to a new <see cref="ReadOnlyTensorSpan{TTO}"/> converting each <typeparamref name="TFrom"/>
        /// value to a <typeparamref name="TTo"/> value.
        /// </summary>
        /// <param name="source">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<TTo> ConvertTruncating<TFrom, TTo>(in ReadOnlyTensorSpan<TFrom> source)
            where TFrom : IEquatable<TFrom>, IEqualityOperators<TFrom, TFrom, bool>, INumberBase<TFrom>
            where TTo : INumberBase<TTo>
        {
            Tensor<TTo> output = Tensor.Create<TTo>(source.Lengths);
 
            ConvertTruncating<TFrom, TTo>(source, output);
            return output;
        }
 
        /// <summary>
        /// Copies <paramref name="source"/> to a new <see cref="TensorSpan{TTo}"/> converting each <typeparamref name="TFrom"/>
        /// value to a <typeparamref name="TTo"/> value.
        /// </summary>
        /// <param name="source">The input <see cref="TensorSpan{TFrom}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<TTo> ConvertTruncating<TFrom, TTo>(scoped in ReadOnlyTensorSpan<TFrom> source, in TensorSpan<TTo> destination)
            where TFrom : IEquatable<TFrom>, IEqualityOperators<TFrom, TFrom, bool>, INumberBase<TFrom>
            where TTo : INumberBase<TTo>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(source, destination, TensorPrimitives.ConvertTruncating);
        }
        #endregion
 
        #region CopySign
        /// <summary>
        /// Computes the element-wise result of copying the sign from one number to another number in the specified tensors and returns a new tensor with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="sign">The number with the associated sign.</param>
        public static Tensor<T> CopySign<T>(in ReadOnlyTensorSpan<T> x, T sign)
            where T : INumber<T>
        {
            Tensor<T> output = Create<T>(x.Lengths);
 
            CopySign(x, sign, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise result of copying the sign from one number to another number in the specified tensors and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="sign">The <see cref="ReadOnlyTensorSpan{T}"/> with the associated signs.</param>
        public static Tensor<T> CopySign<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> sign)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(sign.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, sign.Lengths));
            }
 
            CopySign(x, sign, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise result of copying the sign from one number to another number in the specified tensors and returns a new tensor with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="sign">The number with the associated sign.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> CopySign<T>(scoped in ReadOnlyTensorSpan<T> x, T sign, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, sign, destination, TensorPrimitives.CopySign);
        }
 
        /// <summary>
        /// Computes the element-wise result of copying the sign from one number to another number in the specified tensors and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="sign">The <see cref="ReadOnlyTensorSpan{T}"/> with the associated signs.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> CopySign<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> sign, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, sign, destination, TensorPrimitives.CopySign);
        }
        #endregion
 
        #region Cos
        /// <summary>
        /// Takes the cosine of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the cosine of.</param>
        public static Tensor<T> Cos<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Cos(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the cosine of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the cosine of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Cos<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Cos);
        }
        #endregion
 
        #region Cosh
        /// <summary>
        /// Takes the hyperbolic cosine of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the cosine of.</param>
        public static Tensor<T> Cosh<T>(in ReadOnlyTensorSpan<T> x)
            where T : IHyperbolicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Cosh(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the hyperbolic cosine of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the cosine of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Cosh<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IHyperbolicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Cosh);
        }
        #endregion
 
        #region CosineSimilarity
        /// <summary>
        /// Compute cosine similarity between <paramref name="x"/> and <paramref name="y"/>.
        /// </summary>
        /// <param name="x">The first <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="y">The second <see cref="ReadOnlyTensorSpan{T}"/></param>
        public static Tensor<T> CosineSimilarity<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IRootFunctions<T>
        {
            if (x.Rank != 2)
                ThrowHelper.ThrowArgument_2DTensorRequired(nameof(x));
 
            if (y.Rank != 2)
                ThrowHelper.ThrowArgument_2DTensorRequired(nameof(y));
 
            if (x.Lengths[1] != y.Lengths[1])
                ThrowHelper.ThrowArgument_IncompatibleDimensions(x.Lengths[1], y.Lengths[1]);
 
            nint dim1 = x.Lengths[0];
            nint dim2 = y.Lengths[0];
 
            T[] values = new T[dim1 * dim2];
 
            Tensor<T> output = Tensor.Create<T>(values, [dim1, dim2]);
 
            CosineSimilarity(x, y, output);
 
            return output;
        }
 
        /// <summary>
        /// Compute cosine similarity between <paramref name="x"/> and <paramref name="y"/>.
        /// </summary>
        /// <param name="x">The first <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="y">The second <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> CosineSimilarity<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IRootFunctions<T>
        {
            if (x.Rank != 2)
                ThrowHelper.ThrowArgument_2DTensorRequired(nameof(x));
 
            if (y.Rank != 2)
                ThrowHelper.ThrowArgument_2DTensorRequired(nameof(y));
 
            if (x.Lengths[1] != y.Lengths[1])
                ThrowHelper.ThrowArgument_IncompatibleDimensions(x.Lengths[1], y.Lengths[1]);
 
            nint dim1 = x.Lengths[0];
            nint dim2 = y.Lengths[0];
 
            if (destination.Lengths[0] != dim1 || destination.Lengths[1] != dim2)
                ThrowHelper.ThrowArgument_IncompatibleDimensions(x.Lengths[1], y.Lengths[1]);
 
            Span<T> values = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
 
            scoped Span<nint> leftIndexes = stackalloc nint[2];
            scoped Span<nint> rightIndexes = stackalloc nint[2];
 
            int outputOffset = 0;
 
            ReadOnlySpan<T> lspan;
            ReadOnlySpan<T> rspan;
            int rowLength = (int)x.Lengths[1];
            for (int i = 0; i < dim1; i++)
            {
                for (int j = 0; j < dim2; j++)
                {
                    lspan = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref x._reference, TensorSpanHelpers.ComputeLinearIndex(leftIndexes, x.Strides, x.Lengths)), (int)rowLength);
                    rspan = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.Add(ref y._reference, TensorSpanHelpers.ComputeLinearIndex(rightIndexes, y.Strides, y.Lengths)), (int)rowLength);
                    values[outputOffset++] = TensorPrimitives.CosineSimilarity(lspan, rspan);
                    rightIndexes[0]++;
                }
                rightIndexes[0] = 0;
                leftIndexes[0]++;
            }
 
            return ref destination;
 
        }
        #endregion
 
        #region CosPi
        /// <summary>Computes the element-wise cosine of the value in the specified tensor that has been multiplied by Pi and returns a new <see cref="Tensor{T}"/> with the results.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <remarks>
        /// <para>
        /// This method effectively computes <c><typeparamref name="T"/>.CosPi(<paramref name="x" />[i])</c>.
        /// </para>
        /// <para>
        /// The angles in x must be in radians. Use <see cref="M:System.Single.DegreesToRadians(System.Single)"/> or multiply by <typeparamref name="T"/>.Pi/180 to convert degrees to radians.
        /// </para>
        /// <para>
        /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different
        /// operating systems or architectures.
        /// </para>
        /// </remarks>
        public static Tensor<T> CosPi<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            CosPi(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise cosine of the value in the specified tensor that has been multiplied by Pi and returns a new <see cref="TensorSpan{T}"/> with the results.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        /// <remarks>
        /// <para>
        /// This method effectively computes <c><typeparamref name="T"/>.CosPi(<paramref name="x" />[i])</c>.
        /// </para>
        /// <para>
        /// The angles in x must be in radians. Use <see cref="M:System.Single.DegreesToRadians(System.Single)"/> or multiply by <typeparamref name="T"/>.Pi/180 to convert degrees to radians.
        /// </para>
        /// <para>
        /// This method may call into the underlying C runtime or employ instructions specific to the current architecture. Exact results may differ between different
        /// operating systems or architectures.
        /// </para>
        /// </remarks>
        public static ref readonly TensorSpan<T> CosPi<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.CosPi);
        }
        #endregion
 
        #region DegreesToRadians
        /// <summary>
        /// Computes the element-wise conversion of each number of degrees in the specified tensor to radians and returns a new tensor with the results.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> DegreesToRadians<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            DegreesToRadians(x, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise conversion of each number of degrees in the specified tensor to radians and returns a new tensor with the results.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> DegreesToRadians<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.DegreesToRadians);
        }
        #endregion
 
        #region Distance
        /// <summary>
        /// Computes the distance between two points, specified as non-empty, equal-length tensors of numbers, in Euclidean space.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static T Distance<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y)
            where T : IRootFunctions<T>
        {
            return TensorPrimitivesHelperTwoSpanInTOut(x, y, TensorPrimitives.Distance);
        }
        #endregion
 
        #region Divide
        /// <summary>
        /// Divides each element of <paramref name="x"/> by <paramref name="y"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The divisor</param>
        public static Tensor<T> Divide<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IDivisionOperators<T, T, T>
        {
            Tensor<T> output = Create<T>(x.Lengths);
            Divide(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Divides <paramref name="x"/> by each element of <paramref name="y"/> and returns a new <see cref="Tensor{T}"/> with the result."/>
        /// </summary>
        /// <param name="x">The value to be divided.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/> divisor.</param>
        public static Tensor<T> Divide<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IDivisionOperators<T, T, T>
        {
            Tensor<T> output = Tensor.Create<T>(y.Lengths);
            Divide(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Divides each element of <paramref name="x"/> by its corresponding element in <paramref name="y"/> and returns
        /// a new <see cref="ReadOnlyTensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to be divided.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/> divisor.</param>
        public static Tensor<T> Divide<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IDivisionOperators<T, T, T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Divide(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Divides each element of <paramref name="x"/> by <paramref name="y"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The divisor</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Divide<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IDivisionOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Divide);
        }
 
        /// <summary>
        /// Divides <paramref name="x"/> by each element of <paramref name="y"/> and returns a new <see cref="TensorSpan{T}"/> with the result."/>
        /// </summary>
        /// <param name="x">The value to be divided.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/> divisor.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Divide<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IDivisionOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperTInSpanInSpanOut(x, y, destination, TensorPrimitives.Divide);
        }
 
        /// <summary>
        /// Divides each element of <paramref name="x"/> by its corresponding element in <paramref name="y"/> and returns
        /// a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to be divided.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/> divisor.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Divide<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IDivisionOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Divide);
        }
        #endregion
 
        #region Dot
        /// <summary>
        /// Computes the dot product of two tensors containing numbers.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static T Dot<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>, IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>
        {
            return TensorPrimitivesHelperTwoSpanInTOut(x, y, TensorPrimitives.Dot);
        }
        #endregion
 
        #region Exp
        /// <summary>
        /// Computes the element-wise result of raising <c>e</c> to the single-precision floating-point number powers in the specified tensor.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Exp<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Exp(x, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise result of raising <c>e</c> to the single-precision floating-point number powers in the specified tensor.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Exp<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Exp);
        }
        #endregion
 
        #region Exp10
        /// <summary>
        /// Computes the element-wise result of raising 10 to the number powers in the specified tensor.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Exp10<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Exp10(x, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise result of raising 10 to the number powers in the specified tensor.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Exp10<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Exp10);
        }
        #endregion
 
        #region Exp10M1
        /// <summary>Computes the element-wise result of raising 10 to the number powers in the specified tensor, minus one.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Exp10M1<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Exp10M1(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise result of raising 10 to the number powers in the specified tensor, minus one.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Exp10M1<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Exp10M1);
        }
        #endregion
 
        #region Exp2
        /// <summary>Computes the element-wise result of raising 2 to the number powers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Exp2<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Exp2(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise result of raising 2 to the number powers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Exp2<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Exp2);
        }
        #endregion
 
        #region Exp2M1
        /// <summary>Computes the element-wise result of raising 2 to the number powers in the specified tensor, minus one.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Exp2M1<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Exp2M1(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise result of raising 2 to the number powers in the specified tensor, minus one.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Exp2M1<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Exp2M1);
        }
        #endregion
 
        #region ExpM1
        /// <summary>Computes the element-wise result of raising <c>e</c> to the number powers in the specified tensor, minus 1.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> ExpM1<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            ExpM1(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise result of raising <c>e</c> to the number powers in the specified tensor, minus 1.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> ExpM1<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.ExpM1);
        }
        #endregion
 
        #region Floor
        /// <summary>Computes the element-wise floor of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Floor<T>(in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Floor(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise floor of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Floor<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Floor);
        }
        #endregion
 
        #region Hypotenuse
        /// <summary>
        /// Computes the element-wise hypotenuse given values from two tensors representing the lengths of the shorter sides in a right-angled triangle.
        /// If the shapes are not the same they are broadcast to the smallest compatible shape.
        /// </summary>
        /// <param name="x">Left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">Right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Hypot<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IRootFunctions<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Hypot(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise hypotenuse given values from two tensors representing the lengths of the shorter sides in a right-angled triangle.
        /// If the shapes are not the same they are broadcast to the smallest compatible shape.
        /// </summary>
        /// <param name="x">Left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">Right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Hypot<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IRootFunctions<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Hypot);
        }
        #endregion
 
        #region Ieee754Remainder
        /// <summary>Computes the element-wise remainder of the numbers in the specified tensors.</summary>
        /// If the shapes are not the same they are broadcast to the smallest compatible shape.
        /// <param name="x">Left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">Right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Ieee754Remainder<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Ieee754Remainder(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise remainder of the numbers in the specified tensors.</summary>
        /// If the shapes are not the same they are broadcast to the smallest compatible shape.
        /// <param name="x">Left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">Right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Ieee754Remainder<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Ieee754Remainder);
        }
 
        /// <summary>Computes the element-wise remainder of the numbers in the specified tensors.</summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Ieee754Remainder<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
 
            Ieee754Remainder(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise remainder of the numbers in the specified tensors.</summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Ieee754Remainder<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Ieee754Remainder);
        }
 
        /// <summary>Computes the element-wise remainder of the numbers in the specified tensors.</summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Ieee754Remainder<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<T> output = Tensor.Create<T>(y.Lengths);
 
            Ieee754Remainder(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise remainder of the numbers in the specified tensors.</summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Ieee754Remainder<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperTInSpanInSpanOut(x, y, destination, TensorPrimitives.Ieee754Remainder);
        }
        #endregion
 
        #region ILogB
        /// <summary>Computes the element-wise integer logarithm of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<int> ILogB<T>(in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPointIeee754<T>
        {
            Tensor<int> output = Tensor.Create<int>(x.Lengths, x.Strides);
            ILogB(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise integer logarithm of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<int> ILogB<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<int> destination)
            where T : IFloatingPointIeee754<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.ILogB);
        }
        #endregion
 
        #region IndexOfMax
        /// <summary>Searches for the index of the largest number in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static int IndexOfMax<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            return TensorPrimitives.IndexOfMax(span);
        }
        #endregion
 
        #region IndexOfMaxMagnitude
        /// <summary>Searches for the index of the number with the largest magnitude in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static int IndexOfMaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            return TensorPrimitives.IndexOfMaxMagnitude(span);
        }
        #endregion
 
        #region IndexOfMin
        /// <summary>Searches for the index of the smallest number in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static int IndexOfMin<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            return TensorPrimitives.IndexOfMin(span);
        }
        #endregion
 
        #region IndexOfMinMagnitude
        /// <summary>
        /// Searches for the index of the number with the smallest magnitude in the specified tensor.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static int IndexOfMinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            return TensorPrimitives.IndexOfMinMagnitude(span);
        }
        #endregion
 
        #region LeadingZeroCount
        /// <summary>
        /// Computes the element-wise leading zero count of numbers in the specified tensor.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> LeadingZeroCount<T>(in ReadOnlyTensorSpan<T> x)
            where T : IBinaryInteger<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            LeadingZeroCount(x, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise leading zero count of numbers in the specified tensor.
        /// </summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> LeadingZeroCount<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IBinaryInteger<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.LeadingZeroCount);
        }
        #endregion
 
        #region Log
        /// <summary>
        /// Takes the natural logarithm of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the natural logarithm of.</param>
        public static Tensor<T> Log<T>(in ReadOnlyTensorSpan<T> x)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Log(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the natural logarithm of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the natural logarithm of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Log<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Log);
        }
 
        /// <summary>Computes the element-wise logarithm of the numbers in a specified tensor to the specified base in another specified tensor.</summary>
        /// <param name="x">The first tensor</param>
        /// <param name="y">The second tensor</param>
        public static Tensor<T> Log<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Log(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise logarithm of the numbers in a specified tensor to the specified base in another specified tensor.</summary>
        /// <param name="x">The first tensor</param>
        /// <param name="y">The second tensor</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> Log<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Log);
        }
 
        /// <summary>Computes the element-wise logarithm of the numbers in a specified tensor to the specified base in another specified tensor.</summary>
        /// <param name="x">The first tensor</param>
        /// <param name="y">The second tensor</param>
        public static Tensor<T> Log<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
 
            Log(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise logarithm of the numbers in a specified tensor to the specified base in another specified tensor.</summary>
        /// <param name="x">The first tensor</param>
        /// <param name="y">The second tensor</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> Log<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Log);
        }
        #endregion
 
        #region Log10
        /// <summary>
        /// Takes the base 10 logarithm of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 10 logarithm of.</param>
        public static Tensor<T> Log10<T>(in ReadOnlyTensorSpan<T> x)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Log10(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the base 10 logarithm of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 10 logarithm of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Log10<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Log10);
        }
        #endregion
 
        #region Log10P1
        /// <summary>
        /// Takes the base 10 logarithm plus 1 of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 10 logarithm of.</param>
        public static Tensor<T> Log10P1<T>(in ReadOnlyTensorSpan<T> x)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Log10P1(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the base 10 logarithm plus 1 of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 10 logarithm of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Log10P1<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Log10P1);
        }
        #endregion
 
        #region Log2
        /// <summary>
        /// Takes the base 2 logarithm of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 2 logarithm of.</param>
        public static Tensor<T> Log2<T>(in ReadOnlyTensorSpan<T> x)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Log2(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the base 2 logarithm of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 2 logarithm of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Log2<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Log2);
        }
        #endregion
 
        #region Log2P1
        /// <summary>
        /// Takes the base 2 logarithm plus 1 of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 2 logarithm of.</param>
        public static Tensor<T> Log2P1<T>(in ReadOnlyTensorSpan<T> x)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Log2P1(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the base 2 logarithm plus 1 of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the base 2 logarithm of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Log2P1<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Log2P1);
        }
        #endregion
 
        #region LogP1
        /// <summary>
        /// Takes the natural logarithm plus 1 of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the natural logarithm of.</param>
        public static Tensor<T> LogP1<T>(in ReadOnlyTensorSpan<T> x)
            where T : ILogarithmicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            LogP1(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the natural logarithm plus 1 of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the natural logarithm of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> LogP1<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ILogarithmicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.LogP1);
        }
        #endregion
 
        #region Max
        /// <summary>Searches for the largest number in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>..</param>
        public static T Max<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.Max);
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> Max<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Max(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> Max<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Max);
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> Max<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Max(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> Max<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Max);
        }
        #endregion
 
        #region MaxMagnitude
        /// <summary>Searches for the number with the largest magnitude in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>..</param>
        public static T MaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.MaxMagnitude);
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MaxMagnitude<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            MaxMagnitude(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.MaxMagnitude);
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MaxMagnitude<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            MaxMagnitude(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.MaxMagnitude);
        }
        #endregion
 
        #region MaxMagnitudeNumber
        /// <summary>Searches for the number with the largest magnitude in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>..</param>
        public static T MaxMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumberBase<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.MaxMagnitudeNumber);
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MaxMagnitudeNumber<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            MaxMagnitudeNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MaxMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.MaxMagnitudeNumber);
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MaxMagnitudeNumber<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            MaxMagnitudeNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the largest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MaxMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.MaxMagnitudeNumber);
        }
        #endregion
 
        #region MaxNumber
        /// <summary>Searches for the largest number in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>..</param>
        public static T MaxNumber<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.MaxNumber);
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MaxNumber<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            MaxNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MaxNumber<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.MaxNumber);
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MaxNumber<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            MaxNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise maximum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MaxNumber<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.MaxNumber);
        }
        #endregion
 
        #region Min
        /// <summary>Searches for the smallest number in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static T Min<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.Min);
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> Min<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Min(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> Min<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Min);
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> Min<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Min(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> Min<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Min);
        }
        #endregion
 
        #region MinMagnitude
        /// <summary>Searches for the number with the smallest magnitude in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static T MinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.MinMagnitude);
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MinMagnitude<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            MinMagnitude(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.MinMagnitude);
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MinMagnitude<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            MinMagnitude(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.MinMagnitude);
        }
        #endregion
 
        #region MinMagnitudeNumber
        /// <summary>Searches for the number with the smallest magnitude in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>..</param>
        public static T MinMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumberBase<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.MinMagnitudeNumber);
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MinMagnitudeNumber<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            MinMagnitudeNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MinMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.MinMagnitudeNumber);
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MinMagnitudeNumber<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            MinMagnitudeNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise number with the smallest magnitude in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MinMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.MinMagnitudeNumber);
        }
        #endregion
 
        #region MinNumber
        /// <summary>Searches for the smallest number in the specified tensor.</summary>
        /// <param name="x">The input <see cref="TensorSpan{T}"/>..</param>
        public static T MinNumber<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.MinNumber);
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MinNumber<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            MinNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MinNumber<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.MinNumber);
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        public static Tensor<T> MinNumber<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            MinNumber(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise minimum of the numbers in the specified tensors.</summary>
        /// <param name="x">The first tensor, represented as a span.</param>
        /// <param name="y">The second tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        public static ref readonly TensorSpan<T> MinNumber<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.MinNumber);
        }
        #endregion
 
        #region Multiply
        /// <summary>
        /// Multiplies each element of <paramref name="x"/> with <paramref name="y"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="y"><typeparamref name="T"/> value to multiply by.</param>
        public static Tensor<T> Multiply<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Multiply((ReadOnlyTensorSpan<T>)x, y, output);
            return output;
        }
 
        /// <summary>
        /// Multiplies each element of <paramref name="x"/> with <paramref name="y"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// If the shapes are not the same they are broadcast to the smallest compatible shape.
        /// </summary>
        /// <param name="x">Left <see cref="ReadOnlyTensorSpan{T}"/> for multiplication.</param>
        /// <param name="y">Right <see cref="ReadOnlyTensorSpan{T}"/> for multiplication.</param>
        public static Tensor<T> Multiply<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Multiply((ReadOnlyTensorSpan<T>)x, y, output);
            return output;
        }
 
        /// <summary>
        /// Multiplies each element of <paramref name="x"/> with <paramref name="y"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">Input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="y"><typeparamref name="T"/> value to multiply by.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Multiply<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            TensorPrimitives.Multiply(span, y, ospan);
            return ref destination;
        }
 
        /// <summary>
        /// Multiplies each element of <paramref name="x"/> with <paramref name="y"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// If the shapes are not the same they are broadcast to the smallest compatible shape.
        /// </summary>
        /// <param name="x">Left <see cref="ReadOnlyTensorSpan{T}"/> for multiplication.</param>
        /// <param name="y">Right <see cref="ReadOnlyTensorSpan{T}"/> for multiplication.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Multiply<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IMultiplyOperators<T, T, T>, IMultiplicativeIdentity<T, T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Multiply);
        }
        #endregion
 
        #region Negate
        /// <summary>Computes the element-wise negation of each number in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/></param>
        public static Tensor<T> Negate<T>(in ReadOnlyTensorSpan<T> x)
            where T : IUnaryNegationOperators<T, T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Negate(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise negation of each number in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Negate<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IUnaryNegationOperators<T, T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Negate);
        }
        #endregion
 
        #region Norm
        /// <summary>
        ///  Takes the norm of the <see cref="ReadOnlyTensorSpan{T}"/> and returns the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the norm of.</param>
        public static T Norm<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : IRootFunctions<T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.Norm);
        }
        #endregion
 
        #region OnesComplement
        /// <summary>Computes the element-wise one's complement of numbers in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/></param>
        public static Tensor<T> OnesComplement<T>(in ReadOnlyTensorSpan<T> x)
            where T : IBitwiseOperators<T, T, T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            OnesComplement(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise one's complement of numbers in the specified tensor.</summary>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> OnesComplement<T>(scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IBitwiseOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(y, destination, TensorPrimitives.OnesComplement);
        }
        #endregion
 
        #region PopCount
        /// <summary>Computes the element-wise population count of numbers in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/></param>
        public static Tensor<T> PopCount<T>(in ReadOnlyTensorSpan<T> x)
            where T : IBinaryInteger<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            PopCount(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise population count of numbers in the specified tensor.</summary>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> PopCount<T>(scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IBinaryInteger<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(y, destination, TensorPrimitives.PopCount);
        }
        #endregion
 
        #region Pow
        /// <summary>Computes the element-wise power of a number in a specified tensor raised to a number in another specified tensors.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second input <see cref="ReadOnlyTensorSpan{T}"/></param>
        public static Tensor<T> Pow<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IPowerFunctions<T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Pow(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise power of a number in a specified tensor raised to a number in another specified tensors.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Pow<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IPowerFunctions<T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Pow);
        }
 
        /// <summary>Computes the element-wise power of a number in a specified tensor raised to a number in another specified tensors.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second input</param>
        public static Tensor<T> Pow<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IPowerFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
 
            Pow(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise power of a number in a specified tensor raised to a number in another specified tensors.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Pow<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IPowerFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Pow);
        }
 
        /// <summary>Computes the element-wise power of a number in a specified tensor raised to a number in another specified tensors.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second input</param>
        public static Tensor<T> Pow<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IPowerFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(y.Lengths);
 
            Pow(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise power of a number in a specified tensor raised to a number in another specified tensors.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second input <see cref="ReadOnlyTensorSpan{T}"/></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Pow<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IPowerFunctions<T>
        {
            return ref TensorPrimitivesHelperTInSpanInSpanOut(x, y, destination, TensorPrimitives.Pow);
        }
        #endregion
 
        #region Product
        /// <summary>Computes the product of all elements in the specified non-empty tensor of numbers.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static T Product<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : IMultiplicativeIdentity<T, T>, IMultiplyOperators<T, T, T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.Product);
        }
        #endregion
 
        #region RadiansToDegrees
        /// <summary>Computes the element-wise conversion of each number of radians in the specified tensor to degrees.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> RadiansToDegrees<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            RadiansToDegrees(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise conversion of each number of radians in the specified tensor to degrees.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> RadiansToDegrees<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.RadiansToDegrees);
        }
        #endregion
 
        #region Reciprocal
        /// <summary>Computes the element-wise reciprocal of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Reciprocal<T>(in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Reciprocal(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise reciprocal of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Reciprocal<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Reciprocal);
        }
        #endregion
 
        #region RootN
        /// <summary>Computes the element-wise n-th root of the values in the specified tensor.</summary>
        /// <param name="x">The tensor, represented as a span.</param>
        /// <param name="n">The degree of the root to be computed, represented as a scalar.</param>
        public static Tensor<T> RootN<T>(in ReadOnlyTensorSpan<T> x, int n)
            where T : IRootFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            RootN(x, n, output);
            return output;
        }
 
        /// <summary>Computes the element-wise n-th root of the values in the specified tensor.</summary>
        /// <param name="x">The tensor, represented as a span.</param>
        /// <param name="destination">The destination tensor, represented as a span.</param>
        /// <param name="n">The degree of the root to be computed, represented as a scalar.</param>
        public static ref readonly TensorSpan<T> RootN<T>(scoped in ReadOnlyTensorSpan<T> x, int n, in TensorSpan<T> destination)
            where T : IRootFunctions<T>
        {
            if (destination._shape._memoryLength < x._shape._memoryLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            TensorPrimitives.RootN(span, n, ospan);
            return ref destination;
        }
        #endregion
 
        #region RotateLeft
        /// <summary>Computes the element-wise rotation left of numbers in the specified tensor by the specified rotation amount.</summary>
        /// <param name="x">The tensor</param>
        /// <param name="rotateAmount">The number of bits to rotate, represented as a scalar.</param>
        /// <exception cref="ArgumentException">Destination is too short.</exception>
        public static Tensor<T> RotateLeft<T>(in ReadOnlyTensorSpan<T> x, int rotateAmount)
            where T : IBinaryInteger<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            RotateLeft(x, rotateAmount, output);
            return output;
        }
 
        /// <summary>Computes the element-wise rotation left of numbers in the specified tensor by the specified rotation amount.</summary>
        /// <param name="x">The tensor</param>
        /// <param name="rotateAmount">The number of bits to rotate, represented as a scalar.</param>
        /// <param name="destination"></param>
        /// <exception cref="ArgumentException">Destination is too short.</exception>
        public static ref readonly TensorSpan<T> RotateLeft<T>(scoped in ReadOnlyTensorSpan<T> x, int rotateAmount, in TensorSpan<T> destination)
            where T : IBinaryInteger<T>
        {
            if (destination._shape._memoryLength < x._shape._memoryLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            TensorPrimitives.RotateLeft(span, rotateAmount, ospan);
            return ref destination;
        }
        #endregion
 
        #region RotateRight
        /// <summary>Computes the element-wise rotation right of numbers in the specified tensor by the specified rotation amount.</summary>
        /// <param name="x">The tensor</param>
        /// <param name="rotateAmount">The number of bits to rotate, represented as a scalar.</param>
        /// <exception cref="ArgumentException">Destination is too short.</exception>
        public static Tensor<T> RotateRight<T>(in ReadOnlyTensorSpan<T> x, int rotateAmount)
            where T : IBinaryInteger<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            RotateRight(x, rotateAmount, output);
            return output;
        }
 
        /// <summary>Computes the element-wise rotation right of numbers in the specified tensor by the specified rotation amount.</summary>
        /// <param name="x">The tensor</param>
        /// <param name="rotateAmount">The number of bits to rotate, represented as a scalar.</param>
        /// <param name="destination"></param>
        /// <exception cref="ArgumentException">Destination is too short.</exception>
        public static ref readonly TensorSpan<T> RotateRight<T>(scoped in ReadOnlyTensorSpan<T> x, int rotateAmount, in TensorSpan<T> destination)
            where T : IBinaryInteger<T>
        {
            if (destination._shape._memoryLength < x._shape._memoryLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            TensorPrimitives.RotateRight(span, rotateAmount, ospan);
            return ref destination;
        }
        #endregion
 
        #region Round
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Round<T>(in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Round(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Round<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Round);
        }
 
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="digits"></param>
        /// <param name="mode"></param>
        public static Tensor<T> Round<T>(in ReadOnlyTensorSpan<T> x, int digits, MidpointRounding mode)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Round(x, digits, mode, output);
            return output;
        }
 
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="digits"></param>
        /// <param name="mode"></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Round<T>(scoped in ReadOnlyTensorSpan<T> x, int digits, MidpointRounding mode, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            if (destination._shape._memoryLength < x._shape._memoryLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            TensorPrimitives.Round(span, digits, mode, ospan);
            return ref destination;
        }
 
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="digits"></param>
        public static Tensor<T> Round<T>(in ReadOnlyTensorSpan<T> x, int digits)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Round(x, digits, output);
            return output;
        }
 
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="digits"></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Round<T>(scoped in ReadOnlyTensorSpan<T> x, int digits, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            if (destination._shape._memoryLength < x._shape._memoryLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            TensorPrimitives.Round(span, digits, ospan);
            return ref destination;
        }
 
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="mode"></param>
        public static Tensor<T> Round<T>(in ReadOnlyTensorSpan<T> x, MidpointRounding mode)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Round(x, mode, output);
            return output;
        }
 
        /// <summary>Computes the element-wise rounding of the numbers in the specified tensor</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="mode"></param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Round<T>(scoped in ReadOnlyTensorSpan<T> x, MidpointRounding mode, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            if (destination._shape._memoryLength < x._shape._memoryLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape._memoryLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
            TensorPrimitives.Round(span, mode, ospan);
            return ref destination;
        }
        #endregion
 
        #region Sigmoid
        /// <summary>Computes the element-wise sigmoid function on the specified non-empty tensor of numbers.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Sigmoid<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Sigmoid(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise sigmoid function on the specified non-empty tensor of numbers.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Sigmoid<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Sigmoid);
        }
        #endregion
 
        #region Sin
        /// <summary>
        /// Takes the sin of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Sin<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Sin(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the sin of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Sin<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Sin);
        }
        #endregion
 
        #region Sinh
        /// <summary>Computes the element-wise hyperbolic sine of each radian angle in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Sinh<T>(in ReadOnlyTensorSpan<T> x)
            where T : IHyperbolicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Sinh(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise hyperbolic sine of each radian angle in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Sinh<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IHyperbolicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Sinh);
        }
        #endregion
 
        #region SinPi
        /// <summary>Computes the element-wise sine of the value in the specified tensor that has been multiplied by Pi.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> SinPi<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            SinPi(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise sine of the value in the specified tensor that has been multiplied by Pi.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> SinPi<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.SinPi);
        }
        #endregion
 
        #region SoftMax
        /// <summary>Computes the softmax function over the specified non-empty tensor of numbers.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> SoftMax<T>(in ReadOnlyTensorSpan<T> x)
            where T : IExponentialFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            SoftMax(x, output);
            return output;
        }
 
        /// <summary>Computes the softmax function over the specified non-empty tensor of numbers.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> SoftMax<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IExponentialFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.SoftMax);
        }
        #endregion
 
        #region Sqrt
        /// <summary>
        /// Takes the square root of each element of the <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the square root of.</param>
        public static Tensor<T> Sqrt<T>(in ReadOnlyTensorSpan<T> x)
            where T : IRootFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Sqrt(x, output);
            return output;
        }
 
        /// <summary>
        /// Takes the square root of each element of the <paramref name="x"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the square root of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Sqrt<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IRootFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Sqrt);
        }
        #endregion
 
        #region Subtract
        /// <summary>
        /// Subtracts <paramref name="y"/> from each element of <paramref name="x"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The <typeparamref name="T"/> to subtract.</param>
        public static Tensor<T> Subtract<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : ISubtractionOperators<T, T, T>
        {
            Tensor<T> output = Create<T>(x.Lengths);
            Subtract(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Subtracts each element of <paramref name="y"/> from <paramref name="x"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <typeparamref name="T"/> to be subtracted from.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/> of values to subtract.</param>
        public static Tensor<T> Subtract<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : ISubtractionOperators<T, T, T>
        {
            Tensor<T> output = Create<T>(y.Lengths);
            Subtract(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Subtracts each element of <paramref name="x"/> from <paramref name="y"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> with values to be subtracted from.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/> with values to subtract.</param>
        public static Tensor<T> Subtract<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : ISubtractionOperators<T, T, T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Subtract(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Subtracts <paramref name="y"/> from each element of <paramref name="x"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> with values to be subtracted from.</param>
        /// <param name="y">The <typeparamref name="T"/> value to subtract.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Subtract<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : ISubtractionOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Subtract);
        }
 
        /// <summary>
        /// Subtracts each element of <paramref name="y"/> from <paramref name="x"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <typeparamref name="T"/> value to be subtracted from.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/> values to subtract.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Subtract<T>(T x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : ISubtractionOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperTInSpanInSpanOut(x, y, destination, TensorPrimitives.Subtract);
        }
 
        /// <summary>
        /// Subtracts each element of <paramref name="x"/> from <paramref name="y"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> of values to be subtracted from.</param>
        /// <param name="y">The <see cref="ReadOnlyTensorSpan{T}"/>of values to subtract.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Subtract<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : ISubtractionOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Subtract);
        }
        #endregion
 
        #region Sum
        /// <summary>
        /// Sums the elements of the specified tensor.
        /// </summary>
        /// <param name="x">Tensor to sum</param>
        /// <returns></returns>
        public static T Sum<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>
        {
            return TensorPrimitivesHelperSpanInTOut(x, TensorPrimitives.Sum);
        }
        #endregion
 
        #region Tan
        /// <summary>Computes the element-wise tangent of the value in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Tan<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Tan(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise tangent of the value in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Tan<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Tan);
        }
        #endregion
 
        #region Tanh
        /// <summary>Computes the element-wise hyperbolic tangent of each radian angle in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> Tanh<T>(in ReadOnlyTensorSpan<T> x)
            where T : IHyperbolicFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Tanh(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise hyperbolic tangent of each radian angle in the specified tensor.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Tanh<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IHyperbolicFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Tanh);
        }
        #endregion
 
        #region TanPi
        /// <summary>Computes the element-wise tangent of the value in the specified tensor that has been multiplied by Pi.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        public static Tensor<T> TanPi<T>(in ReadOnlyTensorSpan<T> x)
            where T : ITrigonometricFunctions<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            TanPi(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise tangent of the value in the specified tensor that has been multiplied by Pi.</summary>
        /// <param name="x">The <see cref="ReadOnlyTensorSpan{T}"/> to take the sin of.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> TanPi<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : ITrigonometricFunctions<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.TanPi);
        }
        #endregion
 
        #region TrailingZeroCount
        /// <summary>Computes the element-wise trailing zero count of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> TrailingZeroCount<T>(in ReadOnlyTensorSpan<T> x)
            where T : IBinaryInteger<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            TrailingZeroCount(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise trailing zero count of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> TrailingZeroCount<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IBinaryInteger<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.TrailingZeroCount);
        }
        #endregion
 
        #region Truncate
        /// <summary>Computes the element-wise truncation of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Truncate<T>(in ReadOnlyTensorSpan<T> x)
            where T : IFloatingPoint<T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Truncate(x, output);
            return output;
        }
 
        /// <summary>Computes the element-wise truncation of numbers in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Truncate<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            return ref TensorPrimitivesHelperSpanInSpanOut(x, destination, TensorPrimitives.Truncate);
        }
        #endregion
 
        #region Xor
        /// <summary>Computes the element-wise XOR of numbers in the specified tensors.</summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        public static Tensor<T> Xor<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IBitwiseOperators<T, T, T>
        {
            Tensor<T> output;
            if (x.Lengths.SequenceEqual(y.Lengths))
            {
                output = Tensor.Create<T>(x.Lengths);
            }
            else
            {
                output = Tensor.Create<T>(GetSmallestBroadcastableLengths(x.Lengths, y.Lengths));
            }
 
            Xor(x, y, output);
            return output;
        }
 
        /// <summary>Computes the element-wise XOR of numbers in the specified tensors.</summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The right <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Xor<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : IBitwiseOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperTwoSpanInSpanOut(x, y, destination, TensorPrimitives.Xor);
        }
 
        /// <summary>
        /// Computes the element-wise Xor of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="Tensor{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second value.</param>
        public static Tensor<T> Xor<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IBitwiseOperators<T, T, T>
        {
            Tensor<T> output = Tensor.Create<T>(x.Lengths);
            Xor(x, y, output);
            return output;
        }
 
        /// <summary>
        /// Computes the element-wise Xor of the two input <see cref="ReadOnlyTensorSpan{T}"/> and returns a new <see cref="TensorSpan{T}"/> with the result.
        /// </summary>
        /// <param name="x">The left <see cref="ReadOnlyTensorSpan{T}"/>.</param>
        /// <param name="y">The second value.</param>
        /// <param name="destination"></param>
        public static ref readonly TensorSpan<T> Xor<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : IBitwiseOperators<T, T, T>
        {
            return ref TensorPrimitivesHelperSpanInTInSpanOut(x, y, destination, TensorPrimitives.Xor);
        }
        #endregion
 
        /// <summary>
        /// Gets the smallest broadcastable lengths for two shapes.
        /// </summary>
        /// <param name="shape1">The first shape to broadcast.</param>
        /// <param name="shape2">The second shape to broadcast.</param>
        /// <returns>The smallest lengths these shapes can be broadcast to.</returns>
        /// <exception cref="ArgumentException">The lengths of <paramref name="shape1" /> and  <paramref name="shape2" /> are not broadcast compatible.</exception>
        public static nint[] GetSmallestBroadcastableLengths(ReadOnlySpan<nint> shape1, ReadOnlySpan<nint> shape2)
        {
            if (!TensorHelpers.IsBroadcastableTo(shape1, shape2))
                ThrowHelper.ThrowArgument_LengthsNotBroadcastCompatible();
 
            nint[] intermediateShape = TensorHelpers.GetIntermediateShape(shape1, shape2.Length);
            for (int i = 1; i <= shape1.Length; i++)
            {
                intermediateShape[^i] = Math.Max(intermediateShape[^i], shape1[^i]);
            }
            for (int i = 1; i <= shape2.Length; i++)
            {
                intermediateShape[^i] = Math.Max(intermediateShape[^i], shape2[^i]);
            }
 
            return intermediateShape;
        }
 
        #region TensorPrimitivesHelpers
        private delegate void PerformCalculationSpanInSpanOut<TIn, TOut>(ReadOnlySpan<TIn> input, Span<TOut> output);
 
        private delegate void PerformCalculationSpanInTInSpanOut<T>(ReadOnlySpan<T> input, T value, Span<T> output);
 
        private delegate void PerformCalculationTInSpanInSpanOut<T>(T value, ReadOnlySpan<T> input, Span<T> output);
 
        private delegate void PerformCalculationTwoSpanInSpanOut<T>(ReadOnlySpan<T> input, ReadOnlySpan<T> inputTwo, Span<T> output);
 
        private delegate T PerformCalculationTwoSpanInTOut<T>(ReadOnlySpan<T> input, ReadOnlySpan<T> inputTwo);
 
        private delegate T PerformCalculationSpanInTOut<T>(ReadOnlySpan<T> input);
 
        private static T TensorPrimitivesHelperSpanInTOut<T>(scoped in ReadOnlyTensorSpan<T> input, PerformCalculationSpanInTOut<T> performCalculation)
        {
            if (TensorHelpers.IsContiguousAndDense(input))
            {
                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref input._reference, (int)input._shape.FlattenedLength);
                return performCalculation(span);
            }
            // Flattening needs to happen
            else
            {
                // TODO: Can optimize this to not need to realize the broadcasts
                // That will need to be done on a per method basis.
                nint flattenedLength = input.FlattenedLength;
                T[] flattened = new T[flattenedLength];
                input.FlattenTo(flattened);
                return performCalculation(flattened);
            }
        }
 
        private static T TensorPrimitivesHelperTwoSpanInTOut<T>(scoped in ReadOnlyTensorSpan<T> left, scoped in ReadOnlyTensorSpan<T> right, PerformCalculationTwoSpanInTOut<T> performCalculation)
        {
            // If sizes are the same.
            if (TensorHelpers.IsContiguousAndDense(left) && TensorHelpers.IsContiguousAndDense(right) && TensorHelpers.AreLengthsTheSame(left, right))
            {
                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref left._reference, (int)left._shape.FlattenedLength);
                ReadOnlySpan<T> rspan = MemoryMarshal.CreateSpan(ref right._reference, (int)right._shape.FlattenedLength);
                return performCalculation(span, rspan);
            }
            // Broadcasting needs to happen.
            else
            {
                // Have a couple different possible cases here.
                // 1 - Both tensors have row contiguous memory (i.e. a 1x5 being broadcast to a 5x5)
                // 2 - One tensor has row contiguous memory and the right has column contiguous memory (i.e. a 1x5 and a 5x1)
                // Because we are returning a single T though we need to actual realize the broadcasts at this point to perform the calculations.
 
                // TODO: Can optimize this to not need to realize the broadcasts
                // That will need to be done on a per method basis.
                nint[] newLengths = Tensor.GetSmallestBroadcastableLengths(left.Lengths, right.Lengths);
                nint newLength = TensorSpanHelpers.CalculateTotalLength(newLengths);
                TensorSpan<T> broadcastedLeft = new TensorSpan<T>(new T[newLength], newLengths, ReadOnlySpan<nint>.Empty);
                TensorSpan<T> broadcastedRight = new TensorSpan<T>(new T[newLength], newLengths, ReadOnlySpan<nint>.Empty);
                BroadcastTo(left, broadcastedLeft);
                BroadcastTo(right, broadcastedRight);
 
                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref broadcastedLeft._reference, (int)broadcastedLeft.FlattenedLength);
                ReadOnlySpan<T> rspan = MemoryMarshal.CreateSpan(ref broadcastedRight._reference, (int)broadcastedRight.FlattenedLength);
                return performCalculation(span, rspan);
            }
        }
 
        private static ref readonly TensorSpan<TOut> TensorPrimitivesHelperSpanInSpanOut<TIn, TOut>(scoped in ReadOnlyTensorSpan<TIn> input, in TensorSpan<TOut> destination, PerformCalculationSpanInSpanOut<TIn, TOut> performCalculation)
        {
            // Make sure destination has enough memory
            if (destination._shape._memoryLength < input._shape.FlattenedLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            // Make sure destination shape works with input shape
            TensorSpan<TOut> slicedDestination = destination.Slice(input._shape.Lengths);
 
            Span<TOut> destinationSpan;
            ReadOnlySpan<TIn> inputSpan;
 
            // Memory is contiguous for both input and destination
            if (TensorHelpers.IsContiguousAndDense(input) && TensorHelpers.IsContiguousAndDense<TOut>(slicedDestination))
            {
                inputSpan = MemoryMarshal.CreateSpan(ref input._reference, (int)input._shape.FlattenedLength);
                destinationSpan = MemoryMarshal.CreateSpan(ref slicedDestination._reference, (int)slicedDestination._shape.FlattenedLength);
                performCalculation(inputSpan, destinationSpan);
            }
            else
            {
                scoped Span<nint> curIndex;
                nint[]? curIndexArray;
                if (input.Lengths.Length > TensorShape.MaxInlineRank)
                {
                    curIndexArray = ArrayPool<nint>.Shared.Rent(input.Lengths.Length);
                    curIndex = curIndexArray.AsSpan(0, input.Rank);
                }
                else
                {
                    curIndexArray = null;
                    curIndex = stackalloc nint[input.Lengths.Length];
                }
                curIndex.Clear();
 
                int copiedValues = 0;
                nint rowLength = input.Lengths[^1];
 
                while (copiedValues < slicedDestination.FlattenedLength)
                {
                    inputSpan = MemoryMarshal.CreateReadOnlySpan(in input[curIndex], (int)rowLength);
                    destinationSpan = MemoryMarshal.CreateSpan(ref slicedDestination[curIndex], (int)rowLength);
                    performCalculation(inputSpan, destinationSpan);
                    copiedValues += (int)rowLength;
                    TensorSpanHelpers.AdjustIndexes(input.Rank - 2, 1, curIndex, input.Lengths);
                }
 
                if (curIndexArray != null)
                    ArrayPool<nint>.Shared.Return(curIndexArray);
            }
 
            return ref destination;
        }
 
        private static ref readonly TensorSpan<T> TensorPrimitivesHelperSpanInTInSpanOut<T>(scoped in ReadOnlyTensorSpan<T> input, T value, in TensorSpan<T> destination, PerformCalculationSpanInTInSpanOut<T> performCalculation)
        {
            if (destination._shape._memoryLength < input._shape.FlattenedLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            // Make sure destination shape works with input shape
            TensorSpan<T> slicedDestination = destination.Slice(input._shape.Lengths);
 
            ReadOnlySpan<T> inputSpan;
            Span<T> destinationSpan;
 
            if (TensorHelpers.IsContiguousAndDense(input) && TensorHelpers.IsContiguousAndDense<T>(slicedDestination))
            {
                inputSpan = MemoryMarshal.CreateSpan(ref input._reference, (int)input.FlattenedLength);
                destinationSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination.FlattenedLength);
                performCalculation(inputSpan, value, destinationSpan);
            }
            else
            {
                scoped Span<nint> curIndex;
                nint[]? curIndexArray;
                if (input.Lengths.Length > TensorShape.MaxInlineRank)
                {
                    curIndexArray = ArrayPool<nint>.Shared.Rent(input.Lengths.Length);
                    curIndex = curIndexArray.AsSpan(0, input.Rank);
                }
                else
                {
                    curIndexArray = null;
                    curIndex = stackalloc nint[input.Lengths.Length];
                }
                curIndex.Clear();
 
                int copiedValues = 0;
                nint rowLength = input.Lengths[^1];
 
                while (copiedValues < slicedDestination.FlattenedLength)
                {
                    inputSpan = MemoryMarshal.CreateReadOnlySpan(in input[curIndex], (int)rowLength);
                    destinationSpan = MemoryMarshal.CreateSpan(ref slicedDestination[curIndex], (int)rowLength);
                    performCalculation(inputSpan, value, destinationSpan);
                    copiedValues += (int)rowLength;
                    TensorSpanHelpers.AdjustIndexes(input.Rank - 2, 1, curIndex, input.Lengths);
                }
 
                if (curIndexArray != null)
                    ArrayPool<nint>.Shared.Return(curIndexArray);
            }
 
            return ref destination;
        }
 
        private static ref readonly TensorSpan<T> TensorPrimitivesHelperTInSpanInSpanOut<T>(T value, scoped in ReadOnlyTensorSpan<T> input, in TensorSpan<T> destination, PerformCalculationTInSpanInSpanOut<T> performCalculation)
        {
            if (destination._shape._memoryLength < input._shape.FlattenedLength)
                ThrowHelper.ThrowArgumentException_DestinationTooShort();
 
            // Make sure destination shape works with input shape
            TensorSpan<T> slicedDestination = destination.Slice(input._shape.Lengths);
 
            ReadOnlySpan<T> inputSpan;
            Span<T> destinationSpan;
 
            if (TensorHelpers.IsContiguousAndDense(input) && TensorHelpers.IsContiguousAndDense<T>(slicedDestination))
            {
                inputSpan = MemoryMarshal.CreateSpan(ref input._reference, (int)input._shape._memoryLength);
                destinationSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape._memoryLength);
                performCalculation(value, inputSpan, destinationSpan);
            }
            else
            {
                scoped Span<nint> curIndex;
                nint[]? curIndexArray;
                if (input.Lengths.Length > TensorShape.MaxInlineRank)
                {
                    curIndexArray = ArrayPool<nint>.Shared.Rent(input.Lengths.Length);
                    curIndex = curIndexArray.AsSpan(0, input.Rank);
                }
                else
                {
                    curIndexArray = null;
                    curIndex = stackalloc nint[input.Lengths.Length];
                }
                curIndex.Clear();
 
                int copiedValues = 0;
                nint rowLength = input.Lengths[^1];
 
                while (copiedValues < slicedDestination.FlattenedLength)
                {
                    inputSpan = MemoryMarshal.CreateReadOnlySpan(in input[curIndex], (int)rowLength);
                    destinationSpan = MemoryMarshal.CreateSpan(ref slicedDestination[curIndex], (int)rowLength);
                    performCalculation(value, inputSpan, destinationSpan);
                    copiedValues += (int)rowLength;
                    TensorSpanHelpers.AdjustIndexes(input.Rank - 2, 1, curIndex, input.Lengths);
                }
 
                if (curIndexArray != null)
                    ArrayPool<nint>.Shared.Return(curIndexArray);
            }
 
            return ref destination;
        }
 
        private static ref readonly TensorSpan<T> TensorPrimitivesHelperTwoSpanInSpanOut<T>(scoped in ReadOnlyTensorSpan<T> left, scoped in ReadOnlyTensorSpan<T> right, in TensorSpan<T> destination, PerformCalculationTwoSpanInSpanOut<T> performCalculation)
        {
            nint[] newSize = Tensor.GetSmallestBroadcastableLengths(left.Lengths, right.Lengths);
 
            TensorSpan<T> slicedDestination = destination.Slice(newSize);
 
            // If sizes are the same and memory is contiguous for all tensors
            if (TensorHelpers.AreLengthsTheSame(left, right) && TensorHelpers.IsUnderlyingStorageSameSize(left, right) && TensorHelpers.IsContiguousAndDense(left)
                && TensorHelpers.IsContiguousAndDense(right) && TensorHelpers.IsContiguousAndDense<T>(slicedDestination))
            {
                ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref left._reference, left._shape._memoryLength <= left.FlattenedLength ? (int)left._shape._memoryLength : (int)left.FlattenedLength);
                ReadOnlySpan<T> rspan = MemoryMarshal.CreateSpan(ref right._reference, right._shape._memoryLength <= right.FlattenedLength ? (int)right._shape._memoryLength : (int)right.FlattenedLength);
                Span<T> ospan = MemoryMarshal.CreateSpan(ref slicedDestination._reference, (int)slicedDestination._shape._memoryLength);
                performCalculation(span, rspan, ospan);
                return ref destination;
            }
            // Broadcasting needs to happen.
            else
            {
                // Have a couple different possible cases here.
                // 1 - Both tensors have row contiguous memory (i.e. a 1x5 being broadcast to a 5x5)
                // 2 - One tensor has row contiguous memory and the right has column contiguous memory (i.e. a 1x5 and a 5x1)
 
                ReadOnlyTensorSpan<T> broadcastedLeft = Tensor.LazyBroadcast(left, newSize);
                ReadOnlyTensorSpan<T> broadcastedRight = Tensor.LazyBroadcast(right, newSize);
 
                nint rowLength = newSize[^1];
                Span<T> ospan;
                ReadOnlySpan<T> ispan;
                Span<T> buffer = new T[rowLength];
 
                scoped Span<nint> curIndex;
                nint[]? curIndexArray;
                if (newSize.Length > TensorShape.MaxInlineRank)
                {
                    curIndexArray = ArrayPool<nint>.Shared.Rent(newSize.Length);
                    curIndex = curIndexArray.AsSpan(0, newSize.Length);
                }
                else
                {
                    curIndexArray = null;
                    curIndex = stackalloc nint[newSize.Length];
                }
                curIndex.Clear();
 
                int outputOffset = 0;
                // neither row contiguous
                if (broadcastedLeft.Strides[^1] == 0 && broadcastedRight.Strides[^1] == 0)
                {
                    Span<T> buffer2 = new T[rowLength];
 
                    while (outputOffset < slicedDestination.FlattenedLength)
                    {
                        ospan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref slicedDestination._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, slicedDestination.Strides, slicedDestination.Lengths)), (int)rowLength);
                        buffer.Fill(broadcastedLeft[curIndex]);
                        buffer2.Fill(broadcastedRight[curIndex]);
                        performCalculation(buffer, buffer2, ospan);
                        outputOffset += (int)rowLength;
                        TensorSpanHelpers.AdjustIndexes(broadcastedLeft.Rank - 2, 1, curIndex, broadcastedLeft.Lengths);
                    }
                }
                // tensor not row contiguous
                else if (broadcastedLeft.Strides[^1] == 0)
                {
                    while (outputOffset < slicedDestination.FlattenedLength)
                    {
                        ospan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref slicedDestination._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, slicedDestination.Strides, slicedDestination.Lengths)), (int)rowLength);
                        buffer.Fill(broadcastedLeft[curIndex]);
                        ispan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref broadcastedRight._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, broadcastedRight.Strides, broadcastedRight.Lengths)), (int)rowLength);
                        performCalculation(buffer, ispan, ospan);
                        outputOffset += (int)rowLength;
                        TensorSpanHelpers.AdjustIndexes(broadcastedLeft.Rank - 2, 1, curIndex, broadcastedLeft.Lengths);
                    }
                }
                // right not row contiguous
                else if (broadcastedRight.Strides[^1] == 0)
                {
                    while (outputOffset < slicedDestination.FlattenedLength)
                    {
                        ospan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref slicedDestination._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, slicedDestination.Strides, slicedDestination.Lengths)), (int)rowLength);
                        buffer.Fill(broadcastedRight[curIndex]);
                        ispan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref broadcastedLeft._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, broadcastedLeft.Strides, broadcastedLeft.Lengths)), (int)rowLength);
                        performCalculation(ispan, buffer, ospan);
                        outputOffset += (int)rowLength;
                        TensorSpanHelpers.AdjustIndexes(broadcastedLeft.Rank - 2, 1, curIndex, broadcastedLeft.Lengths);
                    }
                }
                // both row contiguous
                else
                {
                    Span<T> rspan;
                    while (outputOffset < slicedDestination.FlattenedLength)
                    {
                        ospan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref slicedDestination._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, slicedDestination.Strides, slicedDestination.Lengths)), (int)rowLength);
                        ispan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref broadcastedLeft._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, broadcastedLeft.Strides, broadcastedLeft.Lengths)), (int)rowLength);
                        rspan = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref broadcastedRight._reference, TensorSpanHelpers.ComputeLinearIndex(curIndex, broadcastedRight.Strides, broadcastedRight.Lengths)), (int)rowLength);
                        performCalculation(ispan, rspan, ospan);
                        outputOffset += (int)rowLength;
                        TensorSpanHelpers.AdjustIndexes(broadcastedLeft.Rank - 2, 1, curIndex, broadcastedLeft.Lengths);
                    }
                }
 
                if (curIndexArray != null)
                    ArrayPool<nint>.Shared.Return(curIndexArray);
            }
            return ref destination;
        }
 
        #endregion
 
        #endregion
    }
}