File: System\Numerics\Tensors\netcore\Tensor.op_Division.cs
Web Access
Project: src\runtime\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.

namespace System.Numerics.Tensors
{
    public static partial class Tensor
    {
        /// <summary>Performs element-wise division between two tensors.</summary>
        /// <typeparam name="T">The type of the elements in the tensor.</typeparam>
        /// <param name="x">The tensor dividend.</param>
        /// <param name="y">The tensor divisor.</param>
        /// <returns>A new tensor containing the result of <paramref name="x" /> / <paramref name="y" />.</returns>
        /// <exception cref="ArgumentException">The shapes of <paramref name="x" /> and <paramref name="y" /> are not compatible.</exception>
        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>Performs element-wise division between a tensor and scalar.</summary>
        /// <typeparam name="T">The type of the elements in the tensor.</typeparam>
        /// <param name="x">The tensor dividend.</param>
        /// <param name="y">The scalar divisor.</param>
        /// <returns>A new tensor containing the result of <paramref name="x" /> / <paramref name="y" />.</returns>
        public static Tensor<T> Divide<T>(in ReadOnlyTensorSpan<T> x, T y)
            where T : IDivisionOperators<T, T, T>
        {
            Tensor<T> destination = CreateFromShapeUninitialized<T>(x.Lengths);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return destination;
        }

        /// <summary>Performs element-wise division between a tensor and scalar.</summary>
        /// <typeparam name="T">The type of the elements in the tensor.</typeparam>
        /// <param name="x">The scalar dividend.</param>
        /// <param name="y">The tensor divisor.</param>
        /// <returns>A new tensor containing the result of <paramref name="x" /> / <paramref name="y" />.</returns>
        public static Tensor<T> Divide<T>(T x, in ReadOnlyTensorSpan<T> y)
            where T : IDivisionOperators<T, T, T>
        {
            Tensor<T> destination = CreateFromShapeUninitialized<T>(y.Lengths);
            TensorOperation.Invoke<TensorOperation.Divide<T>, T, T>(x, y, destination);
            return destination;
        }

        /// <summary>Performs element-wise division between two tensors.</summary>
        /// <typeparam name="T">The type of the elements in the tensor.</typeparam>
        /// <param name="x">The tensor dividend.</param>
        /// <param name="y">The tensor divisor.</param>
        /// <param name="destination">The destination where the result of <paramref name="x" /> / <paramref name="y" /> is written.</param>
        /// <returns>A reference to <paramref name="destination" />.</returns>
        /// <exception cref="ArgumentException">The shapes of <paramref name="x" />, <paramref name="y" />, and <paramref name="destination" /> are not compatible.</exception>
        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;
        }

        /// <summary>Performs element-wise division between a tensor and scalar.</summary>
        /// <typeparam name="T">The type of the elements in the tensor.</typeparam>
        /// <param name="x">The tensor dividend.</param>
        /// <param name="y">The scalar divisor.</param>
        /// <param name="destination">The destination where the result of <paramref name="x" /> / <paramref name="y" /> is written.</param>
        /// <returns>A reference to <paramref name="destination" />.</returns>
        /// <exception cref="ArgumentException">The shapes of <paramref name="x" /> and <paramref name="destination" /> are not compatible.</exception>
        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>Performs element-wise division between a tensor and scalar.</summary>
        /// <typeparam name="T">The type of the elements in the tensor.</typeparam>
        /// <param name="x">The scalar dividend.</param>
        /// <param name="y">The tensor divisor.</param>
        /// <param name="destination">The destination where the result of <paramref name="x" /> / <paramref name="y" /> is written.</param>
        /// <exception cref="ArgumentException">The shapes of <paramref name="y" /> and <paramref name="destination" /> are not compatible.</exception>
        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;
        }

        /// <typeparam name="TScalar">The type of the elements in the tensor.</typeparam>
        extension<TScalar>(ReadOnlyTensorSpan<TScalar>)
            where TScalar : IDivisionOperators<TScalar, TScalar, TScalar>
        {
            /// <summary>Performs element-wise division between two tensors.</summary>
            /// <param name="left">The tensor dividend.</param>
            /// <param name="right">The tensor divisor.</param>
            /// <returns>A new tensor containing the result of <paramref name="left" /> / <paramref name="right" />.</returns>
            /// <exception cref="ArgumentException">The shapes of <paramref name="left" /> and <paramref name="right" /> are not compatible.</exception>
            public static Tensor<TScalar> operator /(in ReadOnlyTensorSpan<TScalar> left, in ReadOnlyTensorSpan<TScalar> right) => Divide(left, right);

            /// <summary>Performs element-wise division between a tensor and scalar.</summary>
            /// <param name="left">The tensor dividend.</param>
            /// <param name="right">The scalar divisor.</param>
            /// <returns>A new tensor containing the result of <paramref name="left" /> / <paramref name="right" />.</returns>
            public static Tensor<TScalar> operator /(in ReadOnlyTensorSpan<TScalar> left, TScalar right) => Divide(left, right);

            /// <summary>Performs element-wise division between a tensor and scalar.</summary>
            /// <param name="left">The scalar dividend.</param>
            /// <param name="right">The tensor divisor.</param>
            /// <returns>A new tensor containing the result of <paramref name="left" /> / <paramref name="right" />.</returns>
            public static Tensor<TScalar> operator /(TScalar left, in ReadOnlyTensorSpan<TScalar> right) => Divide(left, right);
        }

        /// <typeparam name="TScalar">The type of the elements in the tensor.</typeparam>
        extension<TScalar>(Tensor<TScalar> tensor)
            where TScalar : IDivisionOperators<TScalar, TScalar, TScalar>
        {
            /// <inheritdoc cref="op_Division{T}(in ReadOnlyTensorSpan{T}, in ReadOnlyTensorSpan{T})" />
            public static Tensor<TScalar> operator /(Tensor<TScalar> left, Tensor<TScalar> right) => Divide<TScalar>(left, right);

            /// <inheritdoc cref="op_Division{T}(in ReadOnlyTensorSpan{T}, T)" />
            public static Tensor<TScalar> operator /(Tensor<TScalar> left, TScalar right) => Divide(left, right);

            /// <inheritdoc cref="op_Division{T}(T, in ReadOnlyTensorSpan{T})" />
            public static Tensor<TScalar> operator /(TScalar left, Tensor<TScalar> right) => Divide(left, right);

            /// <inheritdoc cref="op_DivisionAssignment{T}(ref TensorSpan{T}, in ReadOnlyTensorSpan{T})" />
            public void operator /=(in ReadOnlyTensorSpan<TScalar> other) => Divide(tensor, other, tensor);

            /// <inheritdoc cref="op_DivisionAssignment{T}(ref TensorSpan{T}, T)" />
            public void operator /=(TScalar other) => Divide(tensor, other, tensor);
        }

        /// <typeparam name="TScalar">The type of the elements in the tensor.</typeparam>
        /// <param name="tensor">The tensor to operate on.</param>
        extension<TScalar>(ref TensorSpan<TScalar> tensor)
            where TScalar : IDivisionOperators<TScalar, TScalar, TScalar>
        {
            /// <inheritdoc cref="op_Division{T}(in ReadOnlyTensorSpan{T}, in ReadOnlyTensorSpan{T})" />
            public static Tensor<TScalar> operator /(in TensorSpan<TScalar> left, in TensorSpan<TScalar> right) => Divide<TScalar>(left, right);

            /// <inheritdoc cref="op_Division{T}(in ReadOnlyTensorSpan{T}, T)" />
            public static Tensor<TScalar> operator /(in TensorSpan<TScalar> left, TScalar right) => Divide(left, right);

            /// <inheritdoc cref="op_Division{T}(T, in ReadOnlyTensorSpan{T})" />
            public static Tensor<TScalar> operator /(TScalar left, in TensorSpan<TScalar> right) => Divide(left, right);

            /// <summary>Performs in-place element-wise division between two tensors.</summary>
            /// <param name="other">The tensor divisor.</param>
            public void operator /=(in ReadOnlyTensorSpan<TScalar> other) => Divide(tensor, other, tensor);

            /// <summary>Performs in-place element-wise division between a tensor and scalar.</summary>
            /// <param name="other">The scalar divisor.</param>
            public void operator /=(TScalar other) => Divide(tensor, other, tensor);
        }
    }
}