// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Runtime.CompilerServices; namespace System.Numerics { /// /// Contains various methods useful for creating, manipulating, combining, and converting generic vectors with one another. /// public static class Vector { // JIT is not looking at the Vector class methods // all methods here should be inlined and they must be implemented in terms of Vector intrinsics #region Select Methods /// /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. /// /// The integral mask vector used to drive selection. /// The first source vector. /// The second source vector. /// The new vector with elements selected based on the mask. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) { return (Vector)Vector.ConditionalSelect((Vector)condition, left, right); } /// /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. /// /// The integral mask vector used to drive selection. /// The first source vector. /// The second source vector. /// The new vector with elements selected based on the mask. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) { return (Vector)Vector.ConditionalSelect((Vector)condition, left, right); } /// /// Creates a new vector with elements selected between the two given source vectors, and based on a mask vector. /// /// The mask vector used to drive selection. /// The first source vector. /// The second source vector. /// The new vector with elements selected based on the mask. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector ConditionalSelect(Vector condition, Vector left, Vector right) where T : struct { return Vector.ConditionalSelect(condition, left, right); } #endregion Select Methods #region Comparison methods #region Equals methods /// /// Returns a new vector whose elements signal whether the elements in left and right were equal. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) where T : struct { return Vector.Equals(left, right); } /// /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return (Vector)Vector.Equals(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left and right were equal. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return Vector.Equals(left, right); } /// /// Returns an integral vector whose elements signal whether elements in the left and right floating point vectors were equal. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return (Vector)Vector.Equals(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left and right were equal. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Equals(Vector left, Vector right) { return Vector.Equals(left, right); } /// /// Returns a boolean indicating whether each pair of elements in the given vectors are equal. /// /// The first vector to compare. /// The first vector to compare. /// True if all elements are equal; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool EqualsAll(Vector left, Vector right) where T : struct { return left == right; } /// /// Returns a boolean indicating whether any single pair of elements in the given vectors are equal. /// /// The first vector to compare. /// The second vector to compare. /// True if any element pairs are equal; False if no element pairs are equal. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool EqualsAny(Vector left, Vector right) where T : struct { return !Vector.Equals(left, right).Equals(Vector.Zero); } #endregion Equals methods #region Lessthan Methods /// /// Returns a new vector whose elements signal whether the elements in left were less than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) where T : struct { return Vector.LessThan(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were less than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return (Vector)Vector.LessThan(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were less than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return Vector.LessThan(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were less than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return (Vector)Vector.LessThan(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were less than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThan(Vector left, Vector right) { return Vector.LessThan(left, right); } /// /// Returns a boolean indicating whether all of the elements in left are less than their corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// True if all elements in left are less than their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool LessThanAll(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.LessThan(left, right); return cond.Equals(Vector.AllOnes); } /// /// Returns a boolean indicating whether any element in left is less than its corresponding element in right. /// /// The first vector to compare. /// The second vector to compare. /// True if any elements in left are less than their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool LessThanAny(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.LessThan(left, right); return !cond.Equals(Vector.Zero); } #endregion LessthanMethods #region Lessthanorequal methods /// /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) where T : struct { return Vector.LessThanOrEqual(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return (Vector)Vector.LessThanOrEqual(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return Vector.LessThanOrEqual(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were less than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return Vector.LessThanOrEqual(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were less than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector LessThanOrEqual(Vector left, Vector right) { return (Vector)Vector.LessThanOrEqual(left, right); } /// /// Returns a boolean indicating whether all elements in left are less than or equal to their corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// True if all elements in left are less than or equal to their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool LessThanOrEqualAll(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.LessThanOrEqual(left, right); return cond.Equals(Vector.AllOnes); } /// /// Returns a boolean indicating whether any element in left is less than or equal to its corresponding element in right. /// /// The first vector to compare. /// The second vector to compare. /// True if any elements in left are less than their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool LessThanOrEqualAny(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.LessThanOrEqual(left, right); return !cond.Equals(Vector.Zero); } #endregion Lessthanorequal methods #region Greaterthan methods /// /// Returns a new vector whose elements signal whether the elements in left were greater than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) where T : struct { return Vector.GreaterThan(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were greater than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return (Vector)Vector.GreaterThan(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were greater than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return Vector.GreaterThan(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were greater than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return (Vector)Vector.GreaterThan(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were greater than their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThan(Vector left, Vector right) { return Vector.GreaterThan(left, right); } /// /// Returns a boolean indicating whether all elements in left are greater than the corresponding elements in right. /// elements in right. /// /// The first vector to compare. /// The second vector to compare. /// True if all elements in left are greater than their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanAll(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.GreaterThan(left, right); return cond.Equals(Vector.AllOnes); } /// /// Returns a boolean indicating whether any element in left is greater than its corresponding element in right. /// /// The first vector to compare. /// The second vector to compare. /// True if any elements in left are greater than their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanAny(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.GreaterThan(left, right); return !cond.Equals(Vector.Zero); } #endregion Greaterthan methods #region Greaterthanorequal methods /// /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) where T : struct { return Vector.GreaterThanOrEqual(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return (Vector)Vector.GreaterThanOrEqual(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return Vector.GreaterThanOrEqual(left, right); } /// /// Returns a new vector whose elements signal whether the elements in left were greater than or equal to their /// corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return Vector.GreaterThanOrEqual(left, right); } /// /// Returns an integral vector whose elements signal whether the elements in left were greater than or equal to /// their corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// The resultant integral vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector GreaterThanOrEqual(Vector left, Vector right) { return (Vector)Vector.GreaterThanOrEqual(left, right); } /// /// Returns a boolean indicating whether all of the elements in left are greater than or equal to /// their corresponding elements in right. /// /// The first vector to compare. /// The second vector to compare. /// True if all elements in left are greater than or equal to their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanOrEqualAll(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.GreaterThanOrEqual(left, right); return cond.Equals(Vector.AllOnes); } /// /// Returns a boolean indicating whether any element in left is greater than or equal to its corresponding element in right. /// /// The first vector to compare. /// The second vector to compare. /// True if any elements in left are greater than or equal to their corresponding elements in right; False otherwise. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static bool GreaterThanOrEqualAny(Vector left, Vector right) where T : struct { Vector cond = (Vector)Vector.GreaterThanOrEqual(left, right); return !cond.Equals(Vector.Zero); } #endregion Greaterthanorequal methods #endregion Comparison methods #region Vector Math Methods // Every operation must either be a JIT intrinsic or implemented over a JIT intrinsic // as a thin wrapper // Operations implemented over a JIT intrinsic should be inlined // Methods that do not have a type parameter are recognized as intrinsics /// /// Returns whether or not vector operations are subject to hardware acceleration through JIT intrinsic support. /// [JitIntrinsic] public static bool IsHardwareAccelerated { get { return false; } } // Vector // Basic Math // All Math operations for Vector are aggressively inlined here /// /// Returns a new vector whose elements are the absolute values of the given vector's elements. /// /// The source vector. /// The absolute value vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Abs(Vector value) where T : struct { return Vector.Abs(value); } /// /// Returns a new vector whose elements are the minimum of each pair of elements in the two given vectors. /// /// The first source vector. /// The second source vector. /// The minimum vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Min(Vector left, Vector right) where T : struct { return Vector.Min(left, right); } /// /// Returns a new vector whose elements are the maximum of each pair of elements in the two given vectors. /// /// The first source vector. /// The second source vector. /// The maximum vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Max(Vector left, Vector right) where T : struct { return Vector.Max(left, right); } // Specialized vector operations /// /// Returns the dot product of two vectors. /// /// The first source vector. /// The second source vector. /// The dot product. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static T Dot(Vector left, Vector right) where T : struct { return Vector.DotProduct(left, right); } /// /// Returns a new vector whose elements are the square roots of the given vector's elements. /// /// The source vector. /// The square root vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector SquareRoot(Vector value) where T : struct { return Vector.SquareRoot(value); } #endregion Vector Math Methods #region Named Arithmetic Operators /// /// Creates a new vector whose values are the sum of each pair of elements from the two given vectors. /// /// The first source vector. /// The second source vector. /// The summed vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Add(Vector left, Vector right) where T : struct { return left + right; } /// /// Creates a new vector whose values are the difference between each pairs of elements in the given vectors. /// /// The first source vector. /// The second source vector. /// The difference vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Subtract(Vector left, Vector right) where T : struct { return left - right; } /// /// Creates a new vector whose values are the product of each pair of elements from the two given vectors. /// /// The first source vector. /// The second source vector. /// The summed vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Multiply(Vector left, Vector right) where T : struct { return left * right; } /// /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value. /// /// The source vector. /// The scalar factor. /// The scaled vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Multiply(Vector left, T right) where T : struct { return left * right; } /// /// Returns a new vector whose values are the values of the given vector each multiplied by a scalar value. /// /// The scalar factor. /// The source vector. /// The scaled vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Multiply(T left, Vector right) where T : struct { return left * right; } /// /// Returns a new vector whose values are the result of dividing the first vector's elements /// by the corresponding elements in the second vector. /// /// The first source vector. /// The second source vector. /// The divided vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Divide(Vector left, Vector right) where T : struct { return left / right; } /// /// Returns a new vector whose elements are the given vector's elements negated. /// /// The source vector. /// The negated vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Negate(Vector value) where T : struct { return -value; } #endregion Named Arithmetic Operators #region Named Bitwise Operators /// /// Returns a new vector by performing a bitwise-and operation on each of the elements in the given vectors. /// /// The first source vector. /// The second source vector. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector BitwiseAnd(Vector left, Vector right) where T : struct { return left & right; } /// /// Returns a new vector by performing a bitwise-or operation on each of the elements in the given vectors. /// /// The first source vector. /// The second source vector. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector BitwiseOr(Vector left, Vector right) where T : struct { return left | right; } /// /// Returns a new vector whose elements are obtained by taking the one's complement of the given vector's elements. /// /// The source vector. /// The one's complement vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector OnesComplement(Vector value) where T : struct { return ~value; } /// /// Returns a new vector by performing a bitwise-exclusive-or operation on each of the elements in the given vectors. /// /// The first source vector. /// The second source vector. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector Xor(Vector left, Vector right) where T : struct { return left ^ right; } /// /// Returns a new vector by performing a bitwise-and-not operation on each of the elements in the given vectors. /// /// The first source vector. /// The second source vector. /// The resultant vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AndNot(Vector left, Vector right) where T : struct { return left & ~right; } #endregion Named Bitwise Operators #region Conversion Methods /// /// Reinterprets the bits of the given vector into those of a vector of unsigned bytes. /// /// The source vector /// The reinterpreted vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorByte(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of signed bytes. /// /// The source vector /// The reinterpreted vector. [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorSByte(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of 16-bit integers. /// /// The source vector /// The reinterpreted vector. [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorUInt16(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of signed 16-bit integers. /// /// The source vector /// The reinterpreted vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorInt16(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of unsigned 32-bit integers. /// /// The source vector /// The reinterpreted vector. [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorUInt32(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of signed 32-bit integers. /// /// The source vector /// The reinterpreted vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorInt32(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of unsigned 64-bit integers. /// /// The source vector /// The reinterpreted vector. [CLSCompliant(false)] [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorUInt64(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of signed 64-bit integers. /// /// The source vector /// The reinterpreted vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorInt64(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of 32-bit floating point numbers. /// /// The source vector /// The reinterpreted vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorSingle(Vector value) where T : struct { return (Vector)value; } /// /// Reinterprets the bits of the given vector into those of a vector of 64-bit floating point numbers. /// /// The source vector /// The reinterpreted vector. [MethodImplAttribute(MethodImplOptions.AggressiveInlining)] public static Vector AsVectorDouble(Vector value) where T : struct { return (Vector)value; } #endregion Conversion Methods } }