File: System\Numerics\Tensors\netcore\Tensor.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.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
 
namespace System.Numerics.Tensors
{
    /// <summary>Provides methods for tensor operations.</summary>
    [Experimental(Experimentals.TensorTDiagId, UrlFormat = Experimentals.SharedUrlFormat)]
    public static partial class Tensor
    {
        #region AsTensorSpan
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[])" />
        public static ReadOnlyTensorSpan<T> AsReadOnlyTensorSpan<T>(this T[]? array)
            => new ReadOnlyTensorSpan<T>(array);
 
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[], ReadOnlySpan{nint})" />
        public static ReadOnlyTensorSpan<T> AsReadOnlyTensorSpan<T>(this T[]? array, scoped ReadOnlySpan<nint> lengths)
            => new ReadOnlyTensorSpan<T>(array, lengths);
 
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[], ReadOnlySpan{nint}, ReadOnlySpan{nint})" />
        public static ReadOnlyTensorSpan<T> AsReadOnlyTensorSpan<T>(this T[]? array, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides)
            => new ReadOnlyTensorSpan<T>(array, lengths, strides);
 
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[], int, ReadOnlySpan{nint}, ReadOnlySpan{nint})" />
        public static ReadOnlyTensorSpan<T> AsReadOnlyTensorSpan<T>(this T[]? array, int start, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides)
            => new ReadOnlyTensorSpan<T>(array, start, lengths, strides);
 
        /// <inheritdoc cref="TensorSpan{T}.TensorSpan(T[])" />
        public static TensorSpan<T> AsTensorSpan<T>(this T[]? array)
            => new TensorSpan<T>(array);
 
        /// <inheritdoc cref="TensorSpan{T}.TensorSpan(T[], ReadOnlySpan{nint})" />
        public static TensorSpan<T> AsTensorSpan<T>(this T[]? array, scoped ReadOnlySpan<nint> lengths)
            => new TensorSpan<T>(array, lengths);
 
        /// <inheritdoc cref="TensorSpan{T}.TensorSpan(T[], ReadOnlySpan{nint} , ReadOnlySpan{nint})" />
        public static TensorSpan<T> AsTensorSpan<T>(this T[]? array, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides)
            => new TensorSpan<T>(array, lengths, strides);
 
        /// <inheritdoc cref="TensorSpan{T}.TensorSpan(T[], int, ReadOnlySpan{nint}, ReadOnlySpan{nint})" />
        public static TensorSpan<T> AsTensorSpan<T>(this T[]? array, int start, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides) => new TensorSpan<T>(array, start, lengths, strides);
        #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)
        {
            TensorOperation.ValidateCompatibility<T>(source, lengths);
            Tensor<T> destination = Tensor.CreateUninitialized<T>(lengths);
            TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(source, destination);
            return destination;
        }
        #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)
        {
            TensorOperation.ValidateCompatibility<T, T>(source, destination);
            TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(source, destination);
        }
 
        /// <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)
        {
            TensorOperation.ValidateCompatibility<T, T>(source, destination);
            TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(source, destination);
        }
 
        /// <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)
        {
            TensorOperation.ValidateCompatibility<T, T>(source, destination);
            TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(source, destination);
        }
        #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_InvalidDimension();
 
            Tensor<T> tensor;
 
            // If axis != -1, make sure all dimensions except the one to concatenate on match.
            if (dimension != -1)
            {
                nint 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();
                        }
                    }
                    checked
                    {
                        sumOfAxis += tensors[i].Lengths[dimension];
                    }
                }
 
                nint[] lengths = new nint[tensors[0].Rank];
                tensors[0].Lengths.CopyTo(lengths);
                lengths[dimension] = sumOfAxis;
                tensor = Tensor.Create<T>(lengths);
            }
            else
            {
                // Calculate total space needed.
                nint totalLength = 0;
                for (int i = 0; i < tensors.Length; i++)
                {
                    checked
                    {
                        totalLength += tensors[i].FlattenedLength;
                    }
                }
 
                tensor = Tensor.Create<T>([totalLength]);
            }
 
            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_InvalidDimension();
 
            // Calculate total space needed.
            nint totalLength = 0;
            for (int i = 0; i < tensors.Length; i++)
                totalLength += tensors[i].FlattenedLength;
 
            // If axis != -1, make sure all dimensions except the one to concatenate on match.
            if (dimension != -1)
            {
                nint sumOfAxis = tensors[0].Lengths[dimension];
                int rank = tensors[0].Rank;
                for (int i = 1; i < tensors.Length; i++)
                {
                    if (rank != tensors[i].Rank)
                        ThrowHelper.ThrowArgument_InvalidConcatenateShape();
                    for (int j = 0; j < 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[rank];
                tensors[0].Lengths.CopyTo(lengths);
                lengths[dimension] = sumOfAxis;
 
                if (!TensorShape.AreLengthsTheSame(destination.Lengths, lengths))
                    ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(destination));
            }
            Span<T> dstSpan = MemoryMarshal.CreateSpan(ref destination._reference, (int)totalLength);
 
            if (dimension == 0 || dimension == -1)
            {
                for (int i = 0; i < tensors.Length; i++)
                {
                    TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(tensors[i], dstSpan);
                    dstSpan = dstSpan.Slice((int)tensors[i].FlattenedLength);
                }
            }
            else
            {
                Span<NRange> ranges = TensorOperation.RentedBuffer.CreateUninitialized(destination.Rank, out TensorOperation.RentedBuffer<NRange> rentedBuffer);
                for (int i = 0; i < dimension; i++)
                {
                    ranges[i] = 0..1;
                }
                for (int i = dimension; i < destination.Rank; i++)
                {
                    ranges[i] = ..;
                }
 
                bool hasMore = true;
                while (hasMore)
                {
                    for (int i = 0; i < tensors.Length; i++)
                    {
                        Tensor<T> slice = tensors[i].Slice(ranges);
                        TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(slice, dstSpan);
                        dstSpan = dstSpan.Slice((int)slice.FlattenedLength);
                    }
                    hasMore = IncrementIndexes(ranges, dimension, destination.Lengths);
                }
                rentedBuffer.Dispose();
            }
            return ref destination;
        }
 
        private static bool IncrementIndexes(Span<NRange> ranges, int dimension, ReadOnlySpan<nint> lengths)
        {
            NRange curRange = ranges[dimension - 1];
            ranges[dimension - 1] = new NRange(curRange.Start.Value + 1, curRange.End.Value + 1);
 
            for (int i = dimension - 1; i >= 0; i--)
            {
                if (ranges[i].Start.Value >= lengths[i])
                {
                    ranges[i] = 0..1;
                    if (i == 0)
                        return false;
                    ranges[i - 1] = new NRange(ranges[i - 1].Start.Value + 1, ranges[i - 1].End.Value + 1);
                }
            }
            return true;
        }
 
        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 Create
        /// <inheritdoc cref="ITensor{TSelf, T}.Create(ReadOnlySpan{nint}, bool)" />
        /// <returns>A new tensor with the specified lengths.</returns>
        public static Tensor<T> Create<T>(scoped ReadOnlySpan<nint> lengths, bool pinned = false)
            => new Tensor<T>(lengths, strides: [], pinned);
 
        /// <inheritdoc cref="ITensor{TSelf, T}.Create(ReadOnlySpan{nint}, ReadOnlySpan{nint}, bool)" />
        /// <returns>A new tensor with the specified <paramref name="lengths" /> and <paramref name="strides" />.</returns>
        public static Tensor<T> Create<T>(scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool pinned = false)
            => new Tensor<T>(lengths, strides, pinned);
 
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[])" />
        /// <returns>A new tensor that uses <paramref name="array" /> as its backing buffer.</returns>
        public static Tensor<T> Create<T>(T[] array)
            => new Tensor<T>(array);
 
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[], ReadOnlySpan{nint})" />
        /// <returns>A new tensor that uses <paramref name="array" /> as its backing buffer and with the specified <paramref name="lengths" />.</returns>
        public static Tensor<T> Create<T>(T[] array, scoped ReadOnlySpan<nint> lengths)
            => new Tensor<T>(array, lengths);
 
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[], ReadOnlySpan{nint}, ReadOnlySpan{nint})" />
        /// <returns>A new tensor that uses <paramref name="array" /> as its backing buffer and with the specified <paramref name="lengths" /> and <paramref name="strides"/>.</returns>
        public static Tensor<T> Create<T>(T[] array, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides)
            => new Tensor<T>(array, lengths, strides);
 
        /// <inheritdoc cref="ReadOnlyTensorSpan{T}.ReadOnlyTensorSpan(T[], int, ReadOnlySpan{nint}, ReadOnlySpan{nint})" />
        /// <returns>A new tensor that uses <paramref name="array" /> as its backing buffer and with the specified <paramref name="lengths" /> and <paramref name="strides" />.</returns>
        public static Tensor<T> Create<T>(T[] array, int start, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides)
            => new Tensor<T>(array, start, lengths, strides);
 
        /// <returns>A new tensor that contains elements copied from <paramref name="enumerable" />.</returns>
        public static Tensor<T> Create<T>(IEnumerable<T> enumerable, bool pinned = false)
        {
            T[] array = enumerable.ToArray();
 
            if (pinned)
            {
                Tensor<T> tensor = CreateUninitialized<T>([array.Length], pinned);
                array.CopyTo(tensor._values);
 
                return tensor;
            }
            else
            {
                return Create(array);
            }
        }
 
        /// <inheritdoc cref="Create{T}(IEnumerable{T}, ReadOnlySpan{nint}, bool)" />
        /// <returns>A new tensor that contains elements copied from <paramref name="enumerable" /> and with the specified <paramref name="lengths" />.</returns>
        public static Tensor<T> Create<T>(IEnumerable<T> enumerable, scoped ReadOnlySpan<nint> lengths, bool pinned = false)
            => Create(enumerable, lengths, strides: [], pinned);
 
        /// <inheritdoc cref="Create{T}(IEnumerable{T}, ReadOnlySpan{nint}, ReadOnlySpan{nint}, bool)" />
        /// <returns>A new tensor that contains elements copied from <paramref name="enumerable" /> and with the specified <paramref name="lengths" /> and <paramref name="strides" />.</returns>
        public static Tensor<T> Create<T>(IEnumerable<T> enumerable, scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool pinned = false)
        {
            T[] array = enumerable.ToArray();
 
            if (pinned)
            {
                Tensor<T> tensor = CreateUninitialized<T>(lengths, strides, pinned);
                array.CopyTo(tensor._values);
 
                return tensor;
            }
            else
            {
                return Create(array, lengths, strides);
            }
        }
 
        /// <summary>
        /// Creates a <see cref="Tensor{T}"/> and initializes it with random data in a gaussian normal distribution.
        /// </summary>
        /// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
        public static Tensor<T> CreateAndFillGaussianNormalDistribution<T>(scoped ReadOnlySpan<nint> lengths)
            where T : IFloatingPoint<T>
        {
            return CreateAndFillGaussianNormalDistribution<T>(Random.Shared, lengths);
        }
 
        /// <summary>
        /// Creates a <see cref="Tensor{T}"/> and initializes it with random data in a gaussian normal distribution.
        /// </summary>
        /// <param name="random"></param>
        /// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
        public static Tensor<T> CreateAndFillGaussianNormalDistribution<T>(Random random, scoped ReadOnlySpan<nint> lengths)
            where T : IFloatingPoint<T>
        {
            Tensor<T> tensor = CreateUninitialized<T>(lengths);
            FillGaussianNormalDistribution<T>(tensor, random);
            return tensor;
        }
 
 
        /// <summary>
        /// Creates a <see cref="Tensor{T}"/> and initializes it with random data uniformly distributed.
        /// </summary>
        /// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
        public static Tensor<T> CreateAndFillUniformDistribution<T>(scoped ReadOnlySpan<nint> lengths)
            where T : IFloatingPoint<T>
        {
            return CreateAndFillUniformDistribution<T>(Random.Shared, lengths);
        }
 
        /// <summary>
        /// Creates a <see cref="Tensor{T}"/> and initializes it with random data uniformly distributed.
        /// </summary>
        /// <param name="random"></param>
        /// <param name="lengths">A <see cref="ReadOnlySpan{T}"/> indicating the lengths of each dimension.</param>
        public static Tensor<T> CreateAndFillUniformDistribution<T>(Random random, scoped ReadOnlySpan<nint> lengths)
            where T : IFloatingPoint<T>
        {
            Tensor<T> tensor = CreateUninitialized<T>(lengths);
            FillUniformDistribution<T>(tensor, random);
            return tensor;
        }
 
        /// <inheritdoc cref="ITensor{TSelf, T}.CreateUninitialized(ReadOnlySpan{nint}, bool)" />
        public static Tensor<T> CreateUninitialized<T>(scoped ReadOnlySpan<nint> lengths, bool pinned = false)
        {
            TensorShape shape = TensorShape.Create(lengths, strides: []);
            T[] array = GC.AllocateUninitializedArray<T>(checked((int)(shape.LinearLength)), pinned);
            return new Tensor<T>(array, in shape, pinned);
        }
 
        /// <inheritdoc cref="ITensor{TSelf, T}.CreateUninitialized(ReadOnlySpan{nint}, ReadOnlySpan{nint}, bool)" />
        public static Tensor<T> CreateUninitialized<T>(scoped ReadOnlySpan<nint> lengths, scoped ReadOnlySpan<nint> strides, bool pinned = false)
        {
            TensorShape shape = TensorShape.Create(lengths, strides);
            T[] values = GC.AllocateUninitializedArray<T>(checked((int)(shape.LinearLength)), pinned);
            return new Tensor<T>(values, in shape, pinned);
        }
        #endregion
 
        #region Fill
        /// <summary>
        /// Fills the given <see cref="TensorSpan{T}"/> with random data in a Gaussian normal distribution. <see cref="System.Random"/>
        /// can optionally be provided for seeding.
        /// </summary>
        /// <typeparam name="T">The element type.</typeparam>
        /// <param name="destination">The destination <see cref="TensorSpan{T}"/> where the data will be stored.</param>
        /// <param name="random"><see cref="System.Random"/> to provide random seeding. Defaults to <see cref="Random.Shared"/> if not provided.</param>
        /// <returns></returns>
        public static ref readonly TensorSpan<T> FillGaussianNormalDistribution<T>(in TensorSpan<T> destination, Random? random = null) where T : IFloatingPoint<T>
        {
            Span<T> span = MemoryMarshal.CreateSpan<T>(ref destination._reference, (int)destination._shape.LinearLength);
            random ??= Random.Shared;
 
            for (int i = 0; i < span.Length; i++)
            {
                double u1 = 1.0 - random.NextDouble();
                double u2 = 1.0 - random.NextDouble();
                span[i] = T.CreateChecked(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2));
            }
 
            return ref destination;
        }
 
        /// <summary>
        /// Fills the given <see cref="TensorSpan{T}"/> with random data in a uniform distribution. <see cref="System.Random"/>
        /// can optionally be provided for seeding.
        /// </summary>
        /// <typeparam name="T">The element type.</typeparam>
        /// <param name="destination">The destination <see cref="TensorSpan{T}"/> where the data will be stored.</param>
        /// <param name="random"><see cref="System.Random"/> to provide random seeding. Defaults to <see cref="Random.Shared"/> if not provided.</param>
        /// <returns></returns>
        public static ref readonly TensorSpan<T> FillUniformDistribution<T>(in TensorSpan<T> destination, Random? random = null) where T : IFloatingPoint<T>
        {
            Span<T> span = MemoryMarshal.CreateSpan<T>(ref destination._reference, (int)destination._shape.LinearLength);
            random ??= Random.Shared;
            for (int i = 0; i < span.Length; i++)
                span[i] = T.CreateChecked(random.NextDouble());
 
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<bool> destination);
            TensorOperation.Invoke<TensorOperation.Equals<T>, T, bool>(x, y, destination);
            return 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 <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Equals<T>, T, bool>(x, y, destination);
            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> destination = CreateUninitialized<bool>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Equals<T>, T, bool>(x, y, destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Equals<T>, T, bool>(x, y, destination);
            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>
        {
            TensorOperation.ValidateCompatibility(x, y);
            return TensorOperation.Invoke<TensorOperation.Equals<T>, T>(x, y);
        }
 
        /// <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> => TensorOperation.Invoke<TensorOperation.Equals<T>, T>(x, y);
        #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>
        {
            // The main loop early exits at the first false condition, so the TensorOperation
            // checks x != y and returns false on first equal. This means we want to negate
            // whatever the main loop returns as `true` means none are equal.
 
            TensorOperation.ValidateCompatibility(x, y);
            return !TensorOperation.Invoke<TensorOperation.EqualsAny<T>, T>(x, y);
        }
 
        /// <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> => !TensorOperation.Invoke<TensorOperation.EqualsAny<T>, T>(x, y);
        #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)
        {
            TensorOperation.ValidateCompatibility(filter, tensor);
            TensorOperation.Invoke<TensorOperation.FilteredUpdate<T>, bool, T, T>(filter, value, tensor);
            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)
        {
            TensorOperation.ValidateCompatibility(filter, values, tensor);
            TensorOperation.Invoke<TensorOperation.FilteredUpdate<T>, bool, T, T>(filter, values, tensor);
            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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<bool> destination);
            TensorOperation.Invoke<TensorOperation.GreaterThan<T>, T, bool>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.GreaterThan<T>, T, bool>(x, y, destination);
            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> destination = Tensor.Create<bool>(x.Lengths, false);
            GreaterThan(x, y, destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.GreaterThan<T>, T, bool>(x, y, destination);
            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> => LessThan(y, x);
 
        /// <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> => ref LessThan(y, x, destination);
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y);
            return TensorOperation.Invoke<TensorOperation.GreaterThan<T>, T>(x, y);
        }
 
        /// <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> => TensorOperation.Invoke<TensorOperation.GreaterThan<T>, T>(x, y);
 
        /// <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> => LessThanAll(y, x);
        #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>
        {
            // The main loop early exits at the first false condition, so the TensorOperation
            // checks !(x > y) and returns false on first equal. This means we want to negate
            // whatever the main loop returns as `true` means none are equal.
 
            TensorOperation.ValidateCompatibility(x, y);
            return !TensorOperation.Invoke<TensorOperation.GreaterThanAny<T>, T>(x, y);
        }
 
        /// <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> => !TensorOperation.Invoke<TensorOperation.GreaterThanAny<T>, T>(x, y);
 
        /// <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> => LessThanAny(y, x);
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<bool> destination);
            TensorOperation.Invoke<TensorOperation.GreaterThanOrEqual<T>, T, bool>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.GreaterThanOrEqual<T>, T, bool>(x, y, destination);
            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> destination = Tensor.Create<bool>(x.Lengths, false);
            GreaterThanOrEqual(x, y, destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.GreaterThanOrEqual<T>, T, bool>(x, y, destination);
            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> => LessThanOrEqual(y, x);
 
        /// <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> => ref LessThanOrEqual(y, x, destination);
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y);
            return TensorOperation.Invoke<TensorOperation.GreaterThanOrEqual<T>, T>(x, y);
        }
 
        /// <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> => TensorOperation.Invoke<TensorOperation.GreaterThanOrEqual<T>, T>(x, y);
 
        /// <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> => LessThanOrEqualAll(y, x);
        #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>
        {
            // The main loop early exits at the first false condition, so the TensorOperation
            // checks !(x >= y) and returns false on first equal. This means we want to negate
            // whatever the main loop returns as `true` means none are equal.
 
            TensorOperation.ValidateCompatibility(x, y);
            return !TensorOperation.Invoke<TensorOperation.GreaterThanOrEqualAny<T>, T>(x, y);
        }
 
        /// <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> => !TensorOperation.Invoke<TensorOperation.GreaterThanOrEqualAny<T>, T>(x, y);
 
        /// <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> => LessThanOrEqualAny(y, x);
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<bool> destination);
            TensorOperation.Invoke<TensorOperation.LessThan<T>, T, bool>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.LessThan<T>, T, bool>(x, y, destination);
            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> destination = Tensor.Create<bool>(x.Lengths, false);
            LessThan(x, y, destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.LessThan<T>, T, bool>(x, y, destination);
            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> => GreaterThan(y, x);
 
        /// <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> => ref GreaterThan(y, x, destination);
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y);
            return TensorOperation.Invoke<TensorOperation.LessThan<T>, T>(x, y);
        }
 
        /// <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> => TensorOperation.Invoke<TensorOperation.LessThan<T>, T>(x, y);
 
        /// <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> => GreaterThanAll(y, x);
        #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>
        {
            // The main loop early exits at the first false condition, so the TensorOperation
            // checks !(x < y) and returns false on first equal. This means we want to negate
            // whatever the main loop returns as `true` means none are equal.
 
            TensorOperation.ValidateCompatibility(x, y);
            return !TensorOperation.Invoke<TensorOperation.LessThanAny<T>, T>(x, y);
        }
 
        /// <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> => !TensorOperation.Invoke<TensorOperation.LessThanAny<T>, T>(x, y);
 
        /// <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> => GreaterThanAny(y, x);
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<bool> destination);
            TensorOperation.Invoke<TensorOperation.LessThanOrEqual<T>, T, bool>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.LessThanOrEqual<T>, T, bool>(x, y, destination);
            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> destination = Tensor.Create<bool>(x.Lengths, false);
            LessThanOrEqual(x, y, destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.LessThanOrEqual<T>, T, bool>(x, y, destination);
            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> => GreaterThanOrEqual(y, x);
 
        /// <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> => ref GreaterThanOrEqual(y, x, destination);
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y);
            return TensorOperation.Invoke<TensorOperation.LessThanOrEqual<T>, T>(x, y);
        }
 
        /// <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> => TensorOperation.Invoke<TensorOperation.LessThanOrEqual<T>, T>(x, y);
 
        /// <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> => GreaterThanOrEqualAll(y, x);
        #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>
        {
            // The main loop early exits at the first false condition, so the TensorOperation
            // checks !(x <= y) and returns false on first equal. This means we want to negate
            // whatever the main loop returns as `true` means none are equal.
 
            TensorOperation.ValidateCompatibility(x, y);
            return !TensorOperation.Invoke<TensorOperation.LessThanOrEqualAny<T>, T>(x, y);
        }
 
        /// <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> => !TensorOperation.Invoke<TensorOperation.LessThanOrEqualAny<T>, T>(x, y);
 
        /// <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> => GreaterThanOrEqualAny(y, x);
        #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, ReadOnlySpan<int> dimensions)
        {
            if (tensor.Rank == 1)
            {
                return tensor;
            }
            else
            {
                if (!dimensions.IsEmpty && dimensions.Length != tensor.Lengths.Length)
                    ThrowHelper.ThrowArgument_PermuteAxisOrder();
 
                scoped Span<nint> newLengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
                scoped Span<nint> newStrides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
                scoped Span<int> newLinearOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<int> linearOrderRentedBuffer);
 
                Tensor<T> outTensor;
 
                if (dimensions.IsEmpty)
                {
                    for (int i = 0; i < tensor.Rank; i++)
                    {
                        newLengths[i] = tensor.Lengths[tensor.Rank - 1 - i];
                        newStrides[i] = tensor.Strides[tensor.Rank - 1 - i];
                        newLinearOrder[i] = tensor._shape.LinearRankOrder[tensor.Rank - 1 - i];
                    }
                }
                else
                {
                    for (int i = 0; i < dimensions.Length; i++)
                    {
                        if (dimensions[i] >= tensor.Lengths.Length || dimensions[i] < 0)
                        {
                            ThrowHelper.ThrowArgument_InvalidDimension();
                        }
                        newLengths[i] = tensor.Lengths[dimensions[i]];
                        newStrides[i] = tensor.Strides[dimensions[i]];
                        newLinearOrder[i] = tensor._shape.LinearRankOrder[dimensions[i]];
                    }
                }
                outTensor = new Tensor<T>(tensor._values, tensor._start, newLengths, newStrides, newLinearOrder);
 
                lengthsRentedBuffer.Dispose();
                stridesRentedBuffer.Dispose();
                linearOrderRentedBuffer.Dispose();
 
                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, ReadOnlySpan<nint> lengths)
        {
            if (tensor.Lengths.SequenceEqual(lengths))
                return tensor;
 
            if (!tensor.IsContiguousAndDense && !tensor.Strides.Contains(0))
            {
                ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense();
            }
 
            nint[] newLengths = lengths.ToArray();
            // Calculate wildcard info.
            int wildcardIndex = lengths.IndexOf(-1);
            if (wildcardIndex >= 0)
            {
                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];
                    }
                }
                newLengths[wildcardIndex] = tempTotal;
            }
 
            nint tempLinear = TensorPrimitives.Product(newLengths);
            if (tempLinear != tensor.FlattenedLength)
                ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
 
            nint[] strides;
 
            // If all our strides are 0 we can reshape however we like and keep all new strides at 0
            if (!tensor.Strides.ContainsAnyExcept(0))
            {
                strides = new nint[newLengths.Length];
            }
            // If we contain a 0 stride we can only add dimensions of length 1.
            else if (tensor.Strides.Contains(0))
            {
                List<nint> origStrides = new List<nint>(tensor.Strides.ToArray());
                int lengthOffset = 0;
                for (int i = 0; i < newLengths.Length; i++)
                {
                    if (lengthOffset < tensor.Rank && newLengths[i] == tensor.Lengths[lengthOffset])
                        lengthOffset++;
                    else if (newLengths[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 = [];
 
            return new Tensor<T>(tensor._values, tensor._start, lengths, 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, scoped ReadOnlySpan<nint> lengths)
        {
            if (tensor.Lengths.SequenceEqual(lengths))
                return tensor;
 
            if (!tensor.IsContiguousAndDense && !tensor.Strides.Contains(0))
            {
                ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense();
            }
 
            nint[] newLengths = lengths.ToArray();
            int wildcardIndex = lengths.IndexOf(-1);
            if (wildcardIndex >= 0)
            {
                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];
                    }
                }
                newLengths[wildcardIndex] = tempTotal;
 
            }
 
            nint tempLinear = TensorPrimitives.Product(newLengths);
            if (tempLinear != tensor.FlattenedLength)
                ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
 
            nint[] strides;
 
            // If all our strides are 0 we can reshape however we like and keep all new strides at 0
            if (!tensor.Strides.ContainsAnyExcept(0))
            {
                strides = new nint[newLengths.Length];
            }
            // If we contain a 0 stride we can only add dimensions of length 1.
            else if (tensor.Strides.Contains(0))
            {
                List<nint> origStrides = new List<nint>(tensor.Strides.ToArray());
                int lengthOffset = 0;
                for (int i = 0; i < newLengths.Length; i++)
                {
                    if (lengthOffset < tensor.Rank && newLengths[i] == tensor.Lengths[lengthOffset])
                    {
                        lengthOffset++;
                    }
                    else if (newLengths[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 = [];
 
            TensorSpan<T> output = new TensorSpan<T>(ref tensor._reference, tensor._shape.LinearLength, newLengths, strides);
            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, scoped ReadOnlySpan<nint> lengths)
        {
            if (tensor.Lengths.SequenceEqual(lengths))
                return tensor;
 
            if (!tensor.IsContiguousAndDense && !tensor.Strides.Contains(0))
            {
                ThrowHelper.ThrowArgument_CannotReshapeNonContiguousOrDense();
            }
 
            nint[] newLengths = lengths.ToArray();
            // Calculate wildcard info.
            int wildcardIndex = lengths.IndexOf(-1);
            if (wildcardIndex >= 0)
            {
                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];
                    }
                }
                newLengths[wildcardIndex] = tempTotal;
 
            }
 
            nint tempLinear = TensorPrimitives.Product(newLengths);
            if (tempLinear != tensor.FlattenedLength)
                ThrowHelper.ThrowArgument_InvalidReshapeDimensions();
 
            nint[] strides;
 
            // If all our strides are 0 we can reshape however we like and keep all new strides at 0
            if (!tensor.Strides.ContainsAnyExcept(0))
            {
                strides = new nint[newLengths.Length];
            }
            // If we contain a 0 stride we can only add dimensions of length 1.
            else if (tensor.Strides.Contains(0))
            {
                List<nint> origStrides = new List<nint>(tensor.Strides.ToArray());
                int lengthOffset = 0;
                for (int i = 0; i < newLengths.Length; i++)
                {
                    if (lengthOffset < tensor.Rank && newLengths[i] == tensor.Lengths[lengthOffset])
                        lengthOffset++;
                    else if (newLengths[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 = [];
 
            ReadOnlyTensorSpan<T> output = new ReadOnlyTensorSpan<T>(ref tensor._reference, tensor._shape.LinearLength, newLengths, strides);
            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 = TensorPrimitives.Product(lengths);
            T[] values = tensor.IsPinned ? GC.AllocateArray<T>((int)newSize) : (new T[newSize]);
            Tensor<T> output = Tensor.Create(values, 0, lengths, []);
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref Unsafe.Add(ref tensor.AsTensorSpan()._reference, tensor._start), (int)tensor._values.Length - tensor._start);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref output.AsTensorSpan()._reference, (int)output.FlattenedLength);
            if (newSize >= span.Length)
                span.CopyTo(ospan);
            else
                span.Slice(0, ospan.Length).CopyTo(ospan);
 
            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)
        {
            ResizeTo(tensor.AsReadOnlyTensorSpan(), destination);
        }
 
        /// <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)
        {
            ResizeTo(tensor.AsReadOnlyTensorSpan(), destination);
        }
 
        /// <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.LinearLength);
            Span<T> ospan = MemoryMarshal.CreateSpan(ref destination._reference, (int)destination._shape.LinearLength);
            if (ospan.Length >= span.Length)
                span.CopyTo(ospan);
            else
                span.Slice(0, ospan.Length).CopyTo(ospan);
        }
        #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)
        {
            // When the dimension is -1, its just a straight reverse copy.
            if (dimension == -1)
            {
                TensorOperation.ValidateCompatibility(tensor, destination);
                TensorOperation.ReverseInvoke<TensorOperation.CopyTo<T>, T, T>(tensor, destination);
            }
            // With any other dimension, we need to copy the data in reverse order based on the provided dimension.
            else
            {
                TensorOperation.ValidateCompatibility(tensor, destination);
                Span<NRange> srcIndexes = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<NRange> srcIndexesRentedBuffer);
                Span<NRange> dstIndexes = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<NRange> dstIndexesRentedBuffer);
 
                for (int i = 0; i < srcIndexes.Length; i++)
                {
                    srcIndexes[i] = NRange.All;
                    dstIndexes[i] = NRange.All;
                }
 
                for (int i = (int)tensor.Lengths[dimension]; i > 0; i--)
                {
                    srcIndexes[dimension] = new NRange(i - 1, i);
                    dstIndexes[dimension] = new NRange(tensor.Lengths[dimension] - i, tensor.Lengths[dimension] - i + 1);
                    TensorOperation.Invoke<TensorOperation.CopyTo<T>, T, T>(tensor.Slice(srcIndexes), destination.Slice(dstIndexes));
                }
                srcIndexesRentedBuffer.Dispose();
                dstIndexesRentedBuffer.Dispose();
            }
 
            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.LinearLength == other._shape.LinearLength
                && tensor.Lengths.SequenceEqual(other.Lengths)
                && MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape.LinearLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape.LinearLength));
        }
 
        /// <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.LinearLength == other._shape.LinearLength
                && tensor.Lengths.SequenceEqual(other.Lengths)
                && MemoryMarshal.CreateReadOnlySpan(in tensor.GetPinnableReference(), (int)tensor._shape.LinearLength).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(in other.GetPinnableReference(), (int)other._shape.LinearLength));
        }
        #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)
        {
            tensor.AsTensorSpan().SetSlice(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)
        {
            if (ranges.IsEmpty)
            {
                values.CopyTo(tensor);
            }
            else
            {
                values.CopyTo(tensor.Slice(ranges));
            }
            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 (dimension < 0 || dimension >= tensor.Rank)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
            if (tensor.Lengths[(int)dimension] % splitCount != 0)
                ThrowHelper.ThrowArgument_SplitNotSplitEvenly();
 
            Tensor<T>[] outputs = new Tensor<T>[splitCount];
 
            nint totalToCopy = tensor.FlattenedLength / splitCount;
 
            nint[] newShape = tensor.Lengths.ToArray();
            nint splitLength = newShape[dimension] / splitCount;
            newShape[dimension] = splitLength;
 
            scoped Span<NRange> sliceDims = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<NRange> lengthsRentedBuffer);
            for (int i = 0; i < sliceDims.Length; i++)
            {
                sliceDims[i] = NRange.All;
            }
            nint start = 0;
            for (int i = 0; i < outputs.Length; i++)
            {
                sliceDims[(int)dimension] = new NRange(start, start + splitLength);
                T[] values = new T[(int)totalToCopy];
                outputs[i] = new Tensor<T>(values, 0, newShape, [], tensor._shape.LinearRankOrder);
 
                tensor.Slice(sliceDims).CopyTo(outputs[i]);
                start += splitLength;
            }
 
            lengthsRentedBuffer.Dispose();
            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 || dimension < -1)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            scoped Span<nint> lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
            scoped Span<nint> strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
            scoped Span<int> strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<int> stridesOrderRentedBuffer);
            int newRank = 0;
            int index = 0;
 
            if (dimension == -1)
            {
                int removalCount = tensor.Lengths.Count(1);
                int removedIndex = 0;
                Span<int> removed = TensorOperation.RentedBuffer.CreateUninitialized(removalCount, out TensorOperation.RentedBuffer<int> removedRentedBuffer);
 
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (tensor.Lengths[i] != 1)
                    {
                        lengths[index] = tensor.Lengths[i];
                        strides[index] = tensor.Strides[i];
                        newRank++;
                        strideOrder[index++] = tensor._shape.LinearRankOrder[i];
                    }
                    else
                    {
                        removed[removedIndex++] = tensor._shape.LinearRankOrder[i];
                    }
                }
                SqueezeHelper(removed, strideOrder);
                removedRentedBuffer.Dispose();
            }
            else
            {
                if (tensor.Lengths[dimension] != 1)
                {
                    ThrowHelper.ThrowArgument_InvalidSqueezeAxis();
                }
                int removed = default;
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (i != dimension)
                    {
                        lengths[index] = tensor.Lengths[i];
                        strides[index] = tensor.Strides[i];
                        newRank++;
                        strideOrder[index++] = tensor._shape.LinearRankOrder[i];
                    }
                    else
                    {
                        removed = tensor._shape.LinearRankOrder[i];
                    }
                }
                SqueezeHelper(removed, strideOrder);
            }
 
            Tensor<T> output = new Tensor<T>(tensor._values, tensor._start, lengths[..newRank], strides[..newRank], strideOrder[..newRank]);
 
            lengthsRentedBuffer.Dispose();
            stridesRentedBuffer.Dispose();
            stridesOrderRentedBuffer.Dispose();
 
            return output;
        }
 
        /// <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 || dimension < -1)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            scoped Span<nint> lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
            scoped Span<nint> strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
            scoped Span<int> strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<int> stridesOrderRentedBuffer);
            int newRank = 0;
            int index = 0;
 
            if (dimension == -1)
            {
                int removalCount = tensor.Lengths.Count(1);
                int removedIndex = 0;
                Span<int> removed = TensorOperation.RentedBuffer.CreateUninitialized(removalCount, out TensorOperation.RentedBuffer<int> removedRentedBuffer);
 
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (tensor.Lengths[i] != 1)
                    {
                        lengths[index] = tensor.Lengths[i];
                        strides[index] = tensor.Strides[i];
                        newRank++;
                        strideOrder[index++] = tensor._shape.LinearRankOrder[i];
                    }
                    else
                    {
                        removed[removedIndex++] = tensor._shape.LinearRankOrder[i];
                    }
                }
                SqueezeHelper(removed, strideOrder);
                removedRentedBuffer.Dispose();
            }
            else
            {
                if (tensor.Lengths[dimension] != 1)
                {
                    ThrowHelper.ThrowArgument_InvalidSqueezeAxis();
                }
                int removed = default;
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (i != dimension)
                    {
                        lengths[index] = tensor.Lengths[i];
                        strides[index] = tensor.Strides[i];
                        newRank++;
                        strideOrder[index++] = tensor._shape.LinearRankOrder[i];
                    }
                    else
                    {
                        removed = tensor._shape.LinearRankOrder[i];
                    }
                }
                SqueezeHelper(removed, strideOrder);
            }
 
            TensorSpan<T> output = new TensorSpan<T>(ref tensor._reference, tensor._shape.LinearLength, lengths[..newRank], strides[..newRank], strideOrder[..newRank]);
 
            lengthsRentedBuffer.Dispose();
            stridesRentedBuffer.Dispose();
            stridesOrderRentedBuffer.Dispose();
 
            return output;
        }
 
        /// <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 || dimension < -1)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            scoped Span<nint> lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
            scoped Span<nint> strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
            scoped Span<int> strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<int> stridesOrderRentedBuffer);
            int newRank = 0;
            int index = 0;
 
            if (dimension == -1)
            {
                int removalCount = tensor.Lengths.Count(1);
                int removedIndex = 0;
                Span<int> removed = TensorOperation.RentedBuffer.CreateUninitialized(removalCount, out TensorOperation.RentedBuffer<int> removedRentedBuffer);
 
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (tensor.Lengths[i] != 1)
                    {
                        lengths[index] = tensor.Lengths[i];
                        strides[index] = tensor.Strides[i];
                        newRank++;
                        strideOrder[index++] = tensor._shape.LinearRankOrder[i];
                    }
                    else
                    {
                        removed[removedIndex++] = tensor._shape.LinearRankOrder[i];
                    }
                }
                SqueezeHelper(removed, strideOrder);
                removedRentedBuffer.Dispose();
            }
            else
            {
                if (tensor.Lengths[dimension] != 1)
                {
                    ThrowHelper.ThrowArgument_InvalidSqueezeAxis();
                }
                int removed = default;
                for (int i = 0; i < tensor.Lengths.Length; i++)
                {
                    if (i != dimension)
                    {
                        lengths[index] = tensor.Lengths[i];
                        strides[index] = tensor.Strides[i];
                        newRank++;
                        strideOrder[index++] = tensor._shape.LinearRankOrder[i];
                    }
                    else
                    {
                        removed = tensor._shape.LinearRankOrder[i];
                    }
                }
                SqueezeHelper(removed, strideOrder);
            }
 
            ReadOnlyTensorSpan<T> output =  new ReadOnlyTensorSpan<T>(ref tensor._reference, tensor._shape.LinearLength, lengths[..newRank], strides[..newRank], strideOrder[..newRank]);
 
            lengthsRentedBuffer.Dispose();
            stridesRentedBuffer.Dispose();
            stridesOrderRentedBuffer.Dispose();
 
            return output;
        }
 
        internal static void SqueezeHelper(scoped in Span<int> removed, scoped in Span<int> strideOrder)
        {
            for (int i = 0; i < strideOrder.Length; i++)
            {
                for (int j = removed.Length - 1; j >= 0; j--)
                {
                    if (strideOrder[i] > removed[j])
                    {
                        strideOrder[i]--;
                    }
                }
            }
        }
 
        internal static void SqueezeHelper(int removed, scoped in Span<int> strideOrder)
        {
            for (int i = 0; i < strideOrder.Length; i++)
            {
                if (strideOrder[i] > removed)
                {
                    strideOrder[i]--;
                }
            }
        }
        #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 (!tensors[0].Lengths.SequenceEqual(tensors[i].Lengths))
                    ThrowHelper.ThrowArgument_StackShapesNotSame();
            }
 
            // We are safe to do dimension > tensors[0].Rank instead of >= because we are adding a new dimension
            // with our call to Unsqueeze.
            if (dimension < 0 || dimension > tensors[0].Rank)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            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 (!tensors[0].Lengths.SequenceEqual(tensors[i].Lengths))
                    ThrowHelper.ThrowArgument_StackShapesNotSame();
            }
 
            // We are safe to do dimension > tensors[0].Rank instead of >= because we are adding a new dimension
            // with our call to Unsqueeze.
            if (dimension < 0 || dimension > tensors[0].Rank)
                ThrowHelper.ThrowArgument_AxisLargerThanRank();
 
            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, outputs, destination);
        }
        #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, ReadOnlySpan<nint> maximumLengths)
            => tensor.AsReadOnlyTensorSpan().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, ReadOnlySpan<nint> maximumLengths)
        {
            if (maximumLengths.Length != tensor.Rank)
            {
                ThrowHelper.ThrowArgument_DimensionsNotSame(nameof(tensor));
            }
 
            StringBuilder sb = new();
            ToString(in tensor, maximumLengths, sb);
            return sb.ToString();
        }
 
        internal static void ToString<T>(in ReadOnlyTensorSpan<T> tensor, ReadOnlySpan<nint> maximumLengths, StringBuilder sb, int indentLevel = 0)
        {
            Debug.Assert(maximumLengths.Length != tensor.Rank);
 
            sb.Append(' ', indentLevel * 2);
            sb.Append('[');
 
            if (tensor.Rank != 0)
            {
                nint length = nint.Max(tensor.Lengths[0], maximumLengths[0]);
 
                if (tensor.Rank != 1)
                {
                    string separator = string.Empty;
 
                    for (nint i = 0; i < length; i++)
                    {
                        sb.AppendLine(separator);
 
                        TensorShape tmpShape = TensorShape.Create(tensor.Lengths[1..], tensor.Strides[1..]);
                        ReadOnlyTensorSpan<T> tmpTensor = new ReadOnlyTensorSpan<T>(ref Unsafe.Add(ref tensor._reference, i * tensor.Strides[0]), tmpShape);
                        ToString(tmpTensor, maximumLengths[1..], sb, indentLevel + 1);
 
                        separator = ",";
                    }
 
                    if (length != tensor.Lengths[0])
                    {
                        sb.AppendLine(separator);
                        sb.Append(' ', indentLevel * 2);
                        sb.AppendLine("...");
                    }
                }
                else
                {
                    string separator = " ";
 
                    for (nint i = 0; i < length; i++)
                    {
                        sb.Append(separator);
                        sb.Append(Unsafe.Add(ref tensor._reference, i));
                        separator = ", ";
                    }
 
                    if (length != tensor.Lengths[0])
                    {
                        sb.Append(separator);
                        sb.Append("...");
                    }
 
                    sb.Append(separator);
                }
            }
            sb.Append(']');
        }
 
        /// <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, ReadOnlySpan<nint> maximumLengths)
            => tensor.AsReadOnlyTensorSpan().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();
 
            scoped Span<nint> lengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
            scoped Span<nint> strides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
            scoped Span<int> strideOrder = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank, out TensorOperation.RentedBuffer<int> stridesOrderRentedBuffer);
 
            tensor.Lengths.CopyTo(lengths);
            tensor.Strides.CopyTo(strides);
            tensor._shape.LinearRankOrder.CopyTo(strideOrder);
 
            nint temp = lengths[^1];
            lengths[^1] = lengths[^2];
            lengths[^2] = temp;
 
            temp = strides[^1];
            strides[^1] = strides[^2];
            strides[^2] = temp;
 
            int tempOrder = strideOrder[^1];
            strideOrder[^1] = strideOrder[^2];
            strideOrder[^2] = tempOrder;
 
            Tensor<T> output = new Tensor<T>(tensor._values, tensor._start, lengths, strides, strideOrder);
 
            lengthsRentedBuffer.Dispose();
            stridesRentedBuffer.Dispose();
            stridesOrderRentedBuffer.Dispose();
 
            return output;
        }
        #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 tensor.AsReadOnlyTensorSpan().TryBroadcastTo(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 tensor.AsReadOnlyTensorSpan().TryBroadcastTo(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)
        {
            TensorOperation.ValidateCompatibility(tensor, destination);
            if (!TensorShape.AreCompatible(destination._shape, tensor._shape, false))
                return false;
 
            BroadcastTo(tensor, 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;
 
            scoped Span<nint> newLengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank + 1, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
 
            tensor.Lengths.Slice(0, dimension).CopyTo(newLengths);
            tensor.Lengths.Slice(dimension).CopyTo(newLengths.Slice(dimension + 1));
            newLengths[dimension] = 1;
 
            Span<nint> newStrides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank + 1, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
            if (dimension == tensor.Rank)
            {
                tensor.Strides.CopyTo(newStrides);
                newStrides[dimension] = 0;
            }
            else
            {
                tensor.Strides.Slice(0, dimension).CopyTo(newStrides);
                tensor.Strides.Slice(dimension).CopyTo(newStrides.Slice(dimension + 1));
                newStrides[dimension] = 0;
            }
 
            Tensor<T> output = new Tensor<T>(tensor._values, tensor._start, newLengths, newStrides);
            lengthsRentedBuffer.Dispose();
            stridesRentedBuffer.Dispose();
            return output;
        }
 
        /// <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;
 
            scoped Span<nint> newLengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank + 1, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
 
            tensor.Lengths.Slice(0, dimension).CopyTo(newLengths);
            tensor.Lengths.Slice(dimension).CopyTo(newLengths.Slice(dimension + 1));
            newLengths[dimension] = 1;
 
            Span<nint> newStrides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank + 1, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
            if (dimension == tensor.Rank)
            {
                tensor.Strides.CopyTo(newStrides);
                newStrides[dimension] = 0;
            }
            else
            {
                tensor.Strides.Slice(0, dimension).CopyTo(newStrides);
                tensor.Strides.Slice(dimension).CopyTo(newStrides.Slice(dimension + 1));
                newStrides[dimension] = 0;
            }
 
            TensorSpan<T> output = new TensorSpan<T>(ref tensor._reference, tensor._shape.LinearLength, newLengths, newStrides);
            lengthsRentedBuffer.Dispose();
            stridesRentedBuffer.Dispose();
            return output;
        }
 
        /// <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;
 
            scoped Span<nint> newLengths = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank + 1, out TensorOperation.RentedBuffer<nint> lengthsRentedBuffer);
 
            tensor.Lengths.Slice(0, dimension).CopyTo(newLengths);
            tensor.Lengths.Slice(dimension).CopyTo(newLengths.Slice(dimension + 1));
            newLengths[dimension] = 1;
 
            Span<nint> newStrides = TensorOperation.RentedBuffer.CreateUninitialized(tensor.Rank + 1, out TensorOperation.RentedBuffer<nint> stridesRentedBuffer);
            if (dimension == tensor.Rank)
            {
                tensor.Strides.CopyTo(newStrides);
                newStrides[dimension] = 0;
            }
            else
            {
                tensor.Strides.Slice(0, dimension).CopyTo(newStrides);
                tensor.Strides.Slice(dimension).CopyTo(newStrides.Slice(dimension + 1));
                newStrides[dimension] = 0;
            }
 
            ReadOnlyTensorSpan<T> output = new ReadOnlyTensorSpan<T>(ref tensor._reference, tensor._shape.LinearLength, newLengths, newStrides);
            lengthsRentedBuffer.Dispose();
            stridesRentedBuffer.Dispose();
            return output;
        }
        #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> destination = CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Abs<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Abs<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Acos<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Acos<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Acosh<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Acosh<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.AcosPi<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.AcosPi<T>, T, T>(x, destination);
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Add<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Add<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Add<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Add<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Asin<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Asin<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Asinh<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Asinh<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.AsinPi<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.AsinPi<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Atan<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Atan<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Atan2<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Atan2<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Atan2<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Atan2<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(y.Lengths);
            TensorOperation.Invoke<TensorOperation.Atan2<T>, T, T>(y, x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.Atan2<T>, T, T>(y, x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Atan2Pi<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Atan2Pi<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Atan2Pi<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Atan2Pi<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(y.Lengths);
            TensorOperation.Invoke<TensorOperation.Atan2Pi<T>, T, T>(y, x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.Atan2Pi<T>, T, T>(y, x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Atanh<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Atanh<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.AtanPi<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.AtanPi<T>, T, T>(x, destination);
            return ref destination;
        }
        #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 : INumberBase<T>
        {
            // Get the flattenedLength first so we don't spend time computing if we'll fail due to overflow
 
            T flattenedLength = T.CreateChecked(x.FlattenedLength);
            T sum = Sum(x);
            return sum / flattenedLength;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.BitwiseAnd<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.BitwiseAnd<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.BitwiseAnd<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.BitwiseAnd<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.BitwiseOr<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.BitwiseOr<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.BitwiseOr<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.BitwiseOr<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Cbrt<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Cbrt<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Ceiling<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Ceiling<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<TTo>(source.Lengths);
            TensorOperation.Invoke<TensorOperation.ConvertChecked<TFrom, TTo>, TFrom, TTo>(source, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(source, destination);
            TensorOperation.Invoke<TensorOperation.ConvertChecked<TFrom, TTo>, TFrom, TTo>(source, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<TTo>(source.Lengths);
            TensorOperation.Invoke<TensorOperation.ConvertSaturating<TFrom, TTo>, TFrom, TTo>(source, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(source, destination);
            TensorOperation.Invoke<TensorOperation.ConvertSaturating<TFrom, TTo>, TFrom, TTo>(source, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<TTo>(source.Lengths);
            TensorOperation.Invoke<TensorOperation.ConvertTruncating<TFrom, TTo>, TFrom, TTo>(source, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(source, destination);
            TensorOperation.Invoke<TensorOperation.ConvertTruncating<TFrom, TTo>, TFrom, TTo>(source, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.CopySign<T>, T, T>(x, sign, destination);
            return destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.CopySign<T>, T, T>(x, sign, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.CopySign<T>, T, T>(x, sign, destination);
            return ref destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, sign, destination);
            TensorOperation.Invoke<TensorOperation.CopySign<T>, T, T>(x, sign, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Cos<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Cos<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Cosh<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Cosh<T>, T, T>(x, destination);
            return ref destination;
        }
        #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 T CosineSimilarity<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : IRootFunctions<T>
        {
            TensorOperation.ValidateCompatibility<T, T>(x, y);
            ValueTuple<T, T, T> result = (T.AdditiveIdentity, T.AdditiveIdentity, T.AdditiveIdentity);
            TensorOperation.Invoke<TensorOperation.CosineSimilarity<T>, T, ValueTuple<T, T, T>>(x, y, ref result);
            return result.Item1 / (T.Sqrt(result.Item2) * T.Sqrt(result.Item3));
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.CosPi<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.CosPi<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.DegreesToRadians<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.DegreesToRadians<T>, T, T>(x, destination);
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y);
            T result = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.SumOfSquaredDifferences<T>, T, T>(x, y, ref result);
            return T.Sqrt(result);
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(y.Lengths);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y);
            T result = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.Dot<T>, T, T>(x, y, ref result);
            return result;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Exp<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Exp<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Exp10<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Exp10<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Exp10M1<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Exp10M1<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Exp2<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Exp2<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Exp2M1<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Exp2M1<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.ExpM1<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.ExpM1<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Floor<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Floor<T>, T, T>(x, destination);
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Hypot<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Hypot<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Ieee754Remainder<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Ieee754Remainder<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Ieee754Remainder<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Ieee754Remainder<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(y.Lengths);
            TensorOperation.Invoke<TensorOperation.Ieee754Remainder<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.Ieee754Remainder<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<int>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.ILogB<T>, T, int>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.ILogB<T>, T, int>(x, destination);
            return ref destination;
        }
        #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 nint IndexOfMax<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
            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 nint IndexOfMaxMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
            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 nint IndexOfMin<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
            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 nint IndexOfMinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            ReadOnlySpan<T> span = MemoryMarshal.CreateSpan(ref x._reference, (int)x._shape.LinearLength);
            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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.LeadingZeroCount<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.LeadingZeroCount<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Log<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Log<T>, T, T>(x, destination);
            return ref destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Log<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Log<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Log<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Log<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Log10<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Log10<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Log10P1<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Log10P1<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Log2<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Log2<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Log2P1<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Log2P1<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.LogP1<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.LogP1<T>, T, T>(x, destination);
            return ref destination;
        }
        #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>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.Max<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> output);
            TensorOperation.Invoke<TensorOperation.Max<T>, T, T>(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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.Max<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Max<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.Max<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.MaxMagnitude<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.MaxMagnitude<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.MaxMagnitude<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.MaxMagnitude<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.MaxMagnitude<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.MaxMagnitudeNumber<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.MaxMagnitudeNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.MaxMagnitudeNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.MaxMagnitudeNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.MaxMagnitudeNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.MaxNumber<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.MaxNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.MaxNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.MaxNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.MaxNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #endregion
 
        #region Min
        /// <summary>Searches for the largest 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>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.Min<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> output);
            TensorOperation.Invoke<TensorOperation.Min<T>, T, T>(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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.Min<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Min<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.Min<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #endregion
 
        #region MinMagnitude
        /// <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 MinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.MinMagnitude<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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> MinMagnitude<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.MinMagnitude<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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> MinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.MinMagnitude<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> MinMagnitude<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.MinMagnitude<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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> MinMagnitude<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.MinMagnitude<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #endregion
 
        #region MinMagnitudeNumber
        /// <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 MinMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumberBase<T>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.MinMagnitudeNumber<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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> MinMagnitudeNumber<T>(in ReadOnlyTensorSpan<T> x, in ReadOnlyTensorSpan<T> y)
            where T : INumber<T>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.MinMagnitudeNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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> MinMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x, scoped in ReadOnlyTensorSpan<T> y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.MinMagnitudeNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> MinMagnitudeNumber<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : INumber<T>
        {
            Tensor<T> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.MinMagnitudeNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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> MinMagnitudeNumber<T>(scoped in ReadOnlyTensorSpan<T> x, T y, in TensorSpan<T> destination)
            where T : INumber<T>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.MinMagnitudeNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #endregion
 
        #region MinNumber
        /// <summary>Searches for the largest number in the specified tensor.</summary>
        /// <param name="x">The input <see cref="ReadOnlyTensorSpan{T}"/>..</param>
        public static T MinNumber<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : INumber<T>
        {
            if (x.IsEmpty)
            {
                ThrowHelper.ThrowArgument_SpansMustBeNonEmpty();
            }
 
            T result = x._reference;
            TensorOperation.Invoke<TensorOperation.MinNumber<T>, T, T>(x, ref result);
            return result;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.MinNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in y, in destination);
            TensorOperation.Invoke<TensorOperation.MinNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.MinNumber<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(in x, in destination);
            TensorOperation.Invoke<TensorOperation.MinNumber<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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> destination = Tensor.Create<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Multiply<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Multiply<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Multiply<T>, T, T>(x, y, destination);
            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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Multiply<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Negate<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Negate<T>, T, T>(x, destination);
            return ref destination;
        }
        #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>
        {
            T result = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.SumOfSquares<T>, T, T>(x, ref result);
            return T.Sqrt(result);
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.OnesComplement<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.OnesComplement<T>, T, T>(y, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.PopCount<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.PopCount<T>, T, T>(y, destination);
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Pow<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Pow<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Pow<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Pow<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(y.Lengths);
            TensorOperation.Invoke<TensorOperation.Pow<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.Pow<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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>
        {
            T destination = T.MultiplicativeIdentity;
            TensorOperation.Invoke<TensorOperation.Product<T>, T, T>(x, ref destination);
            return destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.RadiansToDegrees<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.RadiansToDegrees<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Reciprocal<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Reciprocal<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.RootN<T>, T, T>(x, n, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.RootN<T>, T, T>(x, n, destination);
            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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.RotateLeft<T>, T, T>(x, rotateAmount, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.RotateLeft<T>, T, T>(x, rotateAmount, destination);
            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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.RotateRight<T>, T, T>(x, rotateAmount, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.RotateRight<T>, T, T>(x, rotateAmount, destination);
            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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, T>(x, destination);
            return 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="destination"></param>
        public static ref readonly TensorSpan<T> Round<T>(scoped in ReadOnlyTensorSpan<T> x, in TensorSpan<T> destination)
            where T : IFloatingPoint<T>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, T>(x, destination);
            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>
        /// <param name="mode"></param>
        public static Tensor<T> Round<T>(in ReadOnlyTensorSpan<T> x, int digits, MidpointRounding mode)
            where T : IFloatingPoint<T>
        {
            Tensor<T> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, Tuple<int, MidpointRounding>, T>(x, Tuple.Create(digits, mode), destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, Tuple<int, MidpointRounding>, T>(x, Tuple.Create(digits, mode), in destination);
            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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, Tuple<int, MidpointRounding>, T>(x, Tuple.Create(digits, MidpointRounding.ToEven), destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, Tuple<int, MidpointRounding>, T>(x, Tuple.Create(digits, MidpointRounding.ToEven), in destination);
            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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, Tuple<int, MidpointRounding>, T>(x, Tuple.Create(0, mode), destination);
            return 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>
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Round<T>, T, Tuple<int, MidpointRounding>, T>(x, Tuple.Create(0, mode), in destination);
            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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Sigmoid<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Sigmoid<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Sin<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Sin<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Sinh<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Sinh<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.SinPi<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.SinPi<T>, T, T>(x, destination);
            return ref destination;
        }
        #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>
        {
            T sumExp = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.SumExp<T>, T, T>(x, ref sumExp);
 
            Tensor<T> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.SoftMax<T>, T, T>(x, sumExp, destination);
            return destination;
        }
 
        /// <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>
        {
            T sumExp = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.SumExp<T>, T, T>(x, ref sumExp);
 
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.SoftMax<T>, T, T>(x, sumExp, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Sqrt<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Sqrt<T>, T, T>(x, destination);
            return ref 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 : IRootFunctions<T>
        {
            T mean = Average(x);
            T result = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.SumOfSquaredDifferences<T>, T, T>(x, mean, ref result);
            T variance = result / T.CreateChecked(x.FlattenedLength);
            return T.Sqrt(variance);
 
        }
        #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> destination = CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Subtract<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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> destination = CreateUninitialized<T>(y.Lengths);
            TensorOperation.Invoke<TensorOperation.Subtract<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Subtract<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Subtract<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(y, destination);
            TensorOperation.Invoke<TensorOperation.Subtract<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Subtract<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #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>
        {
            T destination = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.Sum<T>, T, T>(x, ref destination);
            return destination;
        }
        #endregion
 
        #region SumOfSquares
        /// <summary>
        /// Sums the squared elements of the specified tensor.
        /// </summary>
        /// <param name="x">Tensor to sum squares of</param>
        /// <returns></returns>
        internal static T SumOfSquares<T>(scoped in ReadOnlyTensorSpan<T> x)
            where T : IAdditionOperators<T, T, T>, IAdditiveIdentity<T, T>, IMultiplyOperators<T, T, T>
        {
            T result = T.AdditiveIdentity;
            TensorOperation.Invoke<TensorOperation.SumOfSquares<T>, T, T>(x, ref result);
            return result;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Tan<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Tan<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Tanh<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Tanh<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.TanPi<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.TanPi<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.TrailingZeroCount<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.TrailingZeroCount<T>, T, T>(x, destination);
            return ref destination;
        }
        #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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Truncate<T>, T, T>(x, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Truncate<T>, T, T>(x, destination);
            return ref destination;
        }
        #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>
        {
            TensorOperation.ValidateCompatibility(x, y, out Tensor<T> destination);
            TensorOperation.Invoke<TensorOperation.Xor<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, y, destination);
            TensorOperation.Invoke<TensorOperation.Xor<T>, T, T>(x, y, destination);
            return ref destination;
        }
 
        /// <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> destination = Tensor.CreateUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Xor<T>, T, T>(x, y, destination);
            return destination;
        }
 
        /// <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>
        {
            TensorOperation.ValidateCompatibility(x, destination);
            TensorOperation.Invoke<TensorOperation.Xor<T>, T, T>(x, y, destination);
            return ref destination;
        }
        #endregion
        #endregion
    }
}