// 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;
}
///