1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-11 02:13:38 +09:00

Expose the Sin, Cos, and SinCos methods on the Vector types (#104848)

* Allow using a more efficient algorithm if twice the vector size is accelerated

* Remove an unnecessary generic parameter from ExpDouble

* Expose the Sin, Cos, and SinCos methods on the Vector types

* Use the vector Sin, Cos, and SinCos methods where possible

* Adding tests covering the vector Sin, Cos, and SinCos APIs

* Fix some small bugs in the Sin, Cos, and SinCos impls

* Ensure that very large inputs are handled

* Ensure region is correctly adjusted when determining the sign of sin

* Ensure that TernaryLogic lowering accounts for AND_NOT since it is not commutative

* Don't vectorize too large SinPi or CosPi inputs for TensorPrimitives

* Don't accelerate SinCosPi for the time being

* Don't accelerate TensorPrimitives.SinCos for the time being

* Don't include JIT changes, they were extracted to their own PR
This commit is contained in:
Tanner Gooding 2024-07-19 07:45:11 -07:00 committed by GitHub
parent 5fd965d7bf
commit 72f9ee0d26
Signed by: github
GPG key ID: B5690EEEBB952194
29 changed files with 2898 additions and 456 deletions

View file

@ -198,6 +198,86 @@ namespace System.Tests
}
}
public static IEnumerable<object[]> CosDouble
{
get
{
yield return new object[] { double.NegativeInfinity, double.NaN, 0.0 };
yield return new object[] { -3.1415926535897932, -1.0, DoubleCrossPlatformMachineEpsilon * 10 }; // value: -(pi)
yield return new object[] { -2.7182818284590452, -0.91173391478696510, DoubleCrossPlatformMachineEpsilon }; // value: -(e)
yield return new object[] { -2.3025850929940457, -0.66820151019031295, DoubleCrossPlatformMachineEpsilon }; // value: -(ln(10))
yield return new object[] { -1.5707963267948966, 0.0, DoubleCrossPlatformMachineEpsilon }; // value: -(pi / 2)
yield return new object[] { -1.4426950408889634, 0.12775121753523991, DoubleCrossPlatformMachineEpsilon }; // value: -(log2(e))
yield return new object[] { -1.4142135623730950, 0.15594369476537447, DoubleCrossPlatformMachineEpsilon }; // value: -(sqrt(2))
yield return new object[] { -1.1283791670955126, 0.42812514788535792, DoubleCrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi))
yield return new object[] { -1.0, 0.54030230586813972, DoubleCrossPlatformMachineEpsilon };
yield return new object[] { -0.78539816339744831, 0.70710678118654752, DoubleCrossPlatformMachineEpsilon }; // value: -(pi / 4), expected: (1 / sqrt(2))
yield return new object[] { -0.70710678118654752, 0.76024459707563015, DoubleCrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2))
yield return new object[] { -0.69314718055994531, 0.76923890136397213, DoubleCrossPlatformMachineEpsilon }; // value: -(ln(2))
yield return new object[] { -0.63661977236758134, 0.80410982822879171, DoubleCrossPlatformMachineEpsilon }; // value: -(2 / pi)
yield return new object[] { -0.43429448190325183, 0.90716712923909839, DoubleCrossPlatformMachineEpsilon }; // value: -(log10(e))
yield return new object[] { -0.31830988618379067, 0.94976571538163866, DoubleCrossPlatformMachineEpsilon }; // value: -(1 / pi)
yield return new object[] { -0.0, 1.0, DoubleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { double.NaN, double.NaN, 0.0 };
yield return new object[] { 0.0, 1.0, DoubleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { 0.31830988618379067, 0.94976571538163866, DoubleCrossPlatformMachineEpsilon }; // value: (1 / pi)
yield return new object[] { 0.43429448190325183, 0.90716712923909839, DoubleCrossPlatformMachineEpsilon }; // value: (log10(e))
yield return new object[] { 0.63661977236758134, 0.80410982822879171, DoubleCrossPlatformMachineEpsilon }; // value: (2 / pi)
yield return new object[] { 0.69314718055994531, 0.76923890136397213, DoubleCrossPlatformMachineEpsilon }; // value: (ln(2))
yield return new object[] { 0.70710678118654752, 0.76024459707563015, DoubleCrossPlatformMachineEpsilon }; // value: (1 / sqrt(2))
yield return new object[] { 0.78539816339744831, 0.70710678118654752, DoubleCrossPlatformMachineEpsilon }; // value: (pi / 4), expected: (1 / sqrt(2))
yield return new object[] { 1.0, 0.54030230586813972, DoubleCrossPlatformMachineEpsilon };
yield return new object[] { 1.1283791670955126, 0.42812514788535792, DoubleCrossPlatformMachineEpsilon }; // value: (2 / sqrt(pi))
yield return new object[] { 1.4142135623730950, 0.15594369476537447, DoubleCrossPlatformMachineEpsilon }; // value: (sqrt(2))
yield return new object[] { 1.4426950408889634, 0.12775121753523991, DoubleCrossPlatformMachineEpsilon }; // value: (log2(e))
yield return new object[] { 1.5707963267948966, 0.0, DoubleCrossPlatformMachineEpsilon }; // value: (pi / 2)
yield return new object[] { 2.3025850929940457, -0.66820151019031295, DoubleCrossPlatformMachineEpsilon }; // value: (ln(10))
yield return new object[] { 2.7182818284590452, -0.91173391478696510, DoubleCrossPlatformMachineEpsilon }; // value: (e)
yield return new object[] { 3.1415926535897932, -1.0, DoubleCrossPlatformMachineEpsilon * 10 }; // value: (pi)
yield return new object[] { double.PositiveInfinity, double.NaN, 0.0 };
}
}
public static IEnumerable<object[]> CosSingle
{
get
{
yield return new object[] { float.NegativeInfinity, float.NaN, 0.0f };
yield return new object[] { -3.14159265f, -1.0f, SingleCrossPlatformMachineEpsilon * 10 }; // value: -(pi)
yield return new object[] { -2.71828183f, -0.911733918f, SingleCrossPlatformMachineEpsilon }; // value: -(e)
yield return new object[] { -2.30258509f, -0.668201510f, SingleCrossPlatformMachineEpsilon }; // value: -(ln(10))
yield return new object[] { -1.57079633f, 0.0f, SingleCrossPlatformMachineEpsilon }; // value: -(pi / 2)
yield return new object[] { -1.44269504f, 0.127751218f, SingleCrossPlatformMachineEpsilon }; // value: -(log2(e))
yield return new object[] { -1.41421356f, 0.155943695f, SingleCrossPlatformMachineEpsilon }; // value: -(sqrt(2))
yield return new object[] { -1.12837917f, 0.428125148f, SingleCrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi))
yield return new object[] { -1.0f, 0.540302306f, SingleCrossPlatformMachineEpsilon };
yield return new object[] { -0.785398163f, 0.707106781f, SingleCrossPlatformMachineEpsilon }; // value: -(pi / 4), expected: (1 / sqrt(2))
yield return new object[] { -0.707106781f, 0.760244597f, SingleCrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2))
yield return new object[] { -0.693147181f, 0.769238901f, SingleCrossPlatformMachineEpsilon }; // value: -(ln(2))
yield return new object[] { -0.636619772f, 0.804109828f, SingleCrossPlatformMachineEpsilon }; // value: -(2 / pi)
yield return new object[] { -0.434294482f, 0.907167129f, SingleCrossPlatformMachineEpsilon }; // value: -(log10(e))
yield return new object[] { -0.318309886f, 0.949765715f, SingleCrossPlatformMachineEpsilon }; // value: -(1 / pi)
yield return new object[] { -0.0f, 1.0f, SingleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { float.NaN, float.NaN, 0.0f };
yield return new object[] { 0.0f, 1.0f, SingleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { 0.318309886f, 0.949765715f, SingleCrossPlatformMachineEpsilon }; // value: (1 / pi)
yield return new object[] { 0.434294482f, 0.907167129f, SingleCrossPlatformMachineEpsilon }; // value: (log10(e))
yield return new object[] { 0.636619772f, 0.804109828f, SingleCrossPlatformMachineEpsilon }; // value: (2 / pi)
yield return new object[] { 0.693147181f, 0.769238901f, SingleCrossPlatformMachineEpsilon }; // value: (ln(2))
yield return new object[] { 0.707106781f, 0.760244597f, SingleCrossPlatformMachineEpsilon }; // value: (1 / sqrt(2))
yield return new object[] { 0.785398163f, 0.707106781f, SingleCrossPlatformMachineEpsilon }; // value: (pi / 4), expected: (1 / sqrt(2))
yield return new object[] { 1.0f, 0.540302306f, SingleCrossPlatformMachineEpsilon };
yield return new object[] { 1.12837917f, 0.428125148f, SingleCrossPlatformMachineEpsilon }; // value: (2 / sqrt(pi))
yield return new object[] { 1.41421356f, 0.155943695f, SingleCrossPlatformMachineEpsilon }; // value: (sqrt(2))
yield return new object[] { 1.44269504f, 0.127751218f, SingleCrossPlatformMachineEpsilon }; // value: (log2(e))
yield return new object[] { 1.57079633f, 0.0f, SingleCrossPlatformMachineEpsilon }; // value: (pi / 2)
yield return new object[] { 2.30258509f, -0.668201510f, SingleCrossPlatformMachineEpsilon }; // value: (ln(10))
yield return new object[] { 2.71828183f, -0.911733918f, SingleCrossPlatformMachineEpsilon }; // value: (e)
yield return new object[] { 3.14159265f, -1.0f, SingleCrossPlatformMachineEpsilon * 10 }; // value: (pi)
yield return new object[] { float.PositiveInfinity, float.NaN, 0.0f };
}
}
public static IEnumerable<object[]> DegreesToRadiansDouble
{
get
@ -981,7 +1061,7 @@ namespace System.Tests
yield return new object[] { 0.64321824193300488, -0.63661977236758126, DoubleCrossPlatformMachineEpsilon }; // expected: -(2 / pi)
yield return new object[] { 0.74005557395545179, -0.43429448190325190, DoubleCrossPlatformMachineEpsilon }; // expected: -(log10(e))
yield return new object[] { 0.80200887896145195, -0.31830988618379073, DoubleCrossPlatformMachineEpsilon }; // expected: -(1 / pi)
yield return new object[] { 1, 0.0, 0.0 };
yield return new object[] { 1, 0.0, 0.0 };
yield return new object[] { 1.2468689889006383, 0.31830988618379073, DoubleCrossPlatformMachineEpsilon }; // expected: (1 / pi)
yield return new object[] { 1.3512498725672678, 0.43429448190325226, DoubleCrossPlatformMachineEpsilon }; // expected: (log10(e))
yield return new object[] { 1.5546822754821001, 0.63661977236758126, DoubleCrossPlatformMachineEpsilon }; // expected: (2 / pi)
@ -1664,6 +1744,170 @@ namespace System.Tests
}
}
public static IEnumerable<object[]> SinDouble
{
get
{
yield return new object[] { double.NegativeInfinity, double.NaN, 0.0 };
yield return new object[] { -3.1415926535897932, -0.0, DoubleCrossPlatformMachineEpsilon }; // value: -(pi)
yield return new object[] { -2.7182818284590452, -0.41078129050290870, DoubleCrossPlatformMachineEpsilon }; // value: -(e)
yield return new object[] { -2.3025850929940457, -0.74398033695749319, DoubleCrossPlatformMachineEpsilon }; // value: -(ln(10))
yield return new object[] { -1.5707963267948966, -1.0, DoubleCrossPlatformMachineEpsilon * 10 }; // value: -(pi / 2)
yield return new object[] { -1.4426950408889634, -0.99180624439366372, DoubleCrossPlatformMachineEpsilon }; // value: -(log2(e))
yield return new object[] { -1.4142135623730950, -0.98776594599273553, DoubleCrossPlatformMachineEpsilon }; // value: -(sqrt(2))
yield return new object[] { -1.1283791670955126, -0.90371945743584630, DoubleCrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi))
yield return new object[] { -1.0, -0.84147098480789651, DoubleCrossPlatformMachineEpsilon };
yield return new object[] { -0.78539816339744831, -0.70710678118654752, DoubleCrossPlatformMachineEpsilon }; // value: -(pi / 4), expected: -(1 / sqrt(2))
yield return new object[] { -0.70710678118654752, -0.64963693908006244, DoubleCrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2))
yield return new object[] { -0.69314718055994531, -0.63896127631363480, DoubleCrossPlatformMachineEpsilon }; // value: -(ln(2))
yield return new object[] { -0.63661977236758134, -0.59448076852482208, DoubleCrossPlatformMachineEpsilon }; // value: -(2 / pi)
yield return new object[] { -0.43429448190325183, -0.42077048331375735, DoubleCrossPlatformMachineEpsilon }; // value: -(log10(e))
yield return new object[] { -0.31830988618379067, -0.31296179620778659, DoubleCrossPlatformMachineEpsilon }; // value: -(1 / pi)
yield return new object[] { -0.0, -0.0, 0.0 };
yield return new object[] { double.NaN, double.NaN, 0.0 };
yield return new object[] { 0.0, 0.0, 0.0 };
yield return new object[] { 0.31830988618379067, 0.31296179620778659, DoubleCrossPlatformMachineEpsilon }; // value: (1 / pi)
yield return new object[] { 0.43429448190325183, 0.42077048331375735, DoubleCrossPlatformMachineEpsilon }; // value: (log10(e))
yield return new object[] { 0.63661977236758134, 0.59448076852482208, DoubleCrossPlatformMachineEpsilon }; // value: (2 / pi)
yield return new object[] { 0.69314718055994531, 0.63896127631363480, DoubleCrossPlatformMachineEpsilon }; // value: (ln(2))
yield return new object[] { 0.70710678118654752, 0.64963693908006244, DoubleCrossPlatformMachineEpsilon }; // value: (1 / sqrt(2))
yield return new object[] { 0.78539816339744831, 0.70710678118654752, DoubleCrossPlatformMachineEpsilon }; // value: (pi / 4), expected: (1 / sqrt(2))
yield return new object[] { 1.0, 0.84147098480789651, DoubleCrossPlatformMachineEpsilon };
yield return new object[] { 1.1283791670955126, 0.90371945743584630, DoubleCrossPlatformMachineEpsilon }; // value: (2 / sqrt(pi))
yield return new object[] { 1.4142135623730950, 0.98776594599273553, DoubleCrossPlatformMachineEpsilon }; // value: (sqrt(2))
yield return new object[] { 1.4426950408889634, 0.99180624439366372, DoubleCrossPlatformMachineEpsilon }; // value: (log2(e))
yield return new object[] { 1.5707963267948966, 1.0, DoubleCrossPlatformMachineEpsilon * 10 }; // value: (pi / 2)
yield return new object[] { 2.3025850929940457, 0.74398033695749319, DoubleCrossPlatformMachineEpsilon }; // value: (ln(10))
yield return new object[] { 2.7182818284590452, 0.41078129050290870, DoubleCrossPlatformMachineEpsilon }; // value: (e)
yield return new object[] { 3.1415926535897932, 0.0, DoubleCrossPlatformMachineEpsilon }; // value: (pi)
yield return new object[] { double.PositiveInfinity, double.NaN, 0.0 };
}
}
public static IEnumerable<object[]> SinSingle
{
get
{
yield return new object[] { float.NegativeInfinity, float.NaN, 0.0f };
yield return new object[] { -3.14159265f, -0.0f, SingleCrossPlatformMachineEpsilon }; // value: -(pi)
yield return new object[] { -2.71828183f, -0.410781291f, SingleCrossPlatformMachineEpsilon }; // value: -(e)
yield return new object[] { -2.30258509f, -0.743980337f, SingleCrossPlatformMachineEpsilon }; // value: -(ln(10))
yield return new object[] { -1.57079633f, -1.0f, SingleCrossPlatformMachineEpsilon * 10 }; // value: -(pi / 2)
yield return new object[] { -1.44269504f, -0.991806244f, SingleCrossPlatformMachineEpsilon }; // value: -(log2(e))
yield return new object[] { -1.41421356f, -0.987765946f, SingleCrossPlatformMachineEpsilon }; // value: -(sqrt(2))
yield return new object[] { -1.12837917f, -0.903719457f, SingleCrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi))
yield return new object[] { -1.0f, -0.841470985f, SingleCrossPlatformMachineEpsilon };
yield return new object[] { -0.785398163f, -0.707106781f, SingleCrossPlatformMachineEpsilon }; // value: -(pi / 4), expected: -(1 / sqrt(2))
yield return new object[] { -0.707106781f, -0.649636939f, SingleCrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2))
yield return new object[] { -0.693147181f, -0.638961276f, SingleCrossPlatformMachineEpsilon }; // value: -(ln(2))
yield return new object[] { -0.636619772f, -0.594480769f, SingleCrossPlatformMachineEpsilon }; // value: -(2 / pi)
yield return new object[] { -0.434294482f, -0.420770483f, SingleCrossPlatformMachineEpsilon }; // value: -(log10(e))
yield return new object[] { -0.318309886f, -0.312961796f, SingleCrossPlatformMachineEpsilon }; // value: -(1 / pi)
yield return new object[] { -0.0f, -0.0f, 0.0f };
yield return new object[] { float.NaN, float.NaN, 0.0f };
yield return new object[] { 0.0f, 0.0f, 0.0f };
yield return new object[] { 0.318309886f, 0.312961796f, SingleCrossPlatformMachineEpsilon }; // value: (1 / pi)
yield return new object[] { 0.434294482f, 0.420770483f, SingleCrossPlatformMachineEpsilon }; // value: (log10(e))
yield return new object[] { 0.636619772f, 0.594480769f, SingleCrossPlatformMachineEpsilon }; // value: (2 / pi)
yield return new object[] { 0.693147181f, 0.638961276f, SingleCrossPlatformMachineEpsilon }; // value: (ln(2))
yield return new object[] { 0.707106781f, 0.649636939f, SingleCrossPlatformMachineEpsilon }; // value: (1 / sqrt(2))
yield return new object[] { 0.785398163f, 0.707106781f, SingleCrossPlatformMachineEpsilon }; // value: (pi / 4), expected: (1 / sqrt(2))
yield return new object[] { 1.0f, 0.841470985f, SingleCrossPlatformMachineEpsilon };
yield return new object[] { 1.12837917f, 0.903719457f, SingleCrossPlatformMachineEpsilon }; // value: (2 / sqrt(pi))
yield return new object[] { 1.41421356f, 0.987765946f, SingleCrossPlatformMachineEpsilon }; // value: (sqrt(2))
yield return new object[] { 1.44269504f, 0.991806244f, SingleCrossPlatformMachineEpsilon }; // value: (log2(e))
yield return new object[] { 1.57079633f, 1.0f, SingleCrossPlatformMachineEpsilon * 10 }; // value: (pi / 2)
yield return new object[] { 2.30258509f, 0.743980337f, SingleCrossPlatformMachineEpsilon }; // value: (ln(10))
yield return new object[] { 2.71828183f, 0.410781291f, SingleCrossPlatformMachineEpsilon }; // value: (e)
yield return new object[] { 3.14159265f, 0.0f, SingleCrossPlatformMachineEpsilon }; // value: (pi)
yield return new object[] { float.PositiveInfinity, float.NaN, 0.0f };
}
}
public static IEnumerable<object[]> SinCosDouble
{
get
{
yield return new object[] { double.NegativeInfinity, double.NaN, double.NaN, 0.0, 0.0 };
yield return new object[] { -1e18, 0.9929693207404051, 0.11837199021871073, 0.0002, 0.002 }; // https://github.com/dotnet/runtime/issues/98204
yield return new object[] { -3.1415926535897932, -0.0, -1.0, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon * 10 }; // value: -(pi)
yield return new object[] { -2.7182818284590452, -0.41078129050290870, -0.91173391478696510, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(e)
yield return new object[] { -2.3025850929940457, -0.74398033695749319, -0.66820151019031295, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(ln(10))
yield return new object[] { -1.5707963267948966, -1.0, 0.0, DoubleCrossPlatformMachineEpsilon * 10, DoubleCrossPlatformMachineEpsilon }; // value: -(pi / 2)
yield return new object[] { -1.4426950408889634, -0.99180624439366372, 0.12775121753523991, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(log2(e))
yield return new object[] { -1.4142135623730950, -0.98776594599273553, 0.15594369476537447, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(sqrt(2))
yield return new object[] { -1.1283791670955126, -0.90371945743584630, 0.42812514788535792, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi))
yield return new object[] { -1.0, -0.84147098480789651, 0.54030230586813972, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon };
yield return new object[] { -0.78539816339744831, -0.70710678118654752, 0.70710678118654752, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(pi / 4), expected_sin: -(1 / sqrt(2)), expected_cos: 1
yield return new object[] { -0.70710678118654752, -0.64963693908006244, 0.76024459707563015, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2))
yield return new object[] { -0.69314718055994531, -0.63896127631363480, 0.76923890136397213, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(ln(2))
yield return new object[] { -0.63661977236758134, -0.59448076852482208, 0.80410982822879171, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(2 / pi)
yield return new object[] { -0.43429448190325183, -0.42077048331375735, 0.90716712923909839, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(log10(e))
yield return new object[] { -0.31830988618379067, -0.31296179620778659, 0.94976571538163866, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: -(1 / pi)
yield return new object[] { -0.0, -0.0, 1.0, 0.0, DoubleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { double.NaN, double.NaN, double.NaN, 0.0, 0.0 };
yield return new object[] { 0.0, 0.0, 1.0, 0.0, DoubleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { 0.31830988618379067, 0.31296179620778659, 0.94976571538163866, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (1 / pi)
yield return new object[] { 0.43429448190325183, 0.42077048331375735, 0.90716712923909839, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (log10(e))
yield return new object[] { 0.63661977236758134, 0.59448076852482208, 0.80410982822879171, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (2 / pi)
yield return new object[] { 0.69314718055994531, 0.63896127631363480, 0.76923890136397213, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (ln(2))
yield return new object[] { 0.70710678118654752, 0.64963693908006244, 0.76024459707563015, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (1 / sqrt(2))
yield return new object[] { 0.78539816339744831, 0.70710678118654752, 0.70710678118654752, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (pi / 4), expected_sin: (1 / sqrt(2)), expected_cos: 1
yield return new object[] { 1.0, 0.84147098480789651, 0.54030230586813972, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon };
yield return new object[] { 1.1283791670955126, 0.90371945743584630, 0.42812514788535792, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (2 / sqrt(pi))
yield return new object[] { 1.4142135623730950, 0.98776594599273553, 0.15594369476537447, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (sqrt(2))
yield return new object[] { 1.4426950408889634, 0.99180624439366372, 0.12775121753523991, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (log2(e))
yield return new object[] { 1.5707963267948966, 1.0, 0.0, DoubleCrossPlatformMachineEpsilon * 10, DoubleCrossPlatformMachineEpsilon }; // value: (pi / 2)
yield return new object[] { 2.3025850929940457, 0.74398033695749319, -0.66820151019031295, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (ln(10))
yield return new object[] { 2.7182818284590452, 0.41078129050290870, -0.91173391478696510, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon }; // value: (e)
yield return new object[] { 3.1415926535897932, 0.0, -1.0, DoubleCrossPlatformMachineEpsilon, DoubleCrossPlatformMachineEpsilon * 10 }; // value: (pi)
yield return new object[] { 1e18, -0.9929693207404051, 0.11837199021871073, 0.0002, 0.002 }; // https://github.com/dotnet/runtime/issues/98204
yield return new object[] { double.PositiveInfinity, double.NaN, double.NaN, 0.0, 0.0 };
}
}
public static IEnumerable<object[]> SinCosSingle
{
get
{
yield return new object[] { float.NegativeInfinity, float.NaN, float.NaN, 0.0f, 0.0f };
yield return new object[] { -1e8f, -0.931639, -0.36338508, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // https://github.com/dotnet/runtime/issues/98204
yield return new object[] { -3.14159265f, -0.0f, -1.0f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon * 10 }; // value: -(pi)
yield return new object[] { -2.71828183f, -0.410781291f, -0.911733918f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(e)
yield return new object[] { -2.30258509f, -0.743980337f, -0.668201510f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(ln(10))
yield return new object[] { -1.57079633f, -1.0f, 0.0f, SingleCrossPlatformMachineEpsilon * 10, SingleCrossPlatformMachineEpsilon }; // value: -(pi / 2)
yield return new object[] { -1.44269504f, -0.991806244f, 0.127751218f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(log2(e))
yield return new object[] { -1.41421356f, -0.987765946f, 0.155943695f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(sqrt(2))
yield return new object[] { -1.12837917f, -0.903719457f, 0.428125148f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi))
yield return new object[] { -1.0f, -0.841470985f, 0.540302306f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon };
yield return new object[] { -0.785398163f, -0.707106781f, 0.707106781f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(pi / 4), expected_sin: -(1 / sqrt(2)), expected_cos: 1
yield return new object[] { -0.707106781f, -0.649636939f, 0.760244597f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2))
yield return new object[] { -0.693147181f, -0.638961276f, 0.769238901f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(ln(2))
yield return new object[] { -0.636619772f, -0.594480769f, 0.804109828f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(2 / pi)
yield return new object[] { -0.434294482f, -0.420770483f, 0.907167129f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(log10(e))
yield return new object[] { -0.318309886f, -0.312961796f, 0.949765715f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: -(1 / pi)
yield return new object[] { -0.0f, -0.0f, 1.0f, 0.0f, SingleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { float.NaN, float.NaN, float.NaN, 0.0f, 0.0f };
yield return new object[] { 0.0f, 0.0f, 1.0f, 0.0f, SingleCrossPlatformMachineEpsilon * 10 };
yield return new object[] { 0.318309886f, 0.312961796f, 0.949765715f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (1 / pi)
yield return new object[] { 0.434294482f, 0.420770483f, 0.907167129f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (log10(e))
yield return new object[] { 0.636619772f, 0.594480769f, 0.804109828f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (2 / pi)
yield return new object[] { 0.693147181f, 0.638961276f, 0.769238901f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (ln(2))
yield return new object[] { 0.707106781f, 0.649636939f, 0.760244597f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (1 / sqrt(2))
yield return new object[] { 0.785398163f, 0.707106781f, 0.707106781f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (pi / 4), expected_sin: (1 / sqrt(2)), expected_cos: 1
yield return new object[] { 1.0f, 0.841470985f, 0.540302306f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon };
yield return new object[] { 1.12837917f, 0.903719457f, 0.428125148f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (2 / sqrt(pi))
yield return new object[] { 1.41421356f, 0.987765946f, 0.155943695f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (sqrt(2))
yield return new object[] { 1.44269504f, 0.991806244f, 0.127751218f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (log2(e))
yield return new object[] { 1.57079633f, 1.0f, 0.0f, SingleCrossPlatformMachineEpsilon * 10, SingleCrossPlatformMachineEpsilon }; // value: (pi / 2)
yield return new object[] { 2.30258509f, 0.743980337f, -0.668201510f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (ln(10))
yield return new object[] { 2.71828183f, 0.410781291f, -0.911733918f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // value: (e)
yield return new object[] { 3.14159265f, 0.0f, -1.0f, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon * 10 }; // value: (pi)
yield return new object[] { 1e8f, 0.931639, -0.36338508, SingleCrossPlatformMachineEpsilon, SingleCrossPlatformMachineEpsilon }; // https://github.com/dotnet/runtime/issues/98204
yield return new object[] { float.PositiveInfinity, float.NaN, float.NaN, 0.0f, 0.0f };
}
}
public static IEnumerable<object[]> TruncateDouble
{
get

View file

@ -60,12 +60,24 @@ namespace System.Numerics.Tensors
// 3. Reconstruction
// Hence, cos(x) = sin(x + pi/2) = (-1)^N * sin(f)
public static bool Vectorizable => typeof(T) == typeof(float) || typeof(T) == typeof(double);
public static bool Vectorizable => (typeof(T) == typeof(float))
|| (typeof(T) == typeof(double));
public static T Invoke(T x) => T.Cos(x);
public static Vector128<T> Invoke(Vector128<T> x)
{
#if NET9_0_OR_GREATER
if (typeof(T) == typeof(double))
{
return Vector128.Cos(x.AsDouble()).As<double, T>();
}
else
{
Debug.Assert(typeof(T) == typeof(float));
return Vector128.Cos(x.AsSingle()).As<float, T>();
}
#else
if (typeof(T) == typeof(float))
{
return CosOperatorSingle.Invoke(x.AsSingle()).As<float, T>();
@ -75,10 +87,22 @@ namespace System.Numerics.Tensors
Debug.Assert(typeof(T) == typeof(double));
return CosOperatorDouble.Invoke(x.AsDouble()).As<double, T>();
}
#endif
}
public static Vector256<T> Invoke(Vector256<T> x)
{
#if NET9_0_OR_GREATER
if (typeof(T) == typeof(double))
{
return Vector256.Cos(x.AsDouble()).As<double, T>();
}
else
{
Debug.Assert(typeof(T) == typeof(float));
return Vector256.Cos(x.AsSingle()).As<float, T>();
}
#else
if (typeof(T) == typeof(float))
{
return CosOperatorSingle.Invoke(x.AsSingle()).As<float, T>();
@ -88,10 +112,22 @@ namespace System.Numerics.Tensors
Debug.Assert(typeof(T) == typeof(double));
return CosOperatorDouble.Invoke(x.AsDouble()).As<double, T>();
}
#endif
}
public static Vector512<T> Invoke(Vector512<T> x)
{
#if NET9_0_OR_GREATER
if (typeof(T) == typeof(double))
{
return Vector512.Cos(x.AsDouble()).As<double, T>();
}
else
{
Debug.Assert(typeof(T) == typeof(float));
return Vector512.Cos(x.AsSingle()).As<float, T>();
}
#else
if (typeof(T) == typeof(float))
{
return CosOperatorSingle.Invoke(x.AsSingle()).As<float, T>();
@ -101,9 +137,25 @@ namespace System.Numerics.Tensors
Debug.Assert(typeof(T) == typeof(double));
return CosOperatorDouble.Invoke(x.AsDouble()).As<double, T>();
}
#endif
}
}
#if NET9_0_OR_GREATER
// These are still used by CosPiOperator
private readonly struct CosOperatorSingle
{
internal const uint MaxVectorizedValue = 0x4A989680u;
internal const uint SignMask = 0x7FFFFFFFu;
}
private readonly struct CosOperatorDouble
{
internal const ulong SignMask = 0x7FFFFFFFFFFFFFFFul;
internal const ulong MaxVectorizedValue = 0x4160000000000000ul;
}
#else
/// <summary>float.Cos(x)</summary>
private readonly struct CosOperatorSingle : IUnaryOperator<float, float>
{
@ -347,5 +399,6 @@ namespace System.Numerics.Tensors
return (poly.AsUInt64() ^ odd).AsDouble();
}
}
#endif
}
}

View file

@ -33,13 +33,15 @@ namespace System.Numerics.Tensors
private readonly struct CosPiOperator<T> : IUnaryOperator<T, T>
where T : ITrigonometricFunctions<T>
{
public static bool Vectorizable => typeof(T) == typeof(float) || typeof(T) == typeof(double);
public static bool Vectorizable => (typeof(T) == typeof(float))
|| (typeof(T) == typeof(double));
public static T Invoke(T x) => T.CosPi(x);
public static Vector128<T> Invoke(Vector128<T> x)
{
Vector128<T> xpi = x * Vector128.Create(T.Pi);
if (typeof(T) == typeof(float))
{
if (Vector128.GreaterThanAny(xpi.AsUInt32() & Vector128.Create(CosOperatorSingle.SignMask), Vector128.Create(CosOperatorSingle.MaxVectorizedValue)))
@ -62,6 +64,7 @@ namespace System.Numerics.Tensors
public static Vector256<T> Invoke(Vector256<T> x)
{
Vector256<T> xpi = x * Vector256.Create(T.Pi);
if (typeof(T) == typeof(float))
{
if (Vector256.GreaterThanAny(xpi.AsUInt32() & Vector256.Create(CosOperatorSingle.SignMask), Vector256.Create(CosOperatorSingle.MaxVectorizedValue)))
@ -84,6 +87,7 @@ namespace System.Numerics.Tensors
public static Vector512<T> Invoke(Vector512<T> x)
{
Vector512<T> xpi = x * Vector512.Create(T.Pi);
if (typeof(T) == typeof(float))
{
if (Vector512.GreaterThanAny(xpi.AsUInt32() & Vector512.Create(CosOperatorSingle.SignMask), Vector512.Create(CosOperatorSingle.MaxVectorizedValue)))

View file

@ -24,5 +24,79 @@ namespace System.Numerics.Tensors
private static Vector512<double> ApplyScalar<TOperator>(Vector512<double> doubles) where TOperator : IUnaryOperator<double, double> =>
Vector512.Create(ApplyScalar<TOperator>(doubles.GetLower()), ApplyScalar<TOperator>(doubles.GetUpper()));
private static (Vector128<float> First, Vector128<float> Second) Apply2xScalar<TOperator>(Vector128<float> floats)
where TOperator : IUnaryInputBinaryOutput<float>
{
(float firstRes0, float secondRes0) = TOperator.Invoke(floats[0]);
(float firstRes1, float secondRes1) = TOperator.Invoke(floats[1]);
(float firstRes2, float secondRes2) = TOperator.Invoke(floats[2]);
(float firstRes3, float secondRes3) = TOperator.Invoke(floats[3]);
return (
Vector128.Create(firstRes0, firstRes1, firstRes2, firstRes3),
Vector128.Create(secondRes0, secondRes1, secondRes2, secondRes3)
);
}
private static (Vector256<float> First, Vector256<float> Second) Apply2xScalar<TOperator>(Vector256<float> floats)
where TOperator : IUnaryInputBinaryOutput<float>
{
(Vector128<float> firstLower, Vector128<float> secondLower) = Apply2xScalar<TOperator>(floats.GetLower());
(Vector128<float> firstUpper, Vector128<float> secondUpper) = Apply2xScalar<TOperator>(floats.GetUpper());
return (
Vector256.Create(firstLower, firstUpper),
Vector256.Create(secondLower, secondUpper)
);
}
private static (Vector512<float> First, Vector512<float> Second) Apply2xScalar<TOperator>(Vector512<float> floats)
where TOperator : IUnaryInputBinaryOutput<float>
{
(Vector256<float> firstLower, Vector256<float> secondLower) = Apply2xScalar<TOperator>(floats.GetLower());
(Vector256<float> firstUpper, Vector256<float> secondUpper) = Apply2xScalar<TOperator>(floats.GetUpper());
return (
Vector512.Create(firstLower, firstUpper),
Vector512.Create(secondLower, secondUpper)
);
}
private static (Vector128<double> First, Vector128<double> Second) Apply2xScalar<TOperator>(Vector128<double> doubles)
where TOperator : IUnaryInputBinaryOutput<double>
{
(double firstRes0, double secondRes0) = TOperator.Invoke(doubles[0]);
(double firstRes1, double secondRes1) = TOperator.Invoke(doubles[1]);
return (
Vector128.Create(firstRes0, firstRes1),
Vector128.Create(secondRes0, secondRes1)
);
}
private static (Vector256<double> First, Vector256<double> Second) Apply2xScalar<TOperator>(Vector256<double> doubles)
where TOperator : IUnaryInputBinaryOutput<double>
{
(Vector128<double> firstLower, Vector128<double> secondLower) = Apply2xScalar<TOperator>(doubles.GetLower());
(Vector128<double> firstUpper, Vector128<double> secondUpper) = Apply2xScalar<TOperator>(doubles.GetUpper());
return (
Vector256.Create(firstLower, firstUpper),
Vector256.Create(secondLower, secondUpper)
);
}
private static (Vector512<double> First, Vector512<double> Second) Apply2xScalar<TOperator>(Vector512<double> doubles)
where TOperator : IUnaryInputBinaryOutput<double>
{
(Vector256<double> firstLower, Vector256<double> secondLower) = Apply2xScalar<TOperator>(doubles.GetLower());
(Vector256<double> firstUpper, Vector256<double> secondUpper) = Apply2xScalar<TOperator>(doubles.GetUpper());
return (
Vector512.Create(firstLower, firstUpper),
Vector512.Create(secondLower, secondUpper)
);
}
}
}

View file

@ -50,12 +50,24 @@ namespace System.Numerics.Tensors
//
// The term sin(f) can be approximated by using a polynomial
public static bool Vectorizable => typeof(T) == typeof(float) || typeof(T) == typeof(double);
public static bool Vectorizable => (typeof(T) == typeof(float))
|| (typeof(T) == typeof(double));
public static T Invoke(T x) => T.Sin(x);
public static Vector128<T> Invoke(Vector128<T> x)
{
#if NET9_0_OR_GREATER
if (typeof(T) == typeof(double))
{
return Vector128.Sin(x.AsDouble()).As<double, T>();
}
else
{
Debug.Assert(typeof(T) == typeof(float));
return Vector128.Sin(x.AsSingle()).As<float, T>();
}
#else
if (typeof(T) == typeof(float))
{
return SinOperatorSingle.Invoke(x.AsSingle()).As<float, T>();
@ -65,10 +77,22 @@ namespace System.Numerics.Tensors
Debug.Assert(typeof(T) == typeof(double));
return SinOperatorDouble.Invoke(x.AsDouble()).As<double, T>();
}
#endif
}
public static Vector256<T> Invoke(Vector256<T> x)
{
#if NET9_0_OR_GREATER
if (typeof(T) == typeof(double))
{
return Vector256.Sin(x.AsDouble()).As<double, T>();
}
else
{
Debug.Assert(typeof(T) == typeof(float));
return Vector256.Sin(x.AsSingle()).As<float, T>();
}
#else
if (typeof(T) == typeof(float))
{
return SinOperatorSingle.Invoke(x.AsSingle()).As<float, T>();
@ -78,10 +102,22 @@ namespace System.Numerics.Tensors
Debug.Assert(typeof(T) == typeof(double));
return SinOperatorDouble.Invoke(x.AsDouble()).As<double, T>();
}
#endif
}
public static Vector512<T> Invoke(Vector512<T> x)
{
#if NET9_0_OR_GREATER
if (typeof(T) == typeof(double))
{
return Vector512.Sin(x.AsDouble()).As<double, T>();
}
else
{
Debug.Assert(typeof(T) == typeof(float));
return Vector512.Sin(x.AsSingle()).As<float, T>();
}
#else
if (typeof(T) == typeof(float))
{
return SinOperatorSingle.Invoke(x.AsSingle()).As<float, T>();
@ -91,9 +127,25 @@ namespace System.Numerics.Tensors
Debug.Assert(typeof(T) == typeof(double));
return SinOperatorDouble.Invoke(x.AsDouble()).As<double, T>();
}
#endif
}
}
#if NET9_0_OR_GREATER
// These are still used by SinPiOperator
private readonly struct SinOperatorSingle
{
internal const uint MaxVectorizedValue = 0x49800000u;
internal const uint SignMask = 0x7FFFFFFFu;
}
private readonly struct SinOperatorDouble
{
internal const ulong SignMask = 0x7FFFFFFFFFFFFFFFul;
internal const ulong MaxVectorizedValue = 0x4160000000000000ul;
}
#else
/// <summary>float.Sin(x)</summary>
private readonly struct SinOperatorSingle : IUnaryOperator<float, float>
{
@ -334,5 +386,6 @@ namespace System.Numerics.Tensors
return (poly.AsUInt64() ^ (x.AsUInt64() & Vector512.Create(~SignMask)) ^ odd).AsDouble();
}
}
#endif
}
}

View file

@ -33,13 +33,15 @@ namespace System.Numerics.Tensors
private readonly struct SinPiOperator<T> : IUnaryOperator<T, T>
where T : ITrigonometricFunctions<T>
{
public static bool Vectorizable => typeof(T) == typeof(float) || typeof(T) == typeof(double);
public static bool Vectorizable => (typeof(T) == typeof(float))
|| (typeof(T) == typeof(double));
public static T Invoke(T x) => T.SinPi(x);
public static Vector128<T> Invoke(Vector128<T> x)
{
Vector128<T> xpi = x * Vector128.Create(T.Pi);
if (typeof(T) == typeof(float))
{
if (Vector128.GreaterThanAny(xpi.AsUInt32() & Vector128.Create(SinOperatorSingle.SignMask), Vector128.Create(SinOperatorSingle.MaxVectorizedValue)))
@ -62,6 +64,7 @@ namespace System.Numerics.Tensors
public static Vector256<T> Invoke(Vector256<T> x)
{
Vector256<T> xpi = x * Vector256.Create(T.Pi);
if (typeof(T) == typeof(float))
{
if (Vector256.GreaterThanAny(xpi.AsUInt32() & Vector256.Create(SinOperatorSingle.SignMask), Vector256.Create(SinOperatorSingle.MaxVectorizedValue)))
@ -84,6 +87,7 @@ namespace System.Numerics.Tensors
public static Vector512<T> Invoke(Vector512<T> x)
{
Vector512<T> xpi = x * Vector512.Create(T.Pi);
if (typeof(T) == typeof(float))
{
if (Vector512.GreaterThanAny(xpi.AsUInt32() & Vector512.Create(SinOperatorSingle.SignMask), Vector512.Create(SinOperatorSingle.MaxVectorizedValue)))

View file

@ -262,6 +262,8 @@ namespace System.Numerics
[System.CLSCompliantAttribute(false)]
public static System.Numerics.Vector<System.UInt64> ConvertToUInt64Native(System.Numerics.Vector<System.Double> value) { throw null; }
public static System.Numerics.Vector<T> CopySign<T>(System.Numerics.Vector<T> value, System.Numerics.Vector<T> sign) { throw null; }
public static System.Numerics.Vector<double> Cos(System.Numerics.Vector<double> vector) { throw null; }
public static System.Numerics.Vector<float> Cos(System.Numerics.Vector<float> vector) { throw null; }
public static System.Numerics.Vector<T> Create<T>(T value) { throw null; }
public static System.Numerics.Vector<T> Create<T>(System.ReadOnlySpan<T> values) { throw null; }
public static System.Numerics.Vector<T> CreateSequence<T>(T start, T step) { throw null; }
@ -404,6 +406,10 @@ namespace System.Numerics
public static System.Numerics.Vector<System.UInt32> ShiftRightLogical(System.Numerics.Vector<System.UInt32> value, int shiftCount) { throw null; }
[System.CLSCompliantAttribute(false)]
public static System.Numerics.Vector<System.UInt64> ShiftRightLogical(System.Numerics.Vector<System.UInt64> value, int shiftCount) { throw null; }
public static System.Numerics.Vector<double> Sin(System.Numerics.Vector<double> vector) { throw null; }
public static System.Numerics.Vector<float> Sin(System.Numerics.Vector<float> vector) { throw null; }
public static (System.Numerics.Vector<double> Sin, System.Numerics.Vector<double> Cos) SinCos(System.Numerics.Vector<double> vector) { throw null; }
public static (System.Numerics.Vector<float> Sin, System.Numerics.Vector<float> Cos) SinCos(System.Numerics.Vector<float> vector) { throw null; }
public static System.Numerics.Vector<T> SquareRoot<T>(System.Numerics.Vector<T> value) { throw null; }
[System.CLSCompliantAttribute(false)]
public static unsafe void Store<T>(this System.Numerics.Vector<T> source, T* destination) { throw null; }
@ -486,6 +492,7 @@ namespace System.Numerics
public readonly void CopyTo(float[] array) { }
public readonly void CopyTo(float[] array, int index) { }
public readonly void CopyTo(System.Span<float> destination) { }
public static System.Numerics.Vector2 Cos(System.Numerics.Vector2 vector) { throw null; }
public readonly bool TryCopyTo(System.Span<float> destination) { throw null; }
public static System.Numerics.Vector2 DegreesToRadians(System.Numerics.Vector2 degrees) { throw null; }
public static float Distance(System.Numerics.Vector2 value1, System.Numerics.Vector2 value2) { throw null; }
@ -535,6 +542,8 @@ namespace System.Numerics
public static System.Numerics.Vector2 Round(System.Numerics.Vector2 vector) { throw null; }
public static System.Numerics.Vector2 Round(System.Numerics.Vector2 vector, System.MidpointRounding mode) { throw null; }
public static System.Numerics.Vector2 Reflect(System.Numerics.Vector2 vector, System.Numerics.Vector2 normal) { throw null; }
public static System.Numerics.Vector2 Sin(System.Numerics.Vector2 vector) { throw null; }
public static (System.Numerics.Vector2 Sin, System.Numerics.Vector2 Cos) SinCos(System.Numerics.Vector2 vector) { throw null; }
public static System.Numerics.Vector2 SquareRoot(System.Numerics.Vector2 value) { throw null; }
public static System.Numerics.Vector2 Subtract(System.Numerics.Vector2 left, System.Numerics.Vector2 right) { throw null; }
public override readonly string ToString() { throw null; }
@ -582,6 +591,7 @@ namespace System.Numerics
public readonly void CopyTo(float[] array) { }
public readonly void CopyTo(float[] array, int index) { }
public readonly void CopyTo(System.Span<float> destination) { }
public static System.Numerics.Vector3 Cos(System.Numerics.Vector3 vector) { throw null; }
public readonly bool TryCopyTo(System.Span<float> destination) { throw null; }
public static System.Numerics.Vector3 Cross(System.Numerics.Vector3 vector1, System.Numerics.Vector3 vector2) { throw null; }
public static System.Numerics.Vector3 DegreesToRadians(System.Numerics.Vector3 degrees) { throw null; }
@ -632,6 +642,8 @@ namespace System.Numerics
public static System.Numerics.Vector3 Reflect(System.Numerics.Vector3 vector, System.Numerics.Vector3 normal) { throw null; }
public static System.Numerics.Vector3 Round(System.Numerics.Vector3 vector) { throw null; }
public static System.Numerics.Vector3 Round(System.Numerics.Vector3 vector, System.MidpointRounding mode) { throw null; }
public static System.Numerics.Vector3 Sin(System.Numerics.Vector3 vector) { throw null; }
public static (System.Numerics.Vector3 Sin, System.Numerics.Vector3 Cos) SinCos(System.Numerics.Vector3 vector) { throw null; }
public static System.Numerics.Vector3 SquareRoot(System.Numerics.Vector3 value) { throw null; }
public static System.Numerics.Vector3 Subtract(System.Numerics.Vector3 left, System.Numerics.Vector3 right) { throw null; }
public override readonly string ToString() { throw null; }
@ -681,6 +693,7 @@ namespace System.Numerics
public readonly void CopyTo(float[] array) { }
public readonly void CopyTo(float[] array, int index) { }
public readonly void CopyTo(System.Span<float> destination) { }
public static System.Numerics.Vector4 Cos(System.Numerics.Vector4 vector) { throw null; }
public readonly bool TryCopyTo(System.Span<float> destination) { throw null; }
public static System.Numerics.Vector4 DegreesToRadians(System.Numerics.Vector4 degrees) { throw null; }
public static float Distance(System.Numerics.Vector4 value1, System.Numerics.Vector4 value2) { throw null; }
@ -729,6 +742,8 @@ namespace System.Numerics
public static System.Numerics.Vector4 RadiansToDegrees(System.Numerics.Vector4 radians) { throw null; }
public static System.Numerics.Vector4 Round(System.Numerics.Vector4 vector) { throw null; }
public static System.Numerics.Vector4 Round(System.Numerics.Vector4 vector, System.MidpointRounding mode) { throw null; }
public static System.Numerics.Vector4 Sin(System.Numerics.Vector4 vector) { throw null; }
public static (System.Numerics.Vector4 Sin, System.Numerics.Vector4 Cos) SinCos(System.Numerics.Vector4 vector) { throw null; }
public static System.Numerics.Vector4 SquareRoot(System.Numerics.Vector4 value) { throw null; }
public static System.Numerics.Vector4 Subtract(System.Numerics.Vector4 left, System.Numerics.Vector4 right) { throw null; }
public override readonly string ToString() { throw null; }

View file

@ -4536,6 +4536,22 @@ namespace System.Numerics.Tests
}
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void CosDoubleTest(double value, double expectedResult, double variance)
{
Vector<double> actualResult = Vector.Cos(Vector.Create(value));
AssertEqual(Vector.Create(expectedResult), actualResult, Vector.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector<float> actualResult = Vector.Cos(Vector.Create(value));
AssertEqual(Vector.Create(expectedResult), actualResult, Vector.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpDouble), MemberType = typeof(GenericMathTestMemberData))]
public void ExpDoubleTest(double value, double expectedResult, double variance)
@ -4959,6 +4975,40 @@ namespace System.Numerics.Tests
AssertEqual(Vector.Create(expectedResult), actualResult, Vector<float>.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinDoubleTest(double value, double expectedResult, double variance)
{
Vector<double> actualResult = Vector.Sin(Vector.Create(value));
AssertEqual(Vector.Create(expectedResult), actualResult, Vector.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector<float> actualResult = Vector.Sin(Vector.Create(value));
AssertEqual(Vector.Create(expectedResult), actualResult, Vector.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosDoubleTest(double value, double expectedResultSin, double expectedResultCos, double allowedVarianceSin, double allowedVarianceCos)
{
(Vector<double> resultSin, Vector<double> resultCos) = Vector.SinCos(Vector.Create(value));
AssertEqual(Vector.Create(expectedResultSin), resultSin, Vector.Create(allowedVarianceSin));
AssertEqual(Vector.Create(expectedResultCos), resultCos, Vector.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector<float> resultSin, Vector<float> resultCos) = Vector.SinCos(Vector.Create(value));
AssertEqual(Vector.Create(expectedResultSin), resultSin, Vector.Create(allowedVarianceSin));
AssertEqual(Vector.Create(expectedResultCos), resultCos, Vector.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateDouble), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateDoubleTest(double value, double expectedResult)

View file

@ -1299,6 +1299,14 @@ namespace System.Numerics.Tests
public Vector2 FieldVector;
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector2 actualResult = Vector2.Cos(Vector2.Create(value));
AssertEqual(Vector2.Create(expectedResult), actualResult, Vector2.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpSingle), MemberType = typeof(GenericMathTestMemberData))]
public void ExpSingleTest(float value, float expectedResult, float variance)
@ -1474,6 +1482,23 @@ namespace System.Numerics.Tests
AssertEqual(Vector2.Create(expectedResult), actualResult, Vector2.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector2 actualResult = Vector2.Sin(Vector2.Create(value));
AssertEqual(Vector2.Create(expectedResult), actualResult, Vector2.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector2 resultSin, Vector2 resultCos) = Vector2.SinCos(Vector2.Create(value));
AssertEqual(Vector2.Create(expectedResultSin), resultSin, Vector2.Create(allowedVarianceSin));
AssertEqual(Vector2.Create(expectedResultCos), resultCos, Vector2.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateSingle), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateSingleTest(float value, float expectedResult)

View file

@ -1349,6 +1349,14 @@ namespace System.Numerics.Tests
public Vector3 FieldVector;
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector3 actualResult = Vector3.Cos(Vector3.Create(value));
AssertEqual(Vector3.Create(expectedResult), actualResult, Vector3.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpSingle), MemberType = typeof(GenericMathTestMemberData))]
public void ExpSingleTest(float value, float expectedResult, float variance)
@ -1524,6 +1532,23 @@ namespace System.Numerics.Tests
AssertEqual(Vector3.Create(expectedResult), actualResult, Vector3.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector3 actualResult = Vector3.Sin(Vector3.Create(value));
AssertEqual(Vector3.Create(expectedResult), actualResult, Vector3.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector3 resultSin, Vector3 resultCos) = Vector3.SinCos(Vector3.Create(value));
AssertEqual(Vector3.Create(expectedResultSin), resultSin, Vector3.Create(allowedVarianceSin));
AssertEqual(Vector3.Create(expectedResultCos), resultCos, Vector3.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateSingle), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateSingleTest(float value, float expectedResult)

View file

@ -1724,6 +1724,14 @@ namespace System.Numerics.Tests
}
#pragma warning restore 0169
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector4 actualResult = Vector4.Cos(Vector4.Create(value));
AssertEqual(Vector4.Create(expectedResult), actualResult, Vector4.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpSingle), MemberType = typeof(GenericMathTestMemberData))]
public void ExpSingleTest(float value, float expectedResult, float variance)
@ -1899,6 +1907,23 @@ namespace System.Numerics.Tests
AssertEqual(Vector4.Create(expectedResult), actualResult, Vector4.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector4 actualResult = Vector4.Sin(Vector4.Create(value));
AssertEqual(Vector4.Create(expectedResult), actualResult, Vector4.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector4 resultSin, Vector4 resultCos) = Vector4.SinCos(Vector4.Create(value));
AssertEqual(Vector4.Create(expectedResultSin), resultSin, Vector4.Create(allowedVarianceSin));
AssertEqual(Vector4.Create(expectedResultCos), resultCos, Vector4.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateSingle), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateSingleTest(float value, float expectedResult)

View file

@ -281,11 +281,11 @@ namespace System.Numerics
/// <returns>The resulting quaternion.</returns>
public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
{
// Roll first, about axis the object is facing, then
// pitch upward, then yaw to face into the new heading
(float sr, float cr) = float.SinCos(roll * 0.5f);
(float sp, float cp) = float.SinCos(pitch * 0.5f);
(float sy, float cy) = float.SinCos(yaw * 0.5f);
(Vector3 sin, Vector3 cos) = Vector3.SinCos(Vector3.Create(roll, pitch, yaw) * 0.5f);
(float sr, float cr) = (sin.X, cos.X);
(float sp, float cp) = (sin.Y, cos.Y);
(float sy, float cy) = (sin.Z, cos.Z);
Quaternion result;

View file

@ -537,6 +537,48 @@ namespace System.Numerics
return result;
}
internal static Vector<T> Cos<T>(Vector<T> vector)
where T : ITrigonometricFunctions<T>
{
Unsafe.SkipInit(out Vector<T> result);
for (int index = 0; index < Vector<T>.Count; index++)
{
T value = T.Cos(vector.GetElementUnsafe(index));
result.SetElementUnsafe(index, value);
}
return result;
}
/// <inheritdoc cref="Vector128.Cos(Vector128{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<double> Cos(Vector<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.CosDouble<Vector<double>, Vector<long>>(vector);
}
else
{
return Cos<double>(vector);
}
}
/// <inheritdoc cref="Vector128.Cos(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<float> Cos(Vector<float> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.CosSingle<Vector<float>, Vector<int>, Vector<double>, Vector<long>>(vector);
}
else
{
return Cos<float>(vector);
}
}
/// <inheritdoc cref="ISimdVector{TSelf, T}.CopySign(TSelf, TSelf)" />
[Intrinsic]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -807,7 +849,7 @@ namespace System.Numerics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpDouble<Vector<double>, Vector<long>, Vector<ulong>>(vector);
return VectorMath.ExpDouble<Vector<double>, Vector<ulong>>(vector);
}
else
{
@ -2423,6 +2465,92 @@ namespace System.Numerics
[CLSCompliant(false)]
public static Vector<ulong> ShiftRightLogical(Vector<ulong> value, int shiftCount) => value >>> shiftCount;
internal static Vector<T> Sin<T>(Vector<T> vector)
where T : ITrigonometricFunctions<T>
{
Unsafe.SkipInit(out Vector<T> result);
for (int index = 0; index < Vector<T>.Count; index++)
{
T value = T.Sin(vector.GetElementUnsafe(index));
result.SetElementUnsafe(index, value);
}
return result;
}
/// <inheritdoc cref="Vector128.Sin(Vector128{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<double> Sin(Vector<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinDouble<Vector<double>, Vector<long>>(vector);
}
else
{
return Sin<double>(vector);
}
}
/// <inheritdoc cref="Vector128.Sin(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<float> Sin(Vector<float> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinSingle<Vector<float>, Vector<int>, Vector<double>, Vector<long>>(vector);
}
else
{
return Sin<float>(vector);
}
}
internal static (Vector<T> Sin, Vector<T> Cos) SinCos<T>(Vector<T> vector)
where T : ITrigonometricFunctions<T>
{
Unsafe.SkipInit(out Vector<T> sinResult);
Unsafe.SkipInit(out Vector<T> cosResult);
for (int index = 0; index < Vector<T>.Count; index++)
{
(T sinValue, T cosValue) = T.SinCos(vector.GetElementUnsafe(index));
sinResult.SetElementUnsafe(index, sinValue);
cosResult.SetElementUnsafe(index, cosValue);
}
return (sinResult, cosResult);
}
/// <inheritdoc cref="Vector128.SinCos(Vector128{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector<double> Sin, Vector<double> Cos) SinCos(Vector<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinCosDouble<Vector<double>, Vector<long>>(vector);
}
else
{
return SinCos<double>(vector);
}
}
/// <inheritdoc cref="Vector128.SinCos(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector<float> Sin, Vector<float> Cos) SinCos(Vector<float> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinCosSingle<Vector<float>, Vector<int>, Vector<double>, Vector<long>>(vector);
}
else
{
return SinCos<float>(vector);
}
}
/// <summary>Computes the square root of a vector on a per-element basis.</summary>
/// <param name="value">The vector whose square root is to be computed.</param>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>

View file

@ -280,6 +280,10 @@ namespace System.Numerics
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 CopySign(Vector2 value, Vector2 sign) => Vector128.CopySign(value.AsVector128Unsafe(), sign.AsVector128Unsafe()).AsVector2();
/// <inheritdoc cref="Vector4.Cos(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Cos(Vector2 vector) => Vector128.Cos(vector.AsVector128()).AsVector2();
/// <summary>Creates a new <see cref="Vector2" /> object whose two elements have the same value.</summary>
/// <param name="value">The value to assign to all two elements.</param>
/// <returns>A new <see cref="Vector2" /> whose two elements have the same value.</returns>
@ -361,7 +365,7 @@ namespace System.Numerics
/// <inheritdoc cref="Vector4.Exp(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Exp(Vector2 vector) => Vector128.Exp(vector.AsVector128Unsafe()).AsVector2();
public static Vector2 Exp(Vector2 vector) => Vector128.Exp(vector.AsVector128()).AsVector2();
/// <inheritdoc cref="Vector128.MultiplyAddEstimate(Vector128{float}, Vector128{float}, Vector128{float})" />
[Intrinsic]
@ -385,11 +389,11 @@ namespace System.Numerics
/// <inheritdoc cref="Vector4.Log2(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Log(Vector2 vector) => Vector128.Log(vector.AsVector128Unsafe()).AsVector2();
public static Vector2 Log(Vector2 vector) => Vector128.Log(Vector4.Create(vector, 1.0f, 1.0f).AsVector128()).AsVector2();
/// <inheritdoc cref="Vector4.Log(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Log2(Vector2 vector) => Vector128.Log2(vector.AsVector128Unsafe()).AsVector2();
public static Vector2 Log2(Vector2 vector) => Vector128.Log2(Vector4.Create(vector, 1.0f, 1.0f).AsVector128()).AsVector2();
/// <inheritdoc cref="ISimdVector{TSelf, T}.Max(TSelf, TSelf)" />
[Intrinsic]
@ -507,6 +511,18 @@ namespace System.Numerics
[Intrinsic]
public static Vector2 Round(Vector2 vector, MidpointRounding mode) => Vector128.Round(vector.AsVector128Unsafe(), mode).AsVector2();
/// <inheritdoc cref="Vector4.Sin(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2 Sin(Vector2 vector) => Vector128.Sin(vector.AsVector128()).AsVector2();
/// <inheritdoc cref="Vector4.SinCos(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector2 Sin, Vector2 Cos) SinCos(Vector2 vector)
{
(Vector128<float> sin, Vector128<float> cos) = Vector128.SinCos(vector.AsVector128());
return (sin.AsVector2(), cos.AsVector2());
}
/// <summary>Returns a vector whose elements are the square root of each of a specified vector's elements.</summary>
/// <param name="value">A vector.</param>
/// <returns>The square root vector.</returns>

View file

@ -301,6 +301,10 @@ namespace System.Numerics
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 CopySign(Vector3 value, Vector3 sign) => Vector128.CopySign(value.AsVector128Unsafe(), sign.AsVector128Unsafe()).AsVector3();
/// <inheritdoc cref="Vector4.Cos(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Cos(Vector3 vector) => Vector128.Cos(vector.AsVector128()).AsVector3();
/// <summary>Creates a new <see cref="Vector3" /> object whose three elements have the same value.</summary>
/// <param name="value">The value to assign to all three elements.</param>
/// <returns>A new <see cref="Vector3" /> whose three elements have the same value.</returns>
@ -418,7 +422,7 @@ namespace System.Numerics
/// <inheritdoc cref="Vector4.Exp(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Exp(Vector3 vector) => Vector128.Exp(vector.AsVector128Unsafe()).AsVector3();
public static Vector3 Exp(Vector3 vector) => Vector128.Exp(vector.AsVector128()).AsVector3();
/// <inheritdoc cref="Vector128.MultiplyAddEstimate(Vector128{float}, Vector128{float}, Vector128{float})" />
[Intrinsic]
@ -442,11 +446,11 @@ namespace System.Numerics
/// <inheritdoc cref="Vector4.Log2(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Log(Vector3 vector) => Vector128.Log(vector.AsVector128Unsafe()).AsVector3();
public static Vector3 Log(Vector3 vector) => Vector128.Log(Vector4.Create(vector, 1.0f).AsVector128()).AsVector3();
/// <inheritdoc cref="Vector4.Log(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Log2(Vector3 vector) => Vector128.Log2(vector.AsVector128Unsafe()).AsVector3();
public static Vector3 Log2(Vector3 vector) => Vector128.Log2(Vector4.Create(vector, 1.0f).AsVector128()).AsVector3();
/// <inheritdoc cref="ISimdVector{TSelf, T}.Max(TSelf, TSelf)" />
[Intrinsic]
@ -564,6 +568,18 @@ namespace System.Numerics
[Intrinsic]
public static Vector3 Round(Vector3 vector, MidpointRounding mode) => Vector128.Round(vector.AsVector128Unsafe(), mode).AsVector3();
/// <inheritdoc cref="Vector4.Sin(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3 Sin(Vector3 vector) => Vector128.Sin(vector.AsVector128()).AsVector3();
/// <inheritdoc cref="Vector4.SinCos(Vector4)" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector3 Sin, Vector3 Cos) SinCos(Vector3 vector)
{
(Vector128<float> sin, Vector128<float> cos) = Vector128.SinCos(vector.AsVector128());
return (sin.AsVector3(), cos.AsVector3());
}
/// <summary>Returns a vector whose elements are the square root of each of a specified vector's elements.</summary>
/// <param name="value">A vector.</param>
/// <returns>The square root vector.</returns>

View file

@ -320,6 +320,10 @@ namespace System.Numerics
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 CopySign(Vector4 value, Vector4 sign) => Vector128.CopySign(value.AsVector128(), sign.AsVector128()).AsVector4();
/// <inheritdoc cref="Vector128.Cos(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Cos(Vector4 vector) => Vector128.Cos(vector.AsVector128()).AsVector4();
/// <summary>Creates a new <see cref="Vector4" /> object whose four elements have the same value.</summary>
/// <param name="value">The value to assign to all four elements.</param>
/// <returns>A new <see cref="Vector4" /> whose four elements have the same value.</returns>
@ -557,6 +561,18 @@ namespace System.Numerics
[Intrinsic]
public static Vector4 Round(Vector4 vector, MidpointRounding mode) => Vector128.Round(vector.AsVector128(), mode).AsVector4();
/// <inheritdoc cref="Vector128.Sin(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Sin(Vector4 vector) => Vector128.Sin(vector.AsVector128()).AsVector4();
/// <inheritdoc cref="Vector128.SinCos(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector4 Sin, Vector4 Cos) SinCos(Vector4 vector)
{
(Vector128<float> sin, Vector128<float> cos) = Vector128.SinCos(vector.AsVector128());
return (sin.AsVector4(), cos.AsVector4());
}
/// <summary>Returns a vector whose elements are the square root of each of a specified vector's elements.</summary>
/// <param name="value">A vector.</param>
/// <returns>The square root vector.</returns>

View file

@ -1,140 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
namespace System.Numerics
{
internal static class VectorMath
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> ConditionalSelectBitwise(Vector128<float> selector, Vector128<float> ifTrue, Vector128<float> ifFalse)
{
// This implementation is based on the DirectX Math Library XMVector4NotEqual method
// https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl
if (AdvSimd.IsSupported)
{
return AdvSimd.BitwiseSelect(selector, ifTrue, ifFalse);
}
else if (Sse.IsSupported)
{
return Sse.Or(Sse.And(ifTrue, selector), Sse.AndNot(selector, ifFalse));
}
else
{
// Redundant test so we won't prejit remainder of this method on platforms without AdvSimd.
throw new PlatformNotSupportedException();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<double> ConditionalSelectBitwise(Vector128<double> selector, Vector128<double> ifTrue, Vector128<double> ifFalse)
{
// This implementation is based on the DirectX Math Library XMVector4NotEqual method
// https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl
if (AdvSimd.IsSupported)
{
return AdvSimd.BitwiseSelect(selector, ifTrue, ifFalse);
}
else if (Sse2.IsSupported)
{
return Sse2.Or(Sse2.And(ifTrue, selector), Sse2.AndNot(selector, ifFalse));
}
else
{
// Redundant test so we won't prejit remainder of this method on platforms without AdvSimd.
throw new PlatformNotSupportedException();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Equal(Vector128<float> vector1, Vector128<float> vector2)
{
// This implementation is based on the DirectX Math Library XMVector4Equal method
// https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl
if (AdvSimd.Arm64.IsSupported)
{
Vector128<uint> vResult = AdvSimd.CompareEqual(vector1, vector2).AsUInt32();
Vector64<byte> vResult0 = vResult.GetLower().AsByte();
Vector64<byte> vResult1 = vResult.GetUpper().AsByte();
Vector64<byte> vTemp10 = AdvSimd.Arm64.ZipLow(vResult0, vResult1);
Vector64<byte> vTemp11 = AdvSimd.Arm64.ZipHigh(vResult0, vResult1);
Vector64<ushort> vTemp21 = AdvSimd.Arm64.ZipHigh(vTemp10.AsUInt16(), vTemp11.AsUInt16());
return vTemp21.AsUInt32().GetElement(1) == 0xFFFFFFFF;
}
else if (Sse.IsSupported)
{
return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) == 0;
}
else
{
// Redundant test so we won't prejit remainder of this method on platforms without AdvSimd.
throw new PlatformNotSupportedException();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> Lerp(Vector128<float> a, Vector128<float> b, Vector128<float> t)
{
// This implementation is based on the DirectX Math Library XMVectorLerp method
// https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl
if (AdvSimd.IsSupported)
{
return AdvSimd.FusedMultiplyAdd(a, AdvSimd.Subtract(b, a), t);
}
else if (Fma.IsSupported)
{
return Fma.MultiplyAdd(Sse.Subtract(b, a), t, a);
}
else if (Sse.IsSupported)
{
return Sse.Add(Sse.Multiply(a, Sse.Subtract(Vector128.Create(1.0f), t)), Sse.Multiply(b, t));
}
else
{
// Redundant test so we won't prejit remainder of this method on platforms without AdvSimd.
throw new PlatformNotSupportedException();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool NotEqual(Vector128<float> vector1, Vector128<float> vector2)
{
// This implementation is based on the DirectX Math Library XMVector4NotEqual method
// https://github.com/microsoft/DirectXMath/blob/master/Inc/DirectXMathVector.inl
if (AdvSimd.Arm64.IsSupported)
{
Vector128<uint> vResult = AdvSimd.CompareEqual(vector1, vector2).AsUInt32();
Vector64<byte> vResult0 = vResult.GetLower().AsByte();
Vector64<byte> vResult1 = vResult.GetUpper().AsByte();
Vector64<byte> vTemp10 = AdvSimd.Arm64.ZipLow(vResult0, vResult1);
Vector64<byte> vTemp11 = AdvSimd.Arm64.ZipHigh(vResult0, vResult1);
Vector64<ushort> vTemp21 = AdvSimd.Arm64.ZipHigh(vTemp10.AsUInt16(), vTemp11.AsUInt16());
return vTemp21.AsUInt32().GetElement(1) != 0xFFFFFFFF;
}
else if (Sse.IsSupported)
{
return Sse.MoveMask(Sse.CompareNotEqual(vector1, vector2)) != 0;
}
else
{
// Redundant test so we won't prejit remainder of this method on platforms without AdvSimd.
throw new PlatformNotSupportedException();
}
}
}
}

View file

@ -824,6 +824,47 @@ namespace System.Runtime.Intrinsics
Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), vector);
}
/// <inheritdoc cref="Vector64.Cos(Vector64{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<double> Cos(Vector128<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.CosDouble<Vector128<double>, Vector128<long>>(vector);
}
else
{
return Create(
Vector64.Cos(vector._lower),
Vector64.Cos(vector._upper)
);
}
}
/// <inheritdoc cref="Vector64.Cos(Vector64{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> Cos(Vector128<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector256.IsHardwareAccelerated)
{
return VectorMath.CosSingle<Vector128<float>, Vector128<int>, Vector256<double>, Vector256<long>>(vector);
}
else
{
return VectorMath.CosSingle<Vector128<float>, Vector128<int>, Vector128<double>, Vector128<long>>(vector);
}
}
else
{
return Create(
Vector64.Cos(vector._lower),
Vector64.Cos(vector._upper)
);
}
}
/// <summary>Creates a new <see cref="Vector128{T}" /> instance with all elements initialized to the specified value.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="value">The value that all elements will be initialized to.</param>
@ -1591,7 +1632,7 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpDouble<Vector128<double>, Vector128<long>, Vector128<ulong>>(vector);
return VectorMath.ExpDouble<Vector128<double>, Vector128<ulong>>(vector);
}
else
{
@ -1608,7 +1649,14 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpSingle<Vector128<float>, Vector128<uint>, Vector128<double>, Vector128<ulong>>(vector);
if (Vector256.IsHardwareAccelerated)
{
return VectorMath.ExpSingle<Vector128<float>, Vector128<uint>, Vector256<double>, Vector256<ulong>>(vector);
}
else
{
return VectorMath.ExpSingle<Vector128<float>, Vector128<uint>, Vector128<double>, Vector128<ulong>>(vector);
}
}
else
{
@ -1855,7 +1903,14 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.HypotSingle<Vector128<float>, Vector128<double>>(x, y);
if (Vector256.IsHardwareAccelerated)
{
return VectorMath.HypotSingle<Vector128<float>, Vector256<double>>(x, y);
}
else
{
return VectorMath.HypotSingle<Vector128<float>, Vector128<double>>(x, y);
}
}
else
{
@ -3144,6 +3199,94 @@ namespace System.Runtime.Intrinsics
return result;
}
/// <inheritdoc cref="Vector64.Sin(Vector64{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<double> Sin(Vector128<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinDouble<Vector128<double>, Vector128<long>>(vector);
}
else
{
return Create(
Vector64.Sin(vector._lower),
Vector64.Sin(vector._upper)
);
}
}
/// <inheritdoc cref="Vector64.Sin(Vector64{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> Sin(Vector128<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector256.IsHardwareAccelerated)
{
return VectorMath.SinSingle<Vector128<float>, Vector128<int>, Vector256<double>, Vector256<long>>(vector);
}
else
{
return VectorMath.SinSingle<Vector128<float>, Vector128<int>, Vector128<double>, Vector128<long>>(vector);
}
}
else
{
return Create(
Vector64.Sin(vector._lower),
Vector64.Sin(vector._upper)
);
}
}
/// <inheritdoc cref="Vector64.Cos(Vector64{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector128<double> Sin, Vector128<double> Cos) SinCos(Vector128<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinCosDouble<Vector128<double>, Vector128<long>>(vector);
}
else
{
(Vector64<double> sinLower, Vector64<double> cosLower) = Vector64.SinCos(vector._lower);
(Vector64<double> sinUpper, Vector64<double> cosUpper) = Vector64.SinCos(vector._upper);
return (
Create(sinLower, sinUpper),
Create(cosLower, cosUpper)
);
}
}
/// <inheritdoc cref="Vector64.Cos(Vector64{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector128<float> Sin, Vector128<float> Cos) SinCos(Vector128<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector256.IsHardwareAccelerated)
{
return VectorMath.SinCosSingle<Vector128<float>, Vector128<int>, Vector256<double>, Vector256<long>>(vector);
}
else
{
return VectorMath.SinCosSingle<Vector128<float>, Vector128<int>, Vector128<double>, Vector128<long>>(vector);
}
}
else
{
(Vector64<float> sinLower, Vector64<float> cosLower) = Vector64.SinCos(vector._lower);
(Vector64<float> sinUpper, Vector64<float> cosUpper) = Vector64.SinCos(vector._upper);
return (
Create(sinLower, sinUpper),
Create(cosLower, cosUpper)
);
}
}
/// <summary>Computes the square root of a vector on a per-element basis.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="vector">The vector whose square root is to be computed.</param>

View file

@ -663,6 +663,47 @@ namespace System.Runtime.Intrinsics
Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), vector);
}
/// <inheritdoc cref="Vector128.Cos(Vector128{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<double> Cos(Vector256<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.CosDouble<Vector256<double>, Vector256<long>>(vector);
}
else
{
return Create(
Vector128.Cos(vector._lower),
Vector128.Cos(vector._upper)
);
}
}
/// <inheritdoc cref="Vector128.Cos(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<float> Cos(Vector256<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector512.IsHardwareAccelerated)
{
return VectorMath.CosSingle<Vector256<float>, Vector256<int>, Vector512<double>, Vector512<long>>(vector);
}
else
{
return VectorMath.CosSingle<Vector256<float>, Vector256<int>, Vector256<double>, Vector256<long>>(vector);
}
}
else
{
return Create(
Vector128.Cos(vector._lower),
Vector128.Cos(vector._upper)
);
}
}
/// <summary>Creates a new <see cref="Vector256{T}" /> instance with all elements initialized to the specified value.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="value">The value that all elements will be initialized to.</param>
@ -1509,7 +1550,7 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpDouble<Vector256<double>, Vector256<long>, Vector256<ulong>>(vector);
return VectorMath.ExpDouble<Vector256<double>, Vector256<ulong>>(vector);
}
else
{
@ -1526,7 +1567,14 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpSingle<Vector256<float>, Vector256<uint>, Vector256<double>, Vector256<ulong>>(vector);
if (Vector512.IsHardwareAccelerated)
{
return VectorMath.ExpSingle<Vector256<float>, Vector256<uint>, Vector512<double>, Vector512<ulong>>(vector);
}
else
{
return VectorMath.ExpSingle<Vector256<float>, Vector256<uint>, Vector256<double>, Vector256<ulong>>(vector);
}
}
else
{
@ -1771,7 +1819,14 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.HypotSingle<Vector256<float>, Vector256<double>>(x, y);
if (Vector512.IsHardwareAccelerated)
{
return VectorMath.HypotSingle<Vector256<float>, Vector512<double>>(x, y);
}
else
{
return VectorMath.HypotSingle<Vector256<float>, Vector256<double>>(x, y);
}
}
else
{
@ -3027,6 +3082,94 @@ namespace System.Runtime.Intrinsics
return result;
}
/// <inheritdoc cref="Vector128.Sin(Vector128{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<double> Sin(Vector256<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinDouble<Vector256<double>, Vector256<long>>(vector);
}
else
{
return Create(
Vector128.Sin(vector._lower),
Vector128.Sin(vector._upper)
);
}
}
/// <inheritdoc cref="Vector128.Sin(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector256<float> Sin(Vector256<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector512.IsHardwareAccelerated)
{
return VectorMath.SinSingle<Vector256<float>, Vector256<int>, Vector512<double>, Vector512<long>>(vector);
}
else
{
return VectorMath.SinSingle<Vector256<float>, Vector256<int>, Vector256<double>, Vector256<long>>(vector);
}
}
else
{
return Create(
Vector128.Sin(vector._lower),
Vector128.Sin(vector._upper)
);
}
}
/// <inheritdoc cref="Vector128.Cos(Vector128{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector256<double> Sin, Vector256<double> Cos) SinCos(Vector256<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinCosDouble<Vector256<double>, Vector256<long>>(vector);
}
else
{
(Vector128<double> sinLower, Vector128<double> cosLower) = Vector128.SinCos(vector._lower);
(Vector128<double> sinUpper, Vector128<double> cosUpper) = Vector128.SinCos(vector._upper);
return (
Create(sinLower, sinUpper),
Create(cosLower, cosUpper)
);
}
}
/// <inheritdoc cref="Vector128.Cos(Vector128{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector256<float> Sin, Vector256<float> Cos) SinCos(Vector256<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector512.IsHardwareAccelerated)
{
return VectorMath.SinCosSingle<Vector256<float>, Vector256<int>, Vector512<double>, Vector512<long>>(vector);
}
else
{
return VectorMath.SinCosSingle<Vector256<float>, Vector256<int>, Vector256<double>, Vector256<long>>(vector);
}
}
else
{
(Vector128<float> sinLower, Vector128<float> cosLower) = Vector128.SinCos(vector._lower);
(Vector128<float> sinUpper, Vector128<float> cosUpper) = Vector128.SinCos(vector._upper);
return (
Create(sinLower, sinUpper),
Create(cosLower, cosUpper)
);
}
}
/// <summary>Computes the square root of a vector on a per-element basis.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="vector">The vector whose square root is to be computed.</param>

View file

@ -589,6 +589,40 @@ namespace System.Runtime.Intrinsics
Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), vector);
}
/// <inheritdoc cref="Vector256.Cos(Vector256{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector512<double> Cos(Vector512<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.CosDouble<Vector512<double>, Vector512<long>>(vector);
}
else
{
return Create(
Vector256.Cos(vector._lower),
Vector256.Cos(vector._upper)
);
}
}
/// <inheritdoc cref="Vector256.Cos(Vector256{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector512<float> Cos(Vector512<float> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.CosSingle<Vector512<float>, Vector512<int>, Vector512<double>, Vector512<long>>(vector);
}
else
{
return Create(
Vector256.Cos(vector._lower),
Vector256.Cos(vector._upper)
);
}
}
/// <summary>Creates a new <see cref="Vector512{T}" /> instance with all elements initialized to the specified value.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="value">The value that all elements will be initialized to.</param>
@ -1572,7 +1606,7 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpDouble<Vector512<double>, Vector512<long>, Vector512<ulong>>(vector);
return VectorMath.ExpDouble<Vector512<double>, Vector512<ulong>>(vector);
}
else
{
@ -3089,6 +3123,80 @@ namespace System.Runtime.Intrinsics
return result;
}
/// <inheritdoc cref="Vector256.Sin(Vector256{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector512<double> Sin(Vector512<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinDouble<Vector512<double>, Vector512<long>>(vector);
}
else
{
return Create(
Vector256.Sin(vector._lower),
Vector256.Sin(vector._upper)
);
}
}
/// <inheritdoc cref="Vector256.Sin(Vector256{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector512<float> Sin(Vector512<float> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinSingle<Vector512<float>, Vector512<int>, Vector512<double>, Vector512<long>>(vector);
}
else
{
return Create(
Vector256.Sin(vector._lower),
Vector256.Sin(vector._upper)
);
}
}
/// <inheritdoc cref="Vector256.Cos(Vector256{double})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector512<double> Sin, Vector512<double> Cos) SinCos(Vector512<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinCosDouble<Vector512<double>, Vector512<long>>(vector);
}
else
{
(Vector256<double> sinLower, Vector256<double> cosLower) = Vector256.SinCos(vector._lower);
(Vector256<double> sinUpper, Vector256<double> cosUpper) = Vector256.SinCos(vector._upper);
return (
Create(sinLower, sinUpper),
Create(cosLower, cosUpper)
);
}
}
/// <inheritdoc cref="Vector256.Cos(Vector256{float})" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector512<float> Sin, Vector512<float> Cos) SinCos(Vector512<float> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinCosSingle<Vector512<float>, Vector512<int>, Vector512<double>, Vector512<long>>(vector);
}
else
{
(Vector256<float> sinLower, Vector256<float> cosLower) = Vector256.SinCos(vector._lower);
(Vector256<float> sinUpper, Vector256<float> cosUpper) = Vector256.SinCos(vector._upper);
return (
Create(sinLower, sinUpper),
Create(cosLower, cosUpper)
);
}
}
/// <summary>Computes the square root of a vector on a per-element basis.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="vector">The vector whose square root is to be computed.</param>

View file

@ -607,6 +607,59 @@ namespace System.Runtime.Intrinsics
Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), vector);
}
internal static Vector64<T> Cos<T>(Vector64<T> vector)
where T : ITrigonometricFunctions<T>
{
Unsafe.SkipInit(out Vector64<T> result);
for (int index = 0; index < Vector64<T>.Count; index++)
{
T value = T.Cos(vector.GetElementUnsafe(index));
result.SetElementUnsafe(index, value);
}
return result;
}
/// <summary>Computes the cos of each element in a vector.</summary>
/// <param name="vector">The vector that will have its Cos computed.</param>
/// <returns>A vector whose elements are the cos of the elements in <paramref name="vector" />.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector64<double> Cos(Vector64<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.CosDouble<Vector64<double>, Vector64<long>>(vector);
}
else
{
return Cos<double>(vector);
}
}
/// <summary>Computes the cos of each element in a vector.</summary>
/// <param name="vector">The vector that will have its Cos computed.</param>
/// <returns>A vector whose elements are the cos of the elements in <paramref name="vector" />.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector64<float> Cos(Vector64<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector128.IsHardwareAccelerated)
{
return VectorMath.CosSingle<Vector64<float>, Vector64<int>, Vector128<double>, Vector128<long>>(vector);
}
else
{
return VectorMath.CosSingle<Vector64<float>, Vector64<int>, Vector64<double>, Vector64<long>>(vector);
}
}
else
{
return Cos<float>(vector);
}
}
/// <summary>Creates a new <see cref="Vector64{T}" /> instance with all elements initialized to the specified value.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="value">The value that all elements will be initialized to.</param>
@ -1248,7 +1301,7 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpDouble<Vector64<double>, Vector64<long>, Vector64<ulong>>(vector);
return VectorMath.ExpDouble<Vector64<double>, Vector64<ulong>>(vector);
}
else
{
@ -1264,7 +1317,14 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.ExpSingle<Vector64<float>, Vector64<uint>, Vector64<double>, Vector64<ulong>>(vector);
if (Vector128.IsHardwareAccelerated)
{
return VectorMath.ExpSingle<Vector64<float>, Vector64<uint>, Vector128<double>, Vector128<ulong>>(vector);
}
else
{
return VectorMath.ExpSingle<Vector64<float>, Vector64<uint>, Vector64<double>, Vector64<ulong>>(vector);
}
}
else
{
@ -1574,7 +1634,14 @@ namespace System.Runtime.Intrinsics
{
if (IsHardwareAccelerated)
{
return VectorMath.HypotSingle<Vector64<float>, Vector64<double>>(x, y);
if (Vector128.IsHardwareAccelerated)
{
return VectorMath.HypotSingle<Vector64<float>, Vector128<double>>(x, y);
}
else
{
return VectorMath.HypotSingle<Vector64<float>, Vector64<double>>(x, y);
}
}
else
{
@ -3002,6 +3069,114 @@ namespace System.Runtime.Intrinsics
return result;
}
internal static Vector64<T> Sin<T>(Vector64<T> vector)
where T : ITrigonometricFunctions<T>
{
Unsafe.SkipInit(out Vector64<T> result);
for (int index = 0; index < Vector64<T>.Count; index++)
{
T value = T.Sin(vector.GetElementUnsafe(index));
result.SetElementUnsafe(index, value);
}
return result;
}
/// <summary>Computes the sin of each element in a vector.</summary>
/// <param name="vector">The vector that will have its Sin computed.</param>
/// <returns>A vector whose elements are the sin of the elements in <paramref name="vector" />.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector64<double> Sin(Vector64<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinDouble<Vector64<double>, Vector64<long>>(vector);
}
else
{
return Sin<double>(vector);
}
}
/// <summary>Computes the sin of each element in a vector.</summary>
/// <param name="vector">The vector that will have its Sin computed.</param>
/// <returns>A vector whose elements are the sin of the elements in <paramref name="vector" />.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector64<float> Sin(Vector64<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector128.IsHardwareAccelerated)
{
return VectorMath.SinSingle<Vector64<float>, Vector64<int>, Vector128<double>, Vector128<long>>(vector);
}
else
{
return VectorMath.SinSingle<Vector64<float>, Vector64<int>, Vector64<double>, Vector64<long>>(vector);
}
}
else
{
return Sin<float>(vector);
}
}
internal static (Vector64<T> Sin, Vector64<T> Cos) SinCos<T>(Vector64<T> vector)
where T : ITrigonometricFunctions<T>
{
Unsafe.SkipInit(out Vector64<T> sinResult);
Unsafe.SkipInit(out Vector64<T> cosResult);
for (int index = 0; index < Vector64<T>.Count; index++)
{
(T sinValue, T cosValue) = T.SinCos(vector.GetElementUnsafe(index));
sinResult.SetElementUnsafe(index, sinValue);
cosResult.SetElementUnsafe(index, cosValue);
}
return (sinResult, cosResult);
}
/// <summary>Computes the sincos of each element in a vector.</summary>
/// <param name="vector">The vector that will have its SinCos computed.</param>
/// <returns>A vector whose elements are the sincos of the elements in <paramref name="vector" />.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector64<double> Sin, Vector64<double> Cos) SinCos(Vector64<double> vector)
{
if (IsHardwareAccelerated)
{
return VectorMath.SinCosDouble<Vector64<double>, Vector64<long>>(vector);
}
else
{
return SinCos<double>(vector);
}
}
/// <summary>Computes the sincos of each element in a vector.</summary>
/// <param name="vector">The vector that will have its SinCos computed.</param>
/// <returns>A vector whose elements are the sincos of the elements in <paramref name="vector" />.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static (Vector64<float> Sin, Vector64<float> Cos) SinCos(Vector64<float> vector)
{
if (IsHardwareAccelerated)
{
if (Vector128.IsHardwareAccelerated)
{
return VectorMath.SinCosSingle<Vector64<float>, Vector64<int>, Vector128<double>, Vector128<long>>(vector);
}
else
{
return VectorMath.SinCosSingle<Vector64<float>, Vector64<int>, Vector64<double>, Vector64<long>>(vector);
}
}
else
{
return SinCos<float>(vector);
}
}
/// <summary>Computes the square root of a vector on a per-element basis.</summary>
/// <typeparam name="T">The type of the elements in the vector.</typeparam>
/// <param name="vector">The vector whose square root is to be computed.</param>

View file

@ -71,6 +71,8 @@ namespace System.Runtime.Intrinsics
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector128<T> vector, System.Span<T> destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector128<T> vector, T[] destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector128<T> vector, T[] destination, int startIndex) { }
public static System.Runtime.Intrinsics.Vector128<double> Cos(System.Runtime.Intrinsics.Vector128<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector128<float> Cos(System.Runtime.Intrinsics.Vector128<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector128<System.Byte> Create(byte value) { throw null; }
public static System.Runtime.Intrinsics.Vector128<System.Byte> Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15) { throw null; }
public static System.Runtime.Intrinsics.Vector128<System.Double> Create(double value) { throw null; }
@ -299,6 +301,10 @@ namespace System.Runtime.Intrinsics
[System.CLSCompliantAttribute(false)]
public static System.Runtime.Intrinsics.Vector128<ulong> Shuffle(System.Runtime.Intrinsics.Vector128<ulong> vector, System.Runtime.Intrinsics.Vector128<ulong> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector128<double> Shuffle(System.Runtime.Intrinsics.Vector128<double> vector, System.Runtime.Intrinsics.Vector128<long> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector128<double> Sin(System.Runtime.Intrinsics.Vector128<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector128<float> Sin(System.Runtime.Intrinsics.Vector128<float> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector128<double> Sin, System.Runtime.Intrinsics.Vector128<double> Cos) SinCos(System.Runtime.Intrinsics.Vector128<double> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector128<float> Sin, System.Runtime.Intrinsics.Vector128<float> Cos) SinCos(System.Runtime.Intrinsics.Vector128<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector128<T> Sqrt<T>(System.Runtime.Intrinsics.Vector128<T> vector) { throw null; }
[System.CLSCompliantAttribute(false)]
public static unsafe void Store<T>(this System.Runtime.Intrinsics.Vector128<T> source, T* destination) { throw null; }
@ -443,6 +449,8 @@ namespace System.Runtime.Intrinsics
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector256<T> vector, System.Span<T> destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector256<T> vector, T[] destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector256<T> vector, T[] destination, int startIndex) { }
public static System.Runtime.Intrinsics.Vector256<double> Cos(System.Runtime.Intrinsics.Vector256<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector256<float> Cos(System.Runtime.Intrinsics.Vector256<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector256<System.Byte> Create(byte value) { throw null; }
public static System.Runtime.Intrinsics.Vector256<System.Byte> Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15, byte e16, byte e17, byte e18, byte e19, byte e20, byte e21, byte e22, byte e23, byte e24, byte e25, byte e26, byte e27, byte e28, byte e29, byte e30, byte e31) { throw null; }
public static System.Runtime.Intrinsics.Vector256<System.Double> Create(double value) { throw null; }
@ -672,6 +680,10 @@ namespace System.Runtime.Intrinsics
[System.CLSCompliantAttribute(false)]
public static System.Runtime.Intrinsics.Vector256<ulong> Shuffle(System.Runtime.Intrinsics.Vector256<ulong> vector, System.Runtime.Intrinsics.Vector256<ulong> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector256<double> Shuffle(System.Runtime.Intrinsics.Vector256<double> vector, System.Runtime.Intrinsics.Vector256<long> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector256<double> Sin(System.Runtime.Intrinsics.Vector256<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector256<float> Sin(System.Runtime.Intrinsics.Vector256<float> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector256<double> Sin, System.Runtime.Intrinsics.Vector256<double> Cos) SinCos(System.Runtime.Intrinsics.Vector256<double> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector256<float> Sin, System.Runtime.Intrinsics.Vector256<float> Cos) SinCos(System.Runtime.Intrinsics.Vector256<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector256<T> Sqrt<T>(System.Runtime.Intrinsics.Vector256<T> vector) { throw null; }
[System.CLSCompliantAttribute(false)]
public static unsafe void Store<T>(this System.Runtime.Intrinsics.Vector256<T> source, T* destination) { throw null; }
@ -816,6 +828,8 @@ namespace System.Runtime.Intrinsics
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector512<T> vector, System.Span<T> destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector512<T> vector, T[] destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector512<T> vector, T[] destination, int startIndex) { }
public static System.Runtime.Intrinsics.Vector512<double> Cos(System.Runtime.Intrinsics.Vector512<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector512<float> Cos(System.Runtime.Intrinsics.Vector512<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector512<System.Byte> Create(byte value) { throw null; }
public static System.Runtime.Intrinsics.Vector512<System.Byte> Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7, byte e8, byte e9, byte e10, byte e11, byte e12, byte e13, byte e14, byte e15, byte e16, byte e17, byte e18, byte e19, byte e20, byte e21, byte e22, byte e23, byte e24, byte e25, byte e26, byte e27, byte e28, byte e29, byte e30, byte e31, byte e32, byte e33, byte e34, byte e35, byte e36, byte e37, byte e38, byte e39, byte e40, byte e41, byte e42, byte e43, byte e44, byte e45, byte e46, byte e47, byte e48, byte e49, byte e50, byte e51, byte e52, byte e53, byte e54, byte e55, byte e56, byte e57, byte e58, byte e59, byte e60, byte e61, byte e62, byte e63) { throw null; }
public static System.Runtime.Intrinsics.Vector512<System.Double> Create(double value) { throw null; }
@ -1046,6 +1060,10 @@ namespace System.Runtime.Intrinsics
[System.CLSCompliantAttribute(false)]
public static System.Runtime.Intrinsics.Vector512<ulong> Shuffle(System.Runtime.Intrinsics.Vector512<ulong> vector, System.Runtime.Intrinsics.Vector512<ulong> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector512<double> Shuffle(System.Runtime.Intrinsics.Vector512<double> vector, System.Runtime.Intrinsics.Vector512<long> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector512<double> Sin(System.Runtime.Intrinsics.Vector512<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector512<float> Sin(System.Runtime.Intrinsics.Vector512<float> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector512<double> Sin, System.Runtime.Intrinsics.Vector512<double> Cos) SinCos(System.Runtime.Intrinsics.Vector512<double> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector512<float> Sin, System.Runtime.Intrinsics.Vector512<float> Cos) SinCos(System.Runtime.Intrinsics.Vector512<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector512<T> Sqrt<T>(System.Runtime.Intrinsics.Vector512<T> vector) { throw null; }
[System.CLSCompliantAttribute(false)]
public static unsafe void Store<T>(this System.Runtime.Intrinsics.Vector512<T> source, T* destination) { throw null; }
@ -1186,6 +1204,8 @@ namespace System.Runtime.Intrinsics
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector64<T> vector, System.Span<T> destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector64<T> vector, T[] destination) { }
public static void CopyTo<T>(this System.Runtime.Intrinsics.Vector64<T> vector, T[] destination, int startIndex) { }
public static System.Runtime.Intrinsics.Vector64<double> Cos(System.Runtime.Intrinsics.Vector64<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector64<float> Cos(System.Runtime.Intrinsics.Vector64<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector64<System.Byte> Create(byte value) { throw null; }
public static System.Runtime.Intrinsics.Vector64<System.Byte> Create(byte e0, byte e1, byte e2, byte e3, byte e4, byte e5, byte e6, byte e7) { throw null; }
public static System.Runtime.Intrinsics.Vector64<System.Double> Create(double value) { throw null; }
@ -1385,6 +1405,10 @@ namespace System.Runtime.Intrinsics
[System.CLSCompliantAttribute(false)]
public static System.Runtime.Intrinsics.Vector64<uint> Shuffle(System.Runtime.Intrinsics.Vector64<uint> vector, System.Runtime.Intrinsics.Vector64<uint> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector64<float> Shuffle(System.Runtime.Intrinsics.Vector64<float> vector, System.Runtime.Intrinsics.Vector64<int> indices) { throw null; }
public static System.Runtime.Intrinsics.Vector64<double> Sin(System.Runtime.Intrinsics.Vector64<double> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector64<float> Sin(System.Runtime.Intrinsics.Vector64<float> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector64<double> Sin, System.Runtime.Intrinsics.Vector64<double> Cos) SinCos(System.Runtime.Intrinsics.Vector64<double> vector) { throw null; }
public static (System.Runtime.Intrinsics.Vector64<float> Sin, System.Runtime.Intrinsics.Vector64<float> Cos) SinCos(System.Runtime.Intrinsics.Vector64<float> vector) { throw null; }
public static System.Runtime.Intrinsics.Vector64<T> Sqrt<T>(System.Runtime.Intrinsics.Vector64<T> vector) { throw null; }
[System.CLSCompliantAttribute(false)]
public static unsafe void Store<T>(this System.Runtime.Intrinsics.Vector64<T> source, T* destination) { throw null; }

View file

@ -4824,6 +4824,22 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
}
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void CosDoubleTest(double value, double expectedResult, double variance)
{
Vector128<double> actualResult = Vector128.Cos(Vector128.Create(value));
AssertEqual(Vector128.Create(expectedResult), actualResult, Vector128.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector128<float> actualResult = Vector128.Cos(Vector128.Create(value));
AssertEqual(Vector128.Create(expectedResult), actualResult, Vector128.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpDouble), MemberType = typeof(GenericMathTestMemberData))]
public void ExpDoubleTest(double value, double expectedResult, double variance)
@ -5329,6 +5345,40 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
AssertEqual(Vector128.Create(expectedResult), actualResult, Vector128<float>.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinDoubleTest(double value, double expectedResult, double variance)
{
Vector128<double> actualResult = Vector128.Sin(Vector128.Create(value));
AssertEqual(Vector128.Create(expectedResult), actualResult, Vector128.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector128<float> actualResult = Vector128.Sin(Vector128.Create(value));
AssertEqual(Vector128.Create(expectedResult), actualResult, Vector128.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosDoubleTest(double value, double expectedResultSin, double expectedResultCos, double allowedVarianceSin, double allowedVarianceCos)
{
(Vector128<double> resultSin, Vector128<double> resultCos) = Vector128.SinCos(Vector128.Create(value));
AssertEqual(Vector128.Create(expectedResultSin), resultSin, Vector128.Create(allowedVarianceSin));
AssertEqual(Vector128.Create(expectedResultCos), resultCos, Vector128.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector128<float> resultSin, Vector128<float> resultCos) = Vector128.SinCos(Vector128.Create(value));
AssertEqual(Vector128.Create(expectedResultSin), resultSin, Vector128.Create(allowedVarianceSin));
AssertEqual(Vector128.Create(expectedResultCos), resultCos, Vector128.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateDouble), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateDoubleTest(double value, double expectedResult)

View file

@ -5840,6 +5840,22 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
}
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void CosDoubleTest(double value, double expectedResult, double variance)
{
Vector256<double> actualResult = Vector256.Cos(Vector256.Create(value));
AssertEqual(Vector256.Create(expectedResult), actualResult, Vector256.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector256<float> actualResult = Vector256.Cos(Vector256.Create(value));
AssertEqual(Vector256.Create(expectedResult), actualResult, Vector256.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpDouble), MemberType = typeof(GenericMathTestMemberData))]
public void ExpDoubleTest(double value, double expectedResult, double variance)
@ -6345,6 +6361,40 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
AssertEqual(Vector256.Create(expectedResult), actualResult, Vector256<float>.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinDoubleTest(double value, double expectedResult, double variance)
{
Vector256<double> actualResult = Vector256.Sin(Vector256.Create(value));
AssertEqual(Vector256.Create(expectedResult), actualResult, Vector256.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector256<float> actualResult = Vector256.Sin(Vector256.Create(value));
AssertEqual(Vector256.Create(expectedResult), actualResult, Vector256.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosDoubleTest(double value, double expectedResultSin, double expectedResultCos, double allowedVarianceSin, double allowedVarianceCos)
{
(Vector256<double> resultSin, Vector256<double> resultCos) = Vector256.SinCos(Vector256.Create(value));
AssertEqual(Vector256.Create(expectedResultSin), resultSin, Vector256.Create(allowedVarianceSin));
AssertEqual(Vector256.Create(expectedResultCos), resultCos, Vector256.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector256<float> resultSin, Vector256<float> resultCos) = Vector256.SinCos(Vector256.Create(value));
AssertEqual(Vector256.Create(expectedResultSin), resultSin, Vector256.Create(allowedVarianceSin));
AssertEqual(Vector256.Create(expectedResultCos), resultCos, Vector256.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateDouble), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateDoubleTest(double value, double expectedResult)

View file

@ -5273,6 +5273,22 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
}
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void CosDoubleTest(double value, double expectedResult, double variance)
{
Vector512<double> actualResult = Vector512.Cos(Vector512.Create(value));
AssertEqual(Vector512.Create(expectedResult), actualResult, Vector512.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector512<float> actualResult = Vector512.Cos(Vector512.Create(value));
AssertEqual(Vector512.Create(expectedResult), actualResult, Vector512.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpDouble), MemberType = typeof(GenericMathTestMemberData))]
public void ExpDoubleTest(double value, double expectedResult, double variance)
@ -5778,6 +5794,40 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
AssertEqual(Vector512.Create(expectedResult), actualResult, Vector512<float>.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinDoubleTest(double value, double expectedResult, double variance)
{
Vector512<double> actualResult = Vector512.Sin(Vector512.Create(value));
AssertEqual(Vector512.Create(expectedResult), actualResult, Vector512.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector512<float> actualResult = Vector512.Sin(Vector512.Create(value));
AssertEqual(Vector512.Create(expectedResult), actualResult, Vector512.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosDoubleTest(double value, double expectedResultSin, double expectedResultCos, double allowedVarianceSin, double allowedVarianceCos)
{
(Vector512<double> resultSin, Vector512<double> resultCos) = Vector512.SinCos(Vector512.Create(value));
AssertEqual(Vector512.Create(expectedResultSin), resultSin, Vector512.Create(allowedVarianceSin));
AssertEqual(Vector512.Create(expectedResultCos), resultCos, Vector512.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector512<float> resultSin, Vector512<float> resultCos) = Vector512.SinCos(Vector512.Create(value));
AssertEqual(Vector512.Create(expectedResultSin), resultSin, Vector512.Create(allowedVarianceSin));
AssertEqual(Vector512.Create(expectedResultCos), resultCos, Vector512.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateDouble), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateDoubleTest(double value, double expectedResult)

View file

@ -4241,6 +4241,22 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
}
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void CosDoubleTest(double value, double expectedResult, double variance)
{
Vector64<double> actualResult = Vector64.Cos(Vector64.Create(value));
AssertEqual(Vector64.Create(expectedResult), actualResult, Vector64.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void CosSingleTest(float value, float expectedResult, float variance)
{
Vector64<float> actualResult = Vector64.Cos(Vector64.Create(value));
AssertEqual(Vector64.Create(expectedResult), actualResult, Vector64.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.ExpDouble), MemberType = typeof(GenericMathTestMemberData))]
public void ExpDoubleTest(double value, double expectedResult, double variance)
@ -4736,6 +4752,40 @@ namespace System.Runtime.Intrinsics.Tests.Vectors
AssertEqual(Vector64.Create(expectedResult), actualResult, Vector64<float>.Zero);
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinDoubleTest(double value, double expectedResult, double variance)
{
Vector64<double> actualResult = Vector64.Sin(Vector64.Create(value));
AssertEqual(Vector64.Create(expectedResult), actualResult, Vector64.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinSingleTest(float value, float expectedResult, float variance)
{
Vector64<float> actualResult = Vector64.Sin(Vector64.Create(value));
AssertEqual(Vector64.Create(expectedResult), actualResult, Vector64.Create(variance));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosDouble), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosDoubleTest(double value, double expectedResultSin, double expectedResultCos, double allowedVarianceSin, double allowedVarianceCos)
{
(Vector64<double> resultSin, Vector64<double> resultCos) = Vector64.SinCos(Vector64.Create(value));
AssertEqual(Vector64.Create(expectedResultSin), resultSin, Vector64.Create(allowedVarianceSin));
AssertEqual(Vector64.Create(expectedResultCos), resultCos, Vector64.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public void SinCosSingleTest(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(Vector64<float> resultSin, Vector64<float> resultCos) = Vector64.SinCos(Vector64.Create(value));
AssertEqual(Vector64.Create(expectedResultSin), resultSin, Vector64.Create(allowedVarianceSin));
AssertEqual(Vector64.Create(expectedResultCos), resultCos, Vector64.Create(allowedVarianceCos));
}
[Theory]
[MemberData(nameof(GenericMathTestMemberData.TruncateDouble), MemberType = typeof(GenericMathTestMemberData))]
public void TruncateDoubleTest(double value, double expectedResult)

View file

@ -473,39 +473,7 @@ namespace System.Tests
}
[Theory]
[InlineData( double.NegativeInfinity, double.NaN, 0.0)]
[InlineData(-3.1415926535897932, -1.0, CrossPlatformMachineEpsilon * 10)] // value: -(pi)
[InlineData(-2.7182818284590452, -0.91173391478696510, CrossPlatformMachineEpsilon)] // value: -(e)
[InlineData(-2.3025850929940457, -0.66820151019031295, CrossPlatformMachineEpsilon)] // value: -(ln(10))
[InlineData(-1.5707963267948966, 0.0, CrossPlatformMachineEpsilon)] // value: -(pi / 2)
[InlineData(-1.4426950408889634, 0.12775121753523991, CrossPlatformMachineEpsilon)] // value: -(log2(e))
[InlineData(-1.4142135623730950, 0.15594369476537447, CrossPlatformMachineEpsilon)] // value: -(sqrt(2))
[InlineData(-1.1283791670955126, 0.42812514788535792, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi))
[InlineData(-1.0, 0.54030230586813972, CrossPlatformMachineEpsilon)]
[InlineData(-0.78539816339744831, 0.70710678118654752, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected: (1 / sqrt(2))
[InlineData(-0.70710678118654752, 0.76024459707563015, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2))
[InlineData(-0.69314718055994531, 0.76923890136397213, CrossPlatformMachineEpsilon)] // value: -(ln(2))
[InlineData(-0.63661977236758134, 0.80410982822879171, CrossPlatformMachineEpsilon)] // value: -(2 / pi)
[InlineData(-0.43429448190325183, 0.90716712923909839, CrossPlatformMachineEpsilon)] // value: -(log10(e))
[InlineData(-0.31830988618379067, 0.94976571538163866, CrossPlatformMachineEpsilon)] // value: -(1 / pi)
[InlineData(-0.0, 1.0, CrossPlatformMachineEpsilon * 10)]
[InlineData( double.NaN, double.NaN, 0.0)]
[InlineData( 0.0, 1.0, CrossPlatformMachineEpsilon * 10)]
[InlineData( 0.31830988618379067, 0.94976571538163866, CrossPlatformMachineEpsilon)] // value: (1 / pi)
[InlineData( 0.43429448190325183, 0.90716712923909839, CrossPlatformMachineEpsilon)] // value: (log10(e))
[InlineData( 0.63661977236758134, 0.80410982822879171, CrossPlatformMachineEpsilon)] // value: (2 / pi)
[InlineData( 0.69314718055994531, 0.76923890136397213, CrossPlatformMachineEpsilon)] // value: (ln(2))
[InlineData( 0.70710678118654752, 0.76024459707563015, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
[InlineData( 0.78539816339744831, 0.70710678118654752, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected: (1 / sqrt(2))
[InlineData( 1.0, 0.54030230586813972, CrossPlatformMachineEpsilon)]
[InlineData( 1.1283791670955126, 0.42812514788535792, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
[InlineData( 1.4142135623730950, 0.15594369476537447, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
[InlineData( 1.4426950408889634, 0.12775121753523991, CrossPlatformMachineEpsilon)] // value: (log2(e))
[InlineData( 1.5707963267948966, 0.0, CrossPlatformMachineEpsilon)] // value: (pi / 2)
[InlineData( 2.3025850929940457, -0.66820151019031295, CrossPlatformMachineEpsilon)] // value: (ln(10))
[InlineData( 2.7182818284590452, -0.91173391478696510, CrossPlatformMachineEpsilon)] // value: (e)
[InlineData( 3.1415926535897932, -1.0, CrossPlatformMachineEpsilon * 10)] // value: (pi)
[InlineData( double.PositiveInfinity, double.NaN, 0.0)]
[MemberData(nameof(GenericMathTestMemberData.CosDouble), MemberType = typeof(GenericMathTestMemberData))]
public static void Cos(double value, double expectedResult, double allowedVariance)
{
AssertExtensions.Equal(expectedResult, Math.Cos(value), allowedVariance);
@ -1354,80 +1322,14 @@ namespace System.Tests
}
[Theory]
[InlineData( double.NegativeInfinity, double.NaN, 0.0)]
[InlineData(-3.1415926535897932, -0.0, CrossPlatformMachineEpsilon)] // value: -(pi)
[InlineData(-2.7182818284590452, -0.41078129050290870, CrossPlatformMachineEpsilon)] // value: -(e)
[InlineData(-2.3025850929940457, -0.74398033695749319, CrossPlatformMachineEpsilon)] // value: -(ln(10))
[InlineData(-1.5707963267948966, -1.0, CrossPlatformMachineEpsilon * 10)] // value: -(pi / 2)
[InlineData(-1.4426950408889634, -0.99180624439366372, CrossPlatformMachineEpsilon)] // value: -(log2(e))
[InlineData(-1.4142135623730950, -0.98776594599273553, CrossPlatformMachineEpsilon)] // value: -(sqrt(2))
[InlineData(-1.1283791670955126, -0.90371945743584630, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi))
[InlineData(-1.0, -0.84147098480789651, CrossPlatformMachineEpsilon)]
[InlineData(-0.78539816339744831, -0.70710678118654752, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected: -(1 / sqrt(2))
[InlineData(-0.70710678118654752, -0.64963693908006244, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2))
[InlineData(-0.69314718055994531, -0.63896127631363480, CrossPlatformMachineEpsilon)] // value: -(ln(2))
[InlineData(-0.63661977236758134, -0.59448076852482208, CrossPlatformMachineEpsilon)] // value: -(2 / pi)
[InlineData(-0.43429448190325183, -0.42077048331375735, CrossPlatformMachineEpsilon)] // value: -(log10(e))
[InlineData(-0.31830988618379067, -0.31296179620778659, CrossPlatformMachineEpsilon)] // value: -(1 / pi)
[InlineData(-0.0, -0.0, 0.0)]
[InlineData( double.NaN, double.NaN, 0.0)]
[InlineData( 0.0, 0.0, 0.0)]
[InlineData( 0.31830988618379067, 0.31296179620778659, CrossPlatformMachineEpsilon)] // value: (1 / pi)
[InlineData( 0.43429448190325183, 0.42077048331375735, CrossPlatformMachineEpsilon)] // value: (log10(e))
[InlineData( 0.63661977236758134, 0.59448076852482208, CrossPlatformMachineEpsilon)] // value: (2 / pi)
[InlineData( 0.69314718055994531, 0.63896127631363480, CrossPlatformMachineEpsilon)] // value: (ln(2))
[InlineData( 0.70710678118654752, 0.64963693908006244, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
[InlineData( 0.78539816339744831, 0.70710678118654752, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected: (1 / sqrt(2))
[InlineData( 1.0, 0.84147098480789651, CrossPlatformMachineEpsilon)]
[InlineData( 1.1283791670955126, 0.90371945743584630, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
[InlineData( 1.4142135623730950, 0.98776594599273553, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
[InlineData( 1.4426950408889634, 0.99180624439366372, CrossPlatformMachineEpsilon)] // value: (log2(e))
[InlineData( 1.5707963267948966, 1.0, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2)
[InlineData( 2.3025850929940457, 0.74398033695749319, CrossPlatformMachineEpsilon)] // value: (ln(10))
[InlineData( 2.7182818284590452, 0.41078129050290870, CrossPlatformMachineEpsilon)] // value: (e)
[InlineData( 3.1415926535897932, 0.0, CrossPlatformMachineEpsilon)] // value: (pi)
[InlineData( double.PositiveInfinity, double.NaN, 0.0)]
[MemberData(nameof(GenericMathTestMemberData.SinDouble), MemberType = typeof(GenericMathTestMemberData))]
public static void Sin(double value, double expectedResult, double allowedVariance)
{
AssertExtensions.Equal(expectedResult, Math.Sin(value), allowedVariance);
}
[Theory]
[InlineData( double.NegativeInfinity, double.NaN, double.NaN, 0.0, 0.0)]
[InlineData(-1e18, 0.9929693207404051, 0.11837199021871073, 0.0002, 0.002)] // https://github.com/dotnet/runtime/issues/98204
[InlineData(-3.1415926535897932, -0.0, -1.0, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: -(pi)
[InlineData(-2.7182818284590452, -0.41078129050290870, -0.91173391478696510, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(e)
[InlineData(-2.3025850929940457, -0.74398033695749319, -0.66820151019031295, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(ln(10))
[InlineData(-1.5707963267948966, -1.0, 0.0, CrossPlatformMachineEpsilon * 10, CrossPlatformMachineEpsilon)] // value: -(pi / 2)
[InlineData(-1.4426950408889634, -0.99180624439366372, 0.12775121753523991, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(log2(e))
[InlineData(-1.4142135623730950, -0.98776594599273553, 0.15594369476537447, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(sqrt(2))
[InlineData(-1.1283791670955126, -0.90371945743584630, 0.42812514788535792, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi))
[InlineData(-1.0, -0.84147098480789651, 0.54030230586813972, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)]
[InlineData(-0.78539816339744831, -0.70710678118654752, 0.70710678118654752, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected_sin: -(1 / sqrt(2)), expected_cos: 1
[InlineData(-0.70710678118654752, -0.64963693908006244, 0.76024459707563015, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2))
[InlineData(-0.69314718055994531, -0.63896127631363480, 0.76923890136397213, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(ln(2))
[InlineData(-0.63661977236758134, -0.59448076852482208, 0.80410982822879171, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(2 / pi)
[InlineData(-0.43429448190325183, -0.42077048331375735, 0.90716712923909839, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(log10(e))
[InlineData(-0.31830988618379067, -0.31296179620778659, 0.94976571538163866, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(1 / pi)
[InlineData(-0.0, -0.0, 1.0, 0.0, CrossPlatformMachineEpsilon * 10)]
[InlineData( double.NaN, double.NaN, double.NaN, 0.0, 0.0)]
[InlineData( 0.0, 0.0, 1.0, 0.0, CrossPlatformMachineEpsilon * 10)]
[InlineData( 0.31830988618379067, 0.31296179620778659, 0.94976571538163866, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (1 / pi)
[InlineData( 0.43429448190325183, 0.42077048331375735, 0.90716712923909839, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (log10(e))
[InlineData( 0.63661977236758134, 0.59448076852482208, 0.80410982822879171, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (2 / pi)
[InlineData( 0.69314718055994531, 0.63896127631363480, 0.76923890136397213, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (ln(2))
[InlineData( 0.70710678118654752, 0.64963693908006244, 0.76024459707563015, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
[InlineData( 0.78539816339744831, 0.70710678118654752, 0.70710678118654752, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected_sin: (1 / sqrt(2)), expected_cos: 1
[InlineData( 1.0, 0.84147098480789651, 0.54030230586813972, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)]
[InlineData( 1.1283791670955126, 0.90371945743584630, 0.42812514788535792, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
[InlineData( 1.4142135623730950, 0.98776594599273553, 0.15594369476537447, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
[InlineData( 1.4426950408889634, 0.99180624439366372, 0.12775121753523991, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (log2(e))
[InlineData( 1.5707963267948966, 1.0, 0.0, CrossPlatformMachineEpsilon * 10, CrossPlatformMachineEpsilon)] // value: (pi / 2)
[InlineData( 2.3025850929940457, 0.74398033695749319, -0.66820151019031295, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (ln(10))
[InlineData( 2.7182818284590452, 0.41078129050290870, -0.91173391478696510, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (e)
[InlineData( 3.1415926535897932, 0.0, -1.0, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: (pi)
[InlineData( 1e18, -0.9929693207404051, 0.11837199021871073, 0.0002, 0.002)] // https://github.com/dotnet/runtime/issues/98204
[InlineData( double.PositiveInfinity, double.NaN, double.NaN, 0.0, 0.0)]
[MemberData(nameof(GenericMathTestMemberData.SinCosDouble), MemberType = typeof(GenericMathTestMemberData))]
public static void SinCos(double value, double expectedResultSin, double expectedResultCos, double allowedVarianceSin, double allowedVarianceCos)
{
(double resultSin, double resultCos) = Math.SinCos(value);

View file

@ -584,39 +584,7 @@ namespace System.Tests
}
[Theory]
[InlineData(float.NegativeInfinity, float.NaN, 0.0f)]
[InlineData(-3.14159265f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: -(pi)
[InlineData(-2.71828183f, -0.911733918f, CrossPlatformMachineEpsilon)] // value: -(e)
[InlineData(-2.30258509f, -0.668201510f, CrossPlatformMachineEpsilon)] // value: -(ln(10))
[InlineData(-1.57079633f, 0.0f, CrossPlatformMachineEpsilon)] // value: -(pi / 2)
[InlineData(-1.44269504f, 0.127751218f, CrossPlatformMachineEpsilon)] // value: -(log2(e))
[InlineData(-1.41421356f, 0.155943695f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2))
[InlineData(-1.12837917f, 0.428125148f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi))
[InlineData(-1.0f, 0.540302306f, CrossPlatformMachineEpsilon)]
[InlineData(-0.785398163f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected: (1 / sqrt(2))
[InlineData(-0.707106781f, 0.760244597f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2))
[InlineData(-0.693147181f, 0.769238901f, CrossPlatformMachineEpsilon)] // value: -(ln(2))
[InlineData(-0.636619772f, 0.804109828f, CrossPlatformMachineEpsilon)] // value: -(2 / pi)
[InlineData(-0.434294482f, 0.907167129f, CrossPlatformMachineEpsilon)] // value: -(log10(e))
[InlineData(-0.318309886f, 0.949765715f, CrossPlatformMachineEpsilon)] // value: -(1 / pi)
[InlineData(-0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)]
[InlineData(float.NaN, float.NaN, 0.0f)]
[InlineData(0.0f, 1.0f, CrossPlatformMachineEpsilon * 10)]
[InlineData(0.318309886f, 0.949765715f, CrossPlatformMachineEpsilon)] // value: (1 / pi)
[InlineData(0.434294482f, 0.907167129f, CrossPlatformMachineEpsilon)] // value: (log10(e))
[InlineData(0.636619772f, 0.804109828f, CrossPlatformMachineEpsilon)] // value: (2 / pi)
[InlineData(0.693147181f, 0.769238901f, CrossPlatformMachineEpsilon)] // value: (ln(2))
[InlineData(0.707106781f, 0.760244597f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
[InlineData(0.785398163f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected: (1 / sqrt(2))
[InlineData(1.0f, 0.540302306f, CrossPlatformMachineEpsilon)]
[InlineData(1.12837917f, 0.428125148f, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
[InlineData(1.41421356f, 0.155943695f, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
[InlineData(1.44269504f, 0.127751218f, CrossPlatformMachineEpsilon)] // value: (log2(e))
[InlineData(1.57079633f, 0.0f, CrossPlatformMachineEpsilon)] // value: (pi / 2)
[InlineData(2.30258509f, -0.668201510f, CrossPlatformMachineEpsilon)] // value: (ln(10))
[InlineData(2.71828183f, -0.911733918f, CrossPlatformMachineEpsilon)] // value: (e)
[InlineData(3.14159265f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: (pi)
[InlineData(float.PositiveInfinity, float.NaN, 0.0f)]
[MemberData(nameof(GenericMathTestMemberData.CosSingle), MemberType = typeof(GenericMathTestMemberData))]
public static void Cos(float value, float expectedResult, float allowedVariance)
{
AssertExtensions.Equal(expectedResult, MathF.Cos(value), allowedVariance);
@ -1349,80 +1317,14 @@ namespace System.Tests
}
[Theory]
[InlineData(float.NegativeInfinity, float.NaN, 0.0f)]
[InlineData(-3.14159265f, -0.0f, CrossPlatformMachineEpsilon)] // value: -(pi)
[InlineData(-2.71828183f, -0.410781291f, CrossPlatformMachineEpsilon)] // value: -(e)
[InlineData(-2.30258509f, -0.743980337f, CrossPlatformMachineEpsilon)] // value: -(ln(10))
[InlineData(-1.57079633f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: -(pi / 2)
[InlineData(-1.44269504f, -0.991806244f, CrossPlatformMachineEpsilon)] // value: -(log2(e))
[InlineData(-1.41421356f, -0.987765946f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2))
[InlineData(-1.12837917f, -0.903719457f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi))
[InlineData(-1.0f, -0.841470985f, CrossPlatformMachineEpsilon)]
[InlineData(-0.785398163f, -0.707106781f, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected: -(1 / sqrt(2))
[InlineData(-0.707106781f, -0.649636939f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2))
[InlineData(-0.693147181f, -0.638961276f, CrossPlatformMachineEpsilon)] // value: -(ln(2))
[InlineData(-0.636619772f, -0.594480769f, CrossPlatformMachineEpsilon)] // value: -(2 / pi)
[InlineData(-0.434294482f, -0.420770483f, CrossPlatformMachineEpsilon)] // value: -(log10(e))
[InlineData(-0.318309886f, -0.312961796f, CrossPlatformMachineEpsilon)] // value: -(1 / pi)
[InlineData(-0.0f, -0.0f, 0.0f)]
[InlineData(float.NaN, float.NaN, 0.0f)]
[InlineData(0.0f, 0.0f, 0.0f)]
[InlineData(0.318309886f, 0.312961796f, CrossPlatformMachineEpsilon)] // value: (1 / pi)
[InlineData(0.434294482f, 0.420770483f, CrossPlatformMachineEpsilon)] // value: (log10(e))
[InlineData(0.636619772f, 0.594480769f, CrossPlatformMachineEpsilon)] // value: (2 / pi)
[InlineData(0.693147181f, 0.638961276f, CrossPlatformMachineEpsilon)] // value: (ln(2))
[InlineData(0.707106781f, 0.649636939f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
[InlineData(0.785398163f, 0.707106781f, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected: (1 / sqrt(2))
[InlineData(1.0f, 0.841470985f, CrossPlatformMachineEpsilon)]
[InlineData(1.12837917f, 0.903719457f, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
[InlineData(1.41421356f, 0.987765946f, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
[InlineData(1.44269504f, 0.991806244f, CrossPlatformMachineEpsilon)] // value: (log2(e))
[InlineData(1.57079633f, 1.0f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2)
[InlineData(2.30258509f, 0.743980337f, CrossPlatformMachineEpsilon)] // value: (ln(10))
[InlineData(2.71828183f, 0.410781291f, CrossPlatformMachineEpsilon)] // value: (e)
[InlineData(3.14159265f, 0.0f, CrossPlatformMachineEpsilon)] // value: (pi)
[InlineData(float.PositiveInfinity, float.NaN, 0.0f)]
[MemberData(nameof(GenericMathTestMemberData.SinSingle), MemberType = typeof(GenericMathTestMemberData))]
public static void Sin(float value, float expectedResult, float allowedVariance)
{
AssertExtensions.Equal(expectedResult, MathF.Sin(value), allowedVariance);
}
[Theory]
[InlineData( float.NegativeInfinity, float.NaN, float.NaN, 0.0f, 0.0f)]
[InlineData(-1e8f, -0.931639, -0.36338508, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // https://github.com/dotnet/runtime/issues/98204
[InlineData(-3.14159265f, -0.0f, -1.0f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: -(pi)
[InlineData(-2.71828183f, -0.410781291f, -0.911733918f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(e)
[InlineData(-2.30258509f, -0.743980337f, -0.668201510f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(ln(10))
[InlineData(-1.57079633f, -1.0f, 0.0f, CrossPlatformMachineEpsilon * 10, CrossPlatformMachineEpsilon)] // value: -(pi / 2)
[InlineData(-1.44269504f, -0.991806244f, 0.127751218f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(log2(e))
[InlineData(-1.41421356f, -0.987765946f, 0.155943695f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(sqrt(2))
[InlineData(-1.12837917f, -0.903719457f, 0.428125148f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi))
[InlineData(-1.0f, -0.841470985f, 0.540302306f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)]
[InlineData(-0.785398163f, -0.707106781f, 0.707106781f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(pi / 4), expected_sin: -(1 / sqrt(2)), expected_cos: 1
[InlineData(-0.707106781f, -0.649636939f, 0.760244597f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2))
[InlineData(-0.693147181f, -0.638961276f, 0.769238901f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(ln(2))
[InlineData(-0.636619772f, -0.594480769f, 0.804109828f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(2 / pi)
[InlineData(-0.434294482f, -0.420770483f, 0.907167129f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(log10(e))
[InlineData(-0.318309886f, -0.312961796f, 0.949765715f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: -(1 / pi)
[InlineData(-0.0f, -0.0f, 1.0f, 0.0f, CrossPlatformMachineEpsilon * 10)]
[InlineData( float.NaN, float.NaN, float.NaN, 0.0f, 0.0f)]
[InlineData( 0.0f, 0.0f, 1.0f, 0.0f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 0.318309886f, 0.312961796f, 0.949765715f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (1 / pi)
[InlineData( 0.434294482f, 0.420770483f, 0.907167129f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (log10(e))
[InlineData( 0.636619772f, 0.594480769f, 0.804109828f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (2 / pi)
[InlineData( 0.693147181f, 0.638961276f, 0.769238901f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (ln(2))
[InlineData( 0.707106781f, 0.649636939f, 0.760244597f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
[InlineData( 0.785398163f, 0.707106781f, 0.707106781f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (pi / 4), expected_sin: (1 / sqrt(2)), expected_cos: 1
[InlineData( 1.0f, 0.841470985f, 0.540302306f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)]
[InlineData( 1.12837917f, 0.903719457f, 0.428125148f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
[InlineData( 1.41421356f, 0.987765946f, 0.155943695f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
[InlineData( 1.44269504f, 0.991806244f, 0.127751218f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (log2(e))
[InlineData( 1.57079633f, 1.0f, 0.0f, CrossPlatformMachineEpsilon * 10, CrossPlatformMachineEpsilon)] // value: (pi / 2)
[InlineData( 2.30258509f, 0.743980337f, -0.668201510f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (ln(10))
[InlineData( 2.71828183f, 0.410781291f, -0.911733918f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // value: (e)
[InlineData( 3.14159265f, 0.0f, -1.0f, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon * 10)] // value: (pi)
[InlineData( 1e8f, 0.931639, -0.36338508, CrossPlatformMachineEpsilon, CrossPlatformMachineEpsilon)] // https://github.com/dotnet/runtime/issues/98204
[InlineData( float.PositiveInfinity, float.NaN, float.NaN, 0.0f, 0.0f)]
[MemberData(nameof(GenericMathTestMemberData.SinCosSingle), MemberType = typeof(GenericMathTestMemberData))]
public static void SinCos(float value, float expectedResultSin, float expectedResultCos, float allowedVarianceSin, float allowedVarianceCos)
{
(float resultSin, float resultCos) = MathF.SinCos(value);