From e6af3669a7ea71c43c52d2fef952aff8ff4b4abd Mon Sep 17 00:00:00 2001 From: U2A5F Date: Thu, 9 Jul 2026 13:52:48 +0800 Subject: [PATCH 1/5] #8 Migrate IsInfinity IsPositiveInfinity IsNegativeInfinity --- .../Coplt.Mathematics.SignedDistances.csproj | 4 +- Coplt.Mathematics/Coplt.Mathematics.csproj | 4 +- Coplt.Mathematics/simd/simd.cs | 53 ------------------- Coplt.Mathematics/simd/simd.math.cs | 2 +- .../simd/simd.math.tri.double.cs | 12 ++--- .../simd/simd.math.tri.double.tt | 4 +- Coplt.Mathematics/simd/simd.math.tri.float.cs | 16 +++--- Coplt.Mathematics/simd/simd.math.tri.float.tt | 4 +- .../vec/arith/vec.arith.float.bin.cs | 36 ++++++------- .../vec/arith/vec.arith.float.bin.tt | 6 +-- Tests/Tests.csproj | 4 +- 11 files changed, 46 insertions(+), 99 deletions(-) diff --git a/Coplt.Mathematics.SignedDistances/Coplt.Mathematics.SignedDistances.csproj b/Coplt.Mathematics.SignedDistances/Coplt.Mathematics.SignedDistances.csproj index 0176ea8..ff9c091 100644 --- a/Coplt.Mathematics.SignedDistances/Coplt.Mathematics.SignedDistances.csproj +++ b/Coplt.Mathematics.SignedDistances/Coplt.Mathematics.SignedDistances.csproj @@ -2,8 +2,8 @@ enable - 13.0 - net8.0;net9.0 + 14.0 + net10.0 true false CS8981;CS0169 diff --git a/Coplt.Mathematics/Coplt.Mathematics.csproj b/Coplt.Mathematics/Coplt.Mathematics.csproj index 9edd2d9..5053de5 100644 --- a/Coplt.Mathematics/Coplt.Mathematics.csproj +++ b/Coplt.Mathematics/Coplt.Mathematics.csproj @@ -3,14 +3,14 @@ enable 14.0 - net8.0;net9.0;net10.0 + net10.0 true false CS8981;CS0169;CS1591 Always true true - 0.18.0 + 0.19.0 HLSL-style linear algebra math library with full simd support https://github.com/coplt/Coplt.Mathematics https://github.com/coplt/Coplt.Mathematics diff --git a/Coplt.Mathematics/simd/simd.cs b/Coplt.Mathematics/simd/simd.cs index 53af60b..b0fa705 100644 --- a/Coplt.Mathematics/simd/simd.cs +++ b/Coplt.Mathematics/simd/simd.cs @@ -2086,59 +2086,6 @@ public static Vector512 Fnma(Vector512 a, Vector512 b, V #endregion - #region IsInfinity - - [MethodImpl(256 | 512)] - public static Vector64 IsInfinity(Vector64 f) - { - var bits = f.AsInt32(); - return Vector64.Equals(bits & Vector64.Create(int.MaxValue), Vector64.Create(0x7F800000)); - } - - [MethodImpl(256 | 512)] - public static Vector128 IsInfinity(Vector128 f) - { - var bits = f.AsInt32(); - return Vector128.Equals(bits & Vector128.Create(int.MaxValue), Vector128.Create(0x7F800000)); - } - - [MethodImpl(256 | 512)] - public static Vector256 IsInfinity(Vector256 f) - { - var bits = f.AsInt32(); - return Vector256.Equals(bits & Vector256.Create(int.MaxValue), Vector256.Create(0x7F800000)); - } - - [MethodImpl(256 | 512)] - public static Vector512 IsInfinity(Vector512 f) - { - var bits = f.AsInt32(); - return Vector512.Equals(bits & Vector512.Create(int.MaxValue), Vector512.Create(0x7F800000)); - } - - [MethodImpl(256 | 512)] - public static Vector128 IsInfinity(Vector128 f) - { - var bits = f.AsInt64(); - return Vector128.Equals(bits & Vector128.Create(long.MaxValue), Vector128.Create(0x7FF0000000000000L)); - } - - [MethodImpl(256 | 512)] - public static Vector256 IsInfinity(Vector256 f) - { - var bits = f.AsInt64(); - return Vector256.Equals(bits & Vector256.Create(long.MaxValue), Vector256.Create(0x7FF0000000000000L)); - } - - [MethodImpl(256 | 512)] - public static Vector512 IsInfinity(Vector512 f) - { - var bits = f.AsInt64(); - return Vector512.Equals(bits & Vector512.Create(long.MaxValue), Vector512.Create(0x7FF0000000000000L)); - } - - #endregion - #region CMin [MethodImpl(256 | 512)] diff --git a/Coplt.Mathematics/simd/simd.math.cs b/Coplt.Mathematics/simd/simd.math.cs index a74ee15..f221240 100644 --- a/Coplt.Mathematics/simd/simd.math.cs +++ b/Coplt.Mathematics/simd/simd.math.cs @@ -648,7 +648,7 @@ private static Vector64 Log2_impl(Vector64 a) xl = (xl & Vector64.Create(0x7FFFFF)) | Vector64.Create(0x7F << 23); var d = (xl.AsSingle() | Vector64.One) * Vector64.Create(2.0f / 3.0f); - + #region Approx // A Taylor Series approximation of ln(x) that relies on the identity that ln(x) = 2*atan((x-1)/(x+1)). diff --git a/Coplt.Mathematics/simd/simd.math.tri.double.cs b/Coplt.Mathematics/simd/simd.math.tri.double.cs index 609f1d5..c29a365 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.double.cs +++ b/Coplt.Mathematics/simd/simd.math.tri.double.cs @@ -1046,8 +1046,8 @@ public static Vector512 Atan(Vector512 s) [MethodImpl(512)] public static Vector128 Atan2(Vector128 y, Vector128 x) { - var x_is_inf = simd.IsInfinity(x).AsDouble(); - var y_is_inf = simd.IsInfinity(y).AsDouble(); + var x_is_inf = Vector128.IsInfinity(x).AsDouble(); + var y_is_inf = Vector128.IsInfinity(y).AsDouble(); var x_iz = Vector128.Equals(x, default); var y_iz = Vector128.Equals(y, default); var y_sign = y & -Vector128.Zero; @@ -1128,8 +1128,8 @@ public static Vector128 Atan2(Vector128 y, Vector128 x) [MethodImpl(512)] public static Vector256 Atan2(Vector256 y, Vector256 x) { - var x_is_inf = simd.IsInfinity(x).AsDouble(); - var y_is_inf = simd.IsInfinity(y).AsDouble(); + var x_is_inf = Vector256.IsInfinity(x).AsDouble(); + var y_is_inf = Vector256.IsInfinity(y).AsDouble(); var x_iz = Vector256.Equals(x, default); var y_iz = Vector256.Equals(y, default); var y_sign = y & -Vector256.Zero; @@ -1210,8 +1210,8 @@ public static Vector256 Atan2(Vector256 y, Vector256 x) [MethodImpl(512)] public static Vector512 Atan2(Vector512 y, Vector512 x) { - var x_is_inf = simd.IsInfinity(x).AsDouble(); - var y_is_inf = simd.IsInfinity(y).AsDouble(); + var x_is_inf = Vector512.IsInfinity(x).AsDouble(); + var y_is_inf = Vector512.IsInfinity(y).AsDouble(); var x_iz = Vector512.Equals(x, default); var y_iz = Vector512.Equals(y, default); var y_sign = y & -Vector512.Zero; diff --git a/Coplt.Mathematics/simd/simd.math.tri.double.tt b/Coplt.Mathematics/simd/simd.math.tri.double.tt index acd4710..82c7de5 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.double.tt +++ b/Coplt.Mathematics/simd/simd.math.tri.double.tt @@ -513,8 +513,8 @@ public static partial class simd_math [MethodImpl(512)] public static <#= vt #> Atan2(<#= vt #> y, <#= vt #> x) { - var x_is_inf = simd.IsInfinity(x).AsDouble(); - var y_is_inf = simd.IsInfinity(y).AsDouble(); + var x_is_inf = <#= vector #>.IsInfinity(x).AsDouble(); + var y_is_inf = <#= vector #>.IsInfinity(y).AsDouble(); var x_iz = <#= vector #>.Equals(x, default); var y_iz = <#= vector #>.Equals(y, default); var y_sign = y & -<#= vt #>.Zero; diff --git a/Coplt.Mathematics/simd/simd.math.tri.float.cs b/Coplt.Mathematics/simd/simd.math.tri.float.cs index e2c26cf..76bc7b5 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.float.cs +++ b/Coplt.Mathematics/simd/simd.math.tri.float.cs @@ -1208,8 +1208,8 @@ public static Vector512 Atan(Vector512 s) [MethodImpl(512)] public static Vector64 Atan2(Vector64 y, Vector64 x) { - var x_is_inf = simd.IsInfinity(x).AsSingle(); - var y_is_inf = simd.IsInfinity(y).AsSingle(); + var x_is_inf = Vector64.IsInfinity(x).AsSingle(); + var y_is_inf = Vector64.IsInfinity(y).AsSingle(); var x_iz = Vector64.Equals(x, default); var y_iz = Vector64.Equals(y, default); var y_sign = y & -Vector64.Zero; @@ -1269,8 +1269,8 @@ public static Vector64 Atan2(Vector64 y, Vector64 x) [MethodImpl(512)] public static Vector128 Atan2(Vector128 y, Vector128 x) { - var x_is_inf = simd.IsInfinity(x).AsSingle(); - var y_is_inf = simd.IsInfinity(y).AsSingle(); + var x_is_inf = Vector128.IsInfinity(x).AsSingle(); + var y_is_inf = Vector128.IsInfinity(y).AsSingle(); var x_iz = Vector128.Equals(x, default); var y_iz = Vector128.Equals(y, default); var y_sign = y & -Vector128.Zero; @@ -1330,8 +1330,8 @@ public static Vector128 Atan2(Vector128 y, Vector128 x) [MethodImpl(512)] public static Vector256 Atan2(Vector256 y, Vector256 x) { - var x_is_inf = simd.IsInfinity(x).AsSingle(); - var y_is_inf = simd.IsInfinity(y).AsSingle(); + var x_is_inf = Vector256.IsInfinity(x).AsSingle(); + var y_is_inf = Vector256.IsInfinity(y).AsSingle(); var x_iz = Vector256.Equals(x, default); var y_iz = Vector256.Equals(y, default); var y_sign = y & -Vector256.Zero; @@ -1391,8 +1391,8 @@ public static Vector256 Atan2(Vector256 y, Vector256 x) [MethodImpl(512)] public static Vector512 Atan2(Vector512 y, Vector512 x) { - var x_is_inf = simd.IsInfinity(x).AsSingle(); - var y_is_inf = simd.IsInfinity(y).AsSingle(); + var x_is_inf = Vector512.IsInfinity(x).AsSingle(); + var y_is_inf = Vector512.IsInfinity(y).AsSingle(); var x_iz = Vector512.Equals(x, default); var y_iz = Vector512.Equals(y, default); var y_sign = y & -Vector512.Zero; diff --git a/Coplt.Mathematics/simd/simd.math.tri.float.tt b/Coplt.Mathematics/simd/simd.math.tri.float.tt index 959de55..c59522a 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.float.tt +++ b/Coplt.Mathematics/simd/simd.math.tri.float.tt @@ -512,8 +512,8 @@ public static partial class simd_math [MethodImpl(512)] public static <#= vt #> Atan2(<#= vt #> y, <#= vt #> x) { - var x_is_inf = simd.IsInfinity(x).AsSingle(); - var y_is_inf = simd.IsInfinity(y).AsSingle(); + var x_is_inf = <#= vector #>.IsInfinity(x).AsSingle(); + var y_is_inf = <#= vector #>.IsInfinity(y).AsSingle(); var x_iz = <#= vector #>.Equals(x, default); var y_iz = <#= vector #>.Equals(y, default); var y_sign = y & -<#= vt #>.Zero; diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs index 467b1cf..9b8add8 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs @@ -20,7 +20,7 @@ public static partial class math public static b32v2 isInf([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.IsInfinity(a.vector).AsUInt32()); + return new(Vector64.IsInfinity(a.vector).AsUInt32()); return new(a.x.isInf(), a.y.isInf()); } @@ -28,7 +28,7 @@ public static b32v2 isInf([This] float2 a) public static b32v2 isPosInf([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(Vector64.Equals(a.vector, Vector64.Create(float.PositiveInfinity)).AsUInt32()); + return new(Vector64.IsPositiveInfinity(a.vector).AsUInt32()); return new(a.x.isPosInf(), a.y.isPosInf()); } @@ -36,7 +36,7 @@ public static b32v2 isPosInf([This] float2 a) public static b32v2 isNegInf([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(Vector64.Equals(a.vector, Vector64.Create(float.NegativeInfinity)).AsUInt32()); + return new(Vector64.IsNegativeInfinity(a.vector).AsUInt32()); return new(a.x.isNegInf(), a.y.isNegInf()); } @@ -329,7 +329,7 @@ public static partial class math public static b32v3 isInf([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.IsInfinity(a.vector).AsUInt32()); + return new(Vector128.IsInfinity(a.vector).AsUInt32()); return new(a.x.isInf(), a.y.isInf(), a.z.isInf()); } @@ -337,7 +337,7 @@ public static b32v3 isInf([This] float3 a) public static b32v3 isPosInf([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(Vector128.Equals(a.vector, Vector128.Create(float.PositiveInfinity)).AsUInt32()); + return new(Vector128.IsPositiveInfinity(a.vector).AsUInt32()); return new(a.x.isPosInf(), a.y.isPosInf(), a.z.isPosInf()); } @@ -345,7 +345,7 @@ public static b32v3 isPosInf([This] float3 a) public static b32v3 isNegInf([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(Vector128.Equals(a.vector, Vector128.Create(float.NegativeInfinity)).AsUInt32()); + return new(Vector128.IsNegativeInfinity(a.vector).AsUInt32()); return new(a.x.isNegInf(), a.y.isNegInf(), a.z.isNegInf()); } @@ -640,7 +640,7 @@ public static partial class math public static b32v4 isInf([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.IsInfinity(a.vector).AsUInt32()); + return new(Vector128.IsInfinity(a.vector).AsUInt32()); return new(a.x.isInf(), a.y.isInf(), a.z.isInf(), a.w.isInf()); } @@ -648,7 +648,7 @@ public static b32v4 isInf([This] float4 a) public static b32v4 isPosInf([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(Vector128.Equals(a.vector, Vector128.Create(float.PositiveInfinity)).AsUInt32()); + return new(Vector128.IsPositiveInfinity(a.vector).AsUInt32()); return new(a.x.isPosInf(), a.y.isPosInf(), a.z.isPosInf(), a.w.isPosInf()); } @@ -656,7 +656,7 @@ public static b32v4 isPosInf([This] float4 a) public static b32v4 isNegInf([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(Vector128.Equals(a.vector, Vector128.Create(float.NegativeInfinity)).AsUInt32()); + return new(Vector128.IsNegativeInfinity(a.vector).AsUInt32()); return new(a.x.isNegInf(), a.y.isNegInf(), a.z.isNegInf(), a.w.isNegInf()); } @@ -953,7 +953,7 @@ public static partial class math public static b64v2 isInf([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.IsInfinity(a.vector).AsUInt64()); + return new(Vector128.IsInfinity(a.vector).AsUInt64()); return new(a.x.isInf(), a.y.isInf()); } @@ -961,7 +961,7 @@ public static b64v2 isInf([This] double2 a) public static b64v2 isPosInf([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(Vector128.Equals(a.vector, Vector128.Create(double.PositiveInfinity)).AsUInt64()); + return new(Vector128.IsPositiveInfinity(a.vector).AsUInt64()); return new(a.x.isPosInf(), a.y.isPosInf()); } @@ -969,7 +969,7 @@ public static b64v2 isPosInf([This] double2 a) public static b64v2 isNegInf([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(Vector128.Equals(a.vector, Vector128.Create(double.NegativeInfinity)).AsUInt64()); + return new(Vector128.IsNegativeInfinity(a.vector).AsUInt64()); return new(a.x.isNegInf(), a.y.isNegInf()); } @@ -1262,7 +1262,7 @@ public static partial class math public static b64v3 isInf([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.IsInfinity(a.vector).AsUInt64()); + return new(Vector256.IsInfinity(a.vector).AsUInt64()); return new(a.x.isInf(), a.y.isInf(), a.z.isInf()); } @@ -1270,7 +1270,7 @@ public static b64v3 isInf([This] double3 a) public static b64v3 isPosInf([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(Vector256.Equals(a.vector, Vector256.Create(double.PositiveInfinity)).AsUInt64()); + return new(Vector256.IsPositiveInfinity(a.vector).AsUInt64()); return new(a.x.isPosInf(), a.y.isPosInf(), a.z.isPosInf()); } @@ -1278,7 +1278,7 @@ public static b64v3 isPosInf([This] double3 a) public static b64v3 isNegInf([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(Vector256.Equals(a.vector, Vector256.Create(double.NegativeInfinity)).AsUInt64()); + return new(Vector256.IsNegativeInfinity(a.vector).AsUInt64()); return new(a.x.isNegInf(), a.y.isNegInf(), a.z.isNegInf()); } @@ -1573,7 +1573,7 @@ public static partial class math public static b64v4 isInf([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.IsInfinity(a.vector).AsUInt64()); + return new(Vector256.IsInfinity(a.vector).AsUInt64()); return new(a.x.isInf(), a.y.isInf(), a.z.isInf(), a.w.isInf()); } @@ -1581,7 +1581,7 @@ public static b64v4 isInf([This] double4 a) public static b64v4 isPosInf([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(Vector256.Equals(a.vector, Vector256.Create(double.PositiveInfinity)).AsUInt64()); + return new(Vector256.IsPositiveInfinity(a.vector).AsUInt64()); return new(a.x.isPosInf(), a.y.isPosInf(), a.z.isPosInf(), a.w.isPosInf()); } @@ -1589,7 +1589,7 @@ public static b64v4 isPosInf([This] double4 a) public static b64v4 isNegInf([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(Vector256.Equals(a.vector, Vector256.Create(double.NegativeInfinity)).AsUInt64()); + return new(Vector256.IsNegativeInfinity(a.vector).AsUInt64()); return new(a.x.isNegInf(), a.y.isNegInf(), a.z.isNegInf(), a.w.isNegInf()); } diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt index 1b0c09a..d04db1c 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt @@ -45,7 +45,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.IsInfinity(a.vector).AsUInt<#= bSize #>()); + return new(Vector<#= bitSize #>.IsInfinity(a.vector).AsUInt<#= bSize #>()); <# } #> @@ -60,7 +60,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(Vector<#= bitSize #>.Equals(a.vector, Vector<#= bitSize #>.Create(<#= typ.simdComp #>.PositiveInfinity)).AsUInt<#= bSize #>()); + return new(Vector<#= bitSize #>.IsPositiveInfinity(a.vector).AsUInt<#= bSize #>()); <# } #> @@ -75,7 +75,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(Vector<#= bitSize #>.Equals(a.vector, Vector<#= bitSize #>.Create(<#= typ.simdComp #>.NegativeInfinity)).AsUInt<#= bSize #>()); + return new(Vector<#= bitSize #>.IsNegativeInfinity(a.vector).AsUInt<#= bSize #>()); <# } #> diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 21b20ef..b9dd6be 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,10 +1,10 @@ - net9.0 + net10.0 enable enable - 13.0 + 14.0 false true MathTests From 21bff7e32bc33073e74d3fbf8c299dff7f438536 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Thu, 9 Jul 2026 14:12:06 +0800 Subject: [PATCH 2/5] Round Truncate fms fnma --- Coplt.Mathematics/simd/simd.cs | 376 +----------------- Coplt.Mathematics/simd/simd.math.cs | 86 ++-- Coplt.Mathematics/simd/simd.math.tt | 14 +- .../vec/arith/vec.arith.float.cs | 24 +- .../vec/arith/vec.arith.float.tt | 4 +- 5 files changed, 85 insertions(+), 419 deletions(-) diff --git a/Coplt.Mathematics/simd/simd.cs b/Coplt.Mathematics/simd/simd.cs index b0fa705..f602bdc 100644 --- a/Coplt.Mathematics/simd/simd.cs +++ b/Coplt.Mathematics/simd/simd.cs @@ -777,312 +777,6 @@ public static Vector512 ShiftRight(Vector512 a, Vector512 b) #endregion - #region Round - - [MethodImpl(256 | 512)] - public static Vector64 Round(Vector64 x) - { - #if NET9_0_OR_GREATER - return Vector64.Round(x); - #else - if (Sse41.IsSupported) - { - return Sse41.RoundToNearestInteger(x.ToVector128()).GetLower(); - } - if (AdvSimd.IsSupported) - { - return AdvSimd.RoundToNearest(x); - } - if (PackedSimd.IsSupported) - { - return PackedSimd.RoundToNearest(x.ToVector128()).GetLower(); - } - return Vector64.Create( - MathF.Round(x.GetElement(0)), - MathF.Round(x.GetElement(1)) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector128 Round(Vector128 x) - { - #if NET9_0_OR_GREATER - return Vector128.Round(x); - #else - if (Sse41.IsSupported) - { - return Sse41.RoundToNearestInteger(x); - } - if (AdvSimd.IsSupported) - { - return AdvSimd.RoundToNearest(x); - } - if (PackedSimd.IsSupported) - { - return PackedSimd.RoundToNearest(x); - } - return Vector128.Create( - Round(x.GetLower()), - Round(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector256 Round(Vector256 x) - { - #if NET9_0_OR_GREATER - return Vector256.Round(x); - #else - if (Avx.IsSupported) - { - return Avx.RoundToNearestInteger(x); - } - return Vector256.Create( - Round(x.GetLower()), - Round(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector512 Round(Vector512 x) - { - #if NET9_0_OR_GREATER - return Vector512.Round(x); - #else - if (Avx512F.IsSupported) - { - return Avx512F.RoundScale(x, 0); - } - return Vector512.Create( - Round(x.GetLower()), - Round(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector128 Round(Vector128 x) - { - #if NET9_0_OR_GREATER - return Vector128.Round(x); - #else - if (Sse41.IsSupported) - { - return Sse41.RoundToNearestInteger(x); - } - if (AdvSimd.Arm64.IsSupported) - { - return AdvSimd.Arm64.RoundToNearest(x); - } - if (PackedSimd.IsSupported) - { - return PackedSimd.RoundToNearest(x); - } - return Vector128.Create( - Math.Round(x.GetElement(0)), - Math.Round(x.GetElement(1)) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector256 Round(Vector256 x) - { - #if NET9_0_OR_GREATER - return Vector256.Round(x); - #else - if (Avx.IsSupported) - { - return Avx.RoundToNearestInteger(x); - } - return Vector256.Create( - Round(x.GetLower()), - Round(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector512 Round(Vector512 x) - { - #if NET9_0_OR_GREATER - return Vector512.Round(x); - #else - if (Avx512F.IsSupported) - { - return Avx512F.RoundScale(x, 0); - } - return Vector512.Create( - Round(x.GetLower()), - Round(x.GetUpper()) - ); - #endif - } - - public static bool IsRoundF256HardwareAccelerated - { - [MethodImpl(256 | 512)] - get => Avx.IsSupported; - } - - public static bool IsRoundD512HardwareAccelerated - { - [MethodImpl(256 | 512)] - get => Avx512F.IsSupported; - } - - #endregion - - #region RoundToZero - - [MethodImpl(256 | 512)] - public static Vector64 RoundToZero(Vector64 x) - { - #if NET9_0_OR_GREATER - return Vector64.Truncate(x); - #else - if (Sse41.IsSupported) - { - return Sse41.RoundToZero(x.ToVector128()).GetLower(); - } - if (AdvSimd.IsSupported) - { - return AdvSimd.RoundToZero(x); - } - if (PackedSimd.IsSupported) - { - return PackedSimd.Truncate(x.ToVector128()).GetLower(); - } - return Vector64.Create( - MathF.Round(x.GetElement(0), MidpointRounding.ToZero), - MathF.Round(x.GetElement(1), MidpointRounding.ToZero) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector128 RoundToZero(Vector128 x) - { - #if NET9_0_OR_GREATER - return Vector128.Truncate(x); - #else - if (Sse41.IsSupported) - { - return Sse41.RoundToZero(x); - } - if (AdvSimd.IsSupported) - { - return AdvSimd.RoundToZero(x); - } - if (PackedSimd.IsSupported) - { - return PackedSimd.Truncate(x); - } - return Vector128.Create( - RoundToZero(x.GetLower()), - RoundToZero(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector256 RoundToZero(Vector256 x) - { - #if NET9_0_OR_GREATER - return Vector256.Truncate(x); - #else - if (Avx.IsSupported) - { - return Avx.RoundToZero(x); - } - return Vector256.Create( - RoundToZero(x.GetLower()), - RoundToZero(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector512 RoundToZero(Vector512 x) - { - #if NET9_0_OR_GREATER - return Vector512.Truncate(x); - #else - if (Avx512F.IsSupported) - { - return Avx512F.RoundScale(x, 3); - } - return Vector512.Create( - RoundToZero(x.GetLower()), - RoundToZero(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector128 RoundToZero(Vector128 x) - { - #if NET9_0_OR_GREATER - return Vector128.Truncate(x); - #else - if (Sse41.IsSupported) - { - return Sse41.RoundToZero(x); - } - if (AdvSimd.Arm64.IsSupported) - { - return AdvSimd.Arm64.RoundToZero(x); - } - if (PackedSimd.IsSupported) - { - return PackedSimd.Truncate(x); - } - return Vector128.Create( - Math.Round(x.GetElement(0), MidpointRounding.ToZero), - Math.Round(x.GetElement(1), MidpointRounding.ToZero) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector256 RoundToZero(Vector256 x) - { - #if NET9_0_OR_GREATER - return Vector256.Truncate(x); - #else - if (Avx.IsSupported) - { - return Avx.RoundToZero(x); - } - return Vector256.Create( - RoundToZero(x.GetLower()), - RoundToZero(x.GetUpper()) - ); - #endif - } - - [MethodImpl(256 | 512)] - public static Vector512 RoundToZero(Vector512 x) - { - #if NET9_0_OR_GREATER - return Vector512.Truncate(x); - #else - if (Avx512F.IsSupported) - { - return Avx512F.RoundScale(x, 3); - } - return Vector512.Create( - RoundToZero(x.GetLower()), - RoundToZero(x.GetUpper()) - ); - #endif - } - - #endregion - #region Rem [MethodImpl(256 | 512)] @@ -1514,7 +1208,7 @@ public static Vector64 ModF(Vector64 d, out Vector64 i) { if (Vector64.IsHardwareAccelerated) { - i = RoundToZero(d); + i = Vector64.Truncate(d); return d - i; } if (Vector128.IsHardwareAccelerated) @@ -1537,7 +1231,7 @@ public static Vector128 ModF(Vector128 d, out Vector128 i) { if (Vector128.IsHardwareAccelerated) { - i = RoundToZero(d); + i = Vector128.Truncate(d); return d - i; } @@ -1554,7 +1248,7 @@ public static Vector256 ModF(Vector256 d, out Vector256 i) { if (Vector256.IsHardwareAccelerated) { - i = RoundToZero(d); + i = Vector256.Truncate(d); return d - i; } @@ -1571,7 +1265,7 @@ public static Vector512 ModF(Vector512 d, out Vector512 i) { if (Vector512.IsHardwareAccelerated) { - i = RoundToZero(d); + i = Vector512.Truncate(d); return d - i; } @@ -1588,7 +1282,7 @@ public static Vector128 ModF(Vector128 d, out Vector128 { if (Vector128.IsHardwareAccelerated) { - i = RoundToZero(d); + i = Vector128.Truncate(d); return d - i; } @@ -1605,7 +1299,7 @@ public static Vector256 ModF(Vector256 d, out Vector256 { if (Vector256.IsHardwareAccelerated) { - i = RoundToZero(d); + i = Vector256.Truncate(d); return d - i; } @@ -1622,7 +1316,7 @@ public static Vector512 ModF(Vector512 d, out Vector512 { if (Vector512.IsHardwareAccelerated) { - i = RoundToZero(d); + i = Vector512.Truncate(d); return d - i; } @@ -1859,11 +1553,7 @@ public static Vector64 Fms(Vector64 a, Vector64 b, Vector64 { return X86.Fma.MultiplySubtract(a.ToVector128(), b.ToVector128(), c.ToVector128()).GetLower(); } - if (AdvSimd.IsSupported) - { - return AdvSimd.FusedMultiplyAdd(-c, a, b); - } - return a * b - c; + return Vector64.FusedMultiplyAdd(a, b, -c); } /// a * b - c @@ -1874,11 +1564,7 @@ public static Vector128 Fms(Vector128 a, Vector128 b, Vecto { return X86.Fma.MultiplySubtract(a, b, c); } - if (AdvSimd.IsSupported) - { - return AdvSimd.FusedMultiplyAdd(-c, a, b); - } - return a * b - c; + return Vector128.FusedMultiplyAdd(a, b, -c); } /// a * b - c @@ -1889,11 +1575,7 @@ public static Vector128 Fms(Vector128 a, Vector128 b, Ve { return X86.Fma.MultiplySubtract(a, b, c); } - if (AdvSimd.Arm64.IsSupported) - { - return AdvSimd.Arm64.FusedMultiplyAdd(-c, a, b); - } - return a * b - c; + return Vector128.FusedMultiplyAdd(a, b, -c); } /// a * b - c @@ -1904,15 +1586,7 @@ public static Vector256 Fms(Vector256 a, Vector256 b, Vecto { return X86.Fma.MultiplySubtract(a, b, c); } - if (AdvSimd.IsSupported) - { - var nc = -c; - return Vector256.Create( - AdvSimd.FusedMultiplyAdd(nc.GetLower(), a.GetLower(), b.GetLower()), - AdvSimd.FusedMultiplyAdd(nc.GetUpper(), a.GetUpper(), b.GetUpper()) - ); - } - return a * b - c; + return Vector256.FusedMultiplyAdd(a, b, -c); } /// a * b - c @@ -1923,15 +1597,7 @@ public static Vector256 Fms(Vector256 a, Vector256 b, Ve { return X86.Fma.MultiplySubtract(a, b, c); } - if (AdvSimd.Arm64.IsSupported) - { - var nc = -c; - return Vector256.Create( - AdvSimd.Arm64.FusedMultiplyAdd(nc.GetLower(), a.GetLower(), b.GetLower()), - AdvSimd.Arm64.FusedMultiplyAdd(nc.GetUpper(), a.GetUpper(), b.GetUpper()) - ); - } - return a * b - c; + return Vector256.FusedMultiplyAdd(a, b, -c); } /// a * b - c @@ -1949,7 +1615,7 @@ public static Vector512 Fms(Vector512 a, Vector512 b, Vecto X86.Fma.MultiplySubtract(a.GetUpper(), b.GetUpper(), c.GetUpper()) ); } - return a * b - c; + return Vector512.FusedMultiplyAdd(a, b, -c); } /// a * b - c @@ -1967,7 +1633,7 @@ public static Vector512 Fms(Vector512 a, Vector512 b, Ve X86.Fma.MultiplySubtract(a.GetUpper(), b.GetUpper(), c.GetUpper()) ); } - return a * b - c; + return Vector512.FusedMultiplyAdd(a, b, -c); } #endregion @@ -1986,7 +1652,7 @@ public static Vector64 Fnma(Vector64 a, Vector64 b, Vector6 { return AdvSimd.FusedMultiplySubtract(c, a, b); } - return c - a * b; + return Vector64.FusedMultiplyAdd(-a, b, c); } /// c - a * b or -(a * b) + c @@ -2001,7 +1667,7 @@ public static Vector128 Fnma(Vector128 a, Vector128 b, Vect { return AdvSimd.FusedMultiplySubtract(c, a, b); } - return c - a * b; + return Vector128.FusedMultiplyAdd(-a, b, c); } /// c - a * b or -(a * b) + c @@ -2016,7 +1682,7 @@ public static Vector128 Fnma(Vector128 a, Vector128 b, V { return AdvSimd.Arm64.FusedMultiplySubtract(c, a, b); } - return c - a * b; + return Vector128.FusedMultiplyAdd(-a, b, c); } /// c - a * b or -(a * b) + c @@ -2034,7 +1700,7 @@ public static Vector256 Fnma(Vector256 a, Vector256 b, Vect AdvSimd.FusedMultiplySubtract(c.GetUpper(), a.GetUpper(), b.GetUpper()) ); } - return c - a * b; + return Vector256.FusedMultiplyAdd(-a, b, c); } /// c - a * b or -(a * b) + c @@ -2052,7 +1718,7 @@ public static Vector256 Fnma(Vector256 a, Vector256 b, V AdvSimd.Arm64.FusedMultiplySubtract(c.GetUpper(), a.GetUpper(), b.GetUpper()) ); } - return c - a * b; + return Vector256.FusedMultiplyAdd(-a, b, c); } /// c - a * b or -(a * b) + c @@ -2070,7 +1736,7 @@ public static Vector512 Fnma(Vector512 a, Vector512 b, Vect Fnma(a.GetUpper(), b.GetUpper(), c.GetUpper()) ); } - return c - a * b; + return Vector512.FusedMultiplyAdd(-a, b, c); } /// c - a * b or -(a * b) + c @@ -2081,7 +1747,7 @@ public static Vector512 Fnma(Vector512 a, Vector512 b, V { return Avx512F.FusedMultiplyAddNegated(a, b, c); } - return c - a * b; + return Vector512.FusedMultiplyAdd(-a, b, c); } #endregion diff --git a/Coplt.Mathematics/simd/simd.math.cs b/Coplt.Mathematics/simd/simd.math.cs index f221240..c4db8ab 100644 --- a/Coplt.Mathematics/simd/simd.math.cs +++ b/Coplt.Mathematics/simd/simd.math.cs @@ -156,7 +156,7 @@ public static Vector512 Mod(Vector512 x, f64 y) public static Vector64 Rem(Vector64 x, Vector64 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector64.Truncate(div); return simd.Fnma(flr, y, x); } @@ -164,7 +164,7 @@ public static Vector64 Rem(Vector64 x, Vector64 y) public static Vector64 Rem(Vector64 x, f32 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector64.Truncate(div); return simd.Fnma(flr, Vector64.Create(y), x); } @@ -176,7 +176,7 @@ public static Vector64 Rem(Vector64 x, f32 y) public static Vector128 Rem(Vector128 x, Vector128 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, y, x); } @@ -184,7 +184,7 @@ public static Vector128 Rem(Vector128 x, Vector128 y) public static Vector128 Rem(Vector128 x, f32 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(y), x); } @@ -196,7 +196,7 @@ public static Vector128 Rem(Vector128 x, f32 y) public static Vector256 Rem(Vector256 x, Vector256 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, y, x); } @@ -204,7 +204,7 @@ public static Vector256 Rem(Vector256 x, Vector256 y) public static Vector256 Rem(Vector256 x, f32 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(y), x); } @@ -216,7 +216,7 @@ public static Vector256 Rem(Vector256 x, f32 y) public static Vector512 Rem(Vector512 x, Vector512 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, y, x); } @@ -224,7 +224,7 @@ public static Vector512 Rem(Vector512 x, Vector512 y) public static Vector512 Rem(Vector512 x, f32 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(y), x); } @@ -236,7 +236,7 @@ public static Vector512 Rem(Vector512 x, f32 y) public static Vector128 Rem(Vector128 x, Vector128 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, y, x); } @@ -244,7 +244,7 @@ public static Vector128 Rem(Vector128 x, Vector128 y) public static Vector128 Rem(Vector128 x, f64 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(y), x); } @@ -256,7 +256,7 @@ public static Vector128 Rem(Vector128 x, f64 y) public static Vector256 Rem(Vector256 x, Vector256 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, y, x); } @@ -264,7 +264,7 @@ public static Vector256 Rem(Vector256 x, Vector256 y) public static Vector256 Rem(Vector256 x, f64 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(y), x); } @@ -276,7 +276,7 @@ public static Vector256 Rem(Vector256 x, f64 y) public static Vector512 Rem(Vector512 x, Vector512 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, y, x); } @@ -284,7 +284,7 @@ public static Vector512 Rem(Vector512 x, Vector512 y) public static Vector512 Rem(Vector512 x, f64 y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(y), x); } @@ -317,7 +317,7 @@ public static Vector64 Wrap0ToPi(Vector64 x) { var add = x + (Vector64.LessThan(x, default) & Vector64.Create(math.F_PI)); var div = x * math.F_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = Vector64.Truncate(div); return simd.Fnma(flr, Vector64.Create(math.F_PI), add); } @@ -326,7 +326,7 @@ public static Vector64 Wrap0To2Pi(Vector64 x) { var add = x + (Vector64.LessThan(x, default) & Vector64.Create(math.F_2_PI)); var div = x * math.F_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = Vector64.Truncate(div); return simd.Fnma(flr, Vector64.Create(math.F_2_PI), add); } @@ -335,7 +335,7 @@ public static Vector64 Wrap0To4Pi(Vector64 x) { var add = x + (Vector64.LessThan(x, default) & Vector64.Create(math.F_4_PI)); var div = x * math.F_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = Vector64.Truncate(div); return simd.Fnma(flr, Vector64.Create(math.F_4_PI), add); } @@ -364,7 +364,7 @@ public static Vector128 Wrap0ToPi(Vector128 x) { var add = x + (Vector128.LessThan(x, default) & Vector128.Create(math.F_PI)); var div = x * math.F_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(math.F_PI), add); } @@ -373,7 +373,7 @@ public static Vector128 Wrap0To2Pi(Vector128 x) { var add = x + (Vector128.LessThan(x, default) & Vector128.Create(math.F_2_PI)); var div = x * math.F_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(math.F_2_PI), add); } @@ -382,7 +382,7 @@ public static Vector128 Wrap0To4Pi(Vector128 x) { var add = x + (Vector128.LessThan(x, default) & Vector128.Create(math.F_4_PI)); var div = x * math.F_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(math.F_4_PI), add); } @@ -411,7 +411,7 @@ public static Vector256 Wrap0ToPi(Vector256 x) { var add = x + (Vector256.LessThan(x, default) & Vector256.Create(math.F_PI)); var div = x * math.F_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(math.F_PI), add); } @@ -420,7 +420,7 @@ public static Vector256 Wrap0To2Pi(Vector256 x) { var add = x + (Vector256.LessThan(x, default) & Vector256.Create(math.F_2_PI)); var div = x * math.F_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(math.F_2_PI), add); } @@ -429,7 +429,7 @@ public static Vector256 Wrap0To4Pi(Vector256 x) { var add = x + (Vector256.LessThan(x, default) & Vector256.Create(math.F_4_PI)); var div = x * math.F_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(math.F_4_PI), add); } @@ -458,7 +458,7 @@ public static Vector512 Wrap0ToPi(Vector512 x) { var add = x + (Vector512.LessThan(x, default) & Vector512.Create(math.F_PI)); var div = x * math.F_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(math.F_PI), add); } @@ -467,7 +467,7 @@ public static Vector512 Wrap0To2Pi(Vector512 x) { var add = x + (Vector512.LessThan(x, default) & Vector512.Create(math.F_2_PI)); var div = x * math.F_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(math.F_2_PI), add); } @@ -476,7 +476,7 @@ public static Vector512 Wrap0To4Pi(Vector512 x) { var add = x + (Vector512.LessThan(x, default) & Vector512.Create(math.F_4_PI)); var div = x * math.F_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(math.F_4_PI), add); } @@ -505,7 +505,7 @@ public static Vector128 Wrap0ToPi(Vector128 x) { var add = x + (Vector128.LessThan(x, default) & Vector128.Create(math.D_PI)); var div = x * math.D_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(math.D_PI), add); } @@ -514,7 +514,7 @@ public static Vector128 Wrap0To2Pi(Vector128 x) { var add = x + (Vector128.LessThan(x, default) & Vector128.Create(math.D_2_PI)); var div = x * math.D_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(math.D_2_PI), add); } @@ -523,7 +523,7 @@ public static Vector128 Wrap0To4Pi(Vector128 x) { var add = x + (Vector128.LessThan(x, default) & Vector128.Create(math.D_4_PI)); var div = x * math.D_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = Vector128.Truncate(div); return simd.Fnma(flr, Vector128.Create(math.D_4_PI), add); } @@ -552,7 +552,7 @@ public static Vector256 Wrap0ToPi(Vector256 x) { var add = x + (Vector256.LessThan(x, default) & Vector256.Create(math.D_PI)); var div = x * math.D_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(math.D_PI), add); } @@ -561,7 +561,7 @@ public static Vector256 Wrap0To2Pi(Vector256 x) { var add = x + (Vector256.LessThan(x, default) & Vector256.Create(math.D_2_PI)); var div = x * math.D_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(math.D_2_PI), add); } @@ -570,7 +570,7 @@ public static Vector256 Wrap0To4Pi(Vector256 x) { var add = x + (Vector256.LessThan(x, default) & Vector256.Create(math.D_4_PI)); var div = x * math.D_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = Vector256.Truncate(div); return simd.Fnma(flr, Vector256.Create(math.D_4_PI), add); } @@ -599,7 +599,7 @@ public static Vector512 Wrap0ToPi(Vector512 x) { var add = x + (Vector512.LessThan(x, default) & Vector512.Create(math.D_PI)); var div = x * math.D_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(math.D_PI), add); } @@ -608,7 +608,7 @@ public static Vector512 Wrap0To2Pi(Vector512 x) { var add = x + (Vector512.LessThan(x, default) & Vector512.Create(math.D_2_PI)); var div = x * math.D_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(math.D_2_PI), add); } @@ -617,7 +617,7 @@ public static Vector512 Wrap0To4Pi(Vector512 x) { var add = x + (Vector512.LessThan(x, default) & Vector512.Create(math.D_4_PI)); var div = x * math.D_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = Vector512.Truncate(div); return simd.Fnma(flr, Vector512.Create(math.D_4_PI), add); } @@ -648,7 +648,7 @@ private static Vector64 Log2_impl(Vector64 a) xl = (xl & Vector64.Create(0x7FFFFF)) | Vector64.Create(0x7F << 23); var d = (xl.AsSingle() | Vector64.One) * Vector64.Create(2.0f / 3.0f); - + #region Approx // A Taylor Series approximation of ln(x) that relies on the identity that ln(x) = 2*atan((x-1)/(x+1)). @@ -1061,7 +1061,7 @@ private static Vector64 Exp2_impl(Vector64 x) Vector64.Create(-81.0f * math.F_1_Div_Log2) ); - var fx = simd.Round(xx); + var fx = Vector64.Round(xx); xx -= fx; var r = simd.Fma(xx, Vector64.Create(1.530610536076361E-05f), Vector64.Create(0.000154631026827329f)); @@ -1104,7 +1104,7 @@ private static Vector128 Exp2_impl(Vector128 x) Vector128.Create(-81.0f * math.F_1_Div_Log2) ); - var fx = simd.Round(xx); + var fx = Vector128.Round(xx); xx -= fx; var r = simd.Fma(xx, Vector128.Create(1.530610536076361E-05f), Vector128.Create(0.000154631026827329f)); @@ -1147,7 +1147,7 @@ private static Vector256 Exp2_impl(Vector256 x) Vector256.Create(-81.0f * math.F_1_Div_Log2) ); - var fx = simd.Round(xx); + var fx = Vector256.Round(xx); xx -= fx; var r = simd.Fma(xx, Vector256.Create(1.530610536076361E-05f), Vector256.Create(0.000154631026827329f)); @@ -1190,7 +1190,7 @@ private static Vector512 Exp2_impl(Vector512 x) Vector512.Create(-81.0f * math.F_1_Div_Log2) ); - var fx = simd.Round(xx); + var fx = Vector512.Round(xx); xx -= fx; var r = simd.Fma(xx, Vector512.Create(1.530610536076361E-05f), Vector512.Create(0.000154631026827329f)); @@ -1232,7 +1232,7 @@ private static Vector128 Exp2_impl(Vector128 x) Vector128.Min(x, Vector128.Create(709.0 * 1.4426950408889634)), Vector128.Create(-709.0 * 1.4426950408889634) ); - var fx = simd.Round(xx); + var fx = Vector128.Round(xx); xx -= fx; var sq = xx * xx; @@ -1279,7 +1279,7 @@ private static Vector256 Exp2_impl(Vector256 x) Vector256.Min(x, Vector256.Create(709.0 * 1.4426950408889634)), Vector256.Create(-709.0 * 1.4426950408889634) ); - var fx = simd.Round(xx); + var fx = Vector256.Round(xx); xx -= fx; var sq = xx * xx; @@ -1326,7 +1326,7 @@ private static Vector512 Exp2_impl(Vector512 x) Vector512.Min(x, Vector512.Create(709.0 * 1.4426950408889634)), Vector512.Create(-709.0 * 1.4426950408889634) ); - var fx = simd.Round(xx); + var fx = Vector512.Round(xx); xx -= fx; var sq = xx * xx; diff --git a/Coplt.Mathematics/simd/simd.math.tt b/Coplt.Mathematics/simd/simd.math.tt index 20a2809..ce2a74a 100644 --- a/Coplt.Mathematics/simd/simd.math.tt +++ b/Coplt.Mathematics/simd/simd.math.tt @@ -63,7 +63,7 @@ public static partial class simd_math public static <#= vt #> Rem(<#= vt #> x, <#= vt #> y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = <#= vector #>.Truncate(div); return simd.Fnma(flr, y, x); } @@ -71,7 +71,7 @@ public static partial class simd_math public static <#= vt #> Rem(<#= vt #> x, <#= type #> y) { var div = x / y; - var flr = simd.RoundToZero(div); + var flr = <#= vector #>.Truncate(div); return simd.Fnma(flr, <#= vector #>.Create(y), x); } @@ -114,7 +114,7 @@ public static partial class simd_math { var add = x + (<#= vector #>.LessThan(x, default) & <#= vector #>.Create(math.<#= mc #>_PI)); var div = x * math.<#= mc #>_1_Div_PI; - var flr = simd.RoundToZero(div); + var flr = <#= vector #>.Truncate(div); return simd.Fnma(flr, <#= vector #>.Create(math.<#= mc #>_PI), add); } @@ -123,7 +123,7 @@ public static partial class simd_math { var add = x + (<#= vector #>.LessThan(x, default) & <#= vector #>.Create(math.<#= mc #>_2_PI)); var div = x * math.<#= mc #>_1_Div_2_PI; - var flr = simd.RoundToZero(div); + var flr = <#= vector #>.Truncate(div); return simd.Fnma(flr, <#= vector #>.Create(math.<#= mc #>_2_PI), add); } @@ -132,7 +132,7 @@ public static partial class simd_math { var add = x + (<#= vector #>.LessThan(x, default) & <#= vector #>.Create(math.<#= mc #>_4_PI)); var div = x * math.<#= mc #>_1_Div_4_PI; - var flr = simd.RoundToZero(div); + var flr = <#= vector #>.Truncate(div); return simd.Fnma(flr, <#= vector #>.Create(math.<#= mc #>_4_PI), add); } @@ -316,7 +316,7 @@ public static partial class simd_math <#= vector #>.Create(-81.0f * math.F_1_Div_Log2) ); - var fx = simd.Round(xx); + var fx = <#= vector #>.Round(xx); xx -= fx; var r = simd.Fma(xx, <#= vector #>.Create(1.530610536076361E-05f), <#= vector #>.Create(0.000154631026827329f)); @@ -369,7 +369,7 @@ public static partial class simd_math <#= vector #>.Min(x, <#= vector #>.Create(709.0 * 1.4426950408889634)), <#= vector #>.Create(-709.0 * 1.4426950408889634) ); - var fx = simd.Round(xx); + var fx = <#= vector #>.Round(xx); xx -= fx; var sq = xx * xx; diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.cs b/Coplt.Mathematics/vec/arith/vec.arith.float.cs index 7037630..ec951e7 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.cs +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.cs @@ -95,7 +95,7 @@ public static float2 floor([This] float2 a) public static float2 round([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.Round(a.vector)); + return new(Vector64.Round(a.vector)); return new(a.x.round(), a.y.round()); } @@ -103,7 +103,7 @@ public static float2 round([This] float2 a) public static float2 trunc([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.RoundToZero(a.vector)); + return new(Vector64.Truncate(a.vector)); return new(a.x.trunc(), a.y.trunc()); } @@ -300,7 +300,7 @@ public static float3 floor([This] float3 a) public static float3 round([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Round(a.vector)); + return new(Vector128.Round(a.vector)); return new(a.x.round(), a.y.round(), a.z.round()); } @@ -308,7 +308,7 @@ public static float3 round([This] float3 a) public static float3 trunc([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.RoundToZero(a.vector)); + return new(Vector128.Truncate(a.vector)); return new(a.x.trunc(), a.y.trunc(), a.z.trunc()); } @@ -505,7 +505,7 @@ public static float4 floor([This] float4 a) public static float4 round([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Round(a.vector)); + return new(Vector128.Round(a.vector)); return new(a.x.round(), a.y.round(), a.z.round(), a.w.round()); } @@ -513,7 +513,7 @@ public static float4 round([This] float4 a) public static float4 trunc([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.RoundToZero(a.vector)); + return new(Vector128.Truncate(a.vector)); return new(a.x.trunc(), a.y.trunc(), a.z.trunc(), a.w.trunc()); } @@ -710,7 +710,7 @@ public static double2 floor([This] double2 a) public static double2 round([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Round(a.vector)); + return new(Vector128.Round(a.vector)); return new(a.x.round(), a.y.round()); } @@ -718,7 +718,7 @@ public static double2 round([This] double2 a) public static double2 trunc([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.RoundToZero(a.vector)); + return new(Vector128.Truncate(a.vector)); return new(a.x.trunc(), a.y.trunc()); } @@ -915,7 +915,7 @@ public static double3 floor([This] double3 a) public static double3 round([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Round(a.vector)); + return new(Vector256.Round(a.vector)); return new(a.x.round(), a.y.round(), a.z.round()); } @@ -923,7 +923,7 @@ public static double3 round([This] double3 a) public static double3 trunc([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.RoundToZero(a.vector)); + return new(Vector256.Truncate(a.vector)); return new(a.x.trunc(), a.y.trunc(), a.z.trunc()); } @@ -1120,7 +1120,7 @@ public static double4 floor([This] double4 a) public static double4 round([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Round(a.vector)); + return new(Vector256.Round(a.vector)); return new(a.x.round(), a.y.round(), a.z.round(), a.w.round()); } @@ -1128,7 +1128,7 @@ public static double4 round([This] double4 a) public static double4 trunc([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.RoundToZero(a.vector)); + return new(Vector256.Truncate(a.vector)); return new(a.x.trunc(), a.y.trunc(), a.z.trunc(), a.w.trunc()); } diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.tt b/Coplt.Mathematics/vec/arith/vec.arith.float.tt index 98945fa..5d6f674 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.tt +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.tt @@ -142,7 +142,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Round(a.vector)); + return new(Vector<#= bitSize #>.Round(a.vector)); <# } #> @@ -157,7 +157,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.RoundToZero(a.vector)); + return new(Vector<#= bitSize #>.Truncate(a.vector)); <# } #> From 36b91f0e0d93bd83f598d2962cc0039f7ef60df2 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Thu, 9 Jul 2026 14:56:30 +0800 Subject: [PATCH 3/5] lerp --- Coplt.Mathematics/vec/arith/vec.arith.cs | 12 ++++++------ Coplt.Mathematics/vec/arith/vec.arith.tt | 9 ++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Coplt.Mathematics/vec/arith/vec.arith.cs b/Coplt.Mathematics/vec/arith/vec.arith.cs index 4e609f8..cb9621b 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.cs +++ b/Coplt.Mathematics/vec/arith/vec.arith.cs @@ -163,7 +163,7 @@ public static float2 clamp([This] float2 v, float2 min, float2 max) public static float2 lerp(float2 start, float2 end, [This] float2 t) { if (Vector64.IsHardwareAccelerated) - return fma(t, end - start, start); + return new(Vector64.Lerp(start.vector, end.vector, t.vector)); return start + t * (end - start); } @@ -497,7 +497,7 @@ public static float3 clamp([This] float3 v, float3 min, float3 max) public static float3 lerp(float3 start, float3 end, [This] float3 t) { if (Vector128.IsHardwareAccelerated) - return fma(t, end - start, start); + return new(Vector128.Lerp(start.vector, end.vector, t.vector)); return start + t * (end - start); } @@ -838,7 +838,7 @@ public static float4 clamp([This] float4 v, float4 min, float4 max) public static float4 lerp(float4 start, float4 end, [This] float4 t) { if (Vector128.IsHardwareAccelerated) - return fma(t, end - start, start); + return new(Vector128.Lerp(start.vector, end.vector, t.vector)); return start + t * (end - start); } @@ -1172,7 +1172,7 @@ public static double2 clamp([This] double2 v, double2 min, double2 max) public static double2 lerp(double2 start, double2 end, [This] double2 t) { if (Vector128.IsHardwareAccelerated) - return fma(t, end - start, start); + return new(Vector128.Lerp(start.vector, end.vector, t.vector)); return start + t * (end - start); } @@ -1506,7 +1506,7 @@ public static double3 clamp([This] double3 v, double3 min, double3 max) public static double3 lerp(double3 start, double3 end, [This] double3 t) { if (Vector256.IsHardwareAccelerated) - return fma(t, end - start, start); + return new(Vector256.Lerp(start.vector, end.vector, t.vector)); return start + t * (end - start); } @@ -1847,7 +1847,7 @@ public static double4 clamp([This] double4 v, double4 min, double4 max) public static double4 lerp(double4 start, double4 end, [This] double4 t) { if (Vector256.IsHardwareAccelerated) - return fma(t, end - start, start); + return new(Vector256.Lerp(start.vector, end.vector, t.vector)); return start + t * (end - start); } diff --git a/Coplt.Mathematics/vec/arith/vec.arith.tt b/Coplt.Mathematics/vec/arith/vec.arith.tt index 7868f7c..e365fef 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.tt +++ b/Coplt.Mathematics/vec/arith/vec.arith.tt @@ -378,7 +378,14 @@ public static partial class math public static <#= typeName #> lerp(<#= typeName #> start, <#= typeName #> end, [This] <#= typeName #> t) { <# - if (typ.simd) + if (typ.f && typ.bin && typ.simd) + { +#> + if (Vector<#= bitSize #>.IsHardwareAccelerated) + return new(Vector<#= bitSize #>.Lerp(start.vector, end.vector, t.vector)); +<# + } + else if (typ.simd) { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) From 6643cc06ebf345189bea707b6b23f2d956ebb035 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Thu, 9 Jul 2026 15:19:53 +0800 Subject: [PATCH 4/5] Sin Cos --- Coplt.Mathematics/simd/simd.cs | 311 ------------------ .../simd/simd.math.tri.double.cs | 147 --------- .../simd/simd.math.tri.double.tt | 70 ---- Coplt.Mathematics/simd/simd.math.tri.float.cs | 209 ------------ Coplt.Mathematics/simd/simd.math.tri.float.tt | 80 ----- .../vec/arith/vec.arith.float.bin.cs | 48 +-- .../vec/arith/vec.arith.float.bin.tt | 8 +- Tests/Functions/Cos.cs | 28 ++ Tests/Functions/Sin.cs | 28 ++ Tests/TestSinCos.cs | 56 ---- 10 files changed, 84 insertions(+), 901 deletions(-) create mode 100644 Tests/Functions/Cos.cs create mode 100644 Tests/Functions/Sin.cs delete mode 100644 Tests/TestSinCos.cs diff --git a/Coplt.Mathematics/simd/simd.cs b/Coplt.Mathematics/simd/simd.cs index f602bdc..e4a8410 100644 --- a/Coplt.Mathematics/simd/simd.cs +++ b/Coplt.Mathematics/simd/simd.cs @@ -3305,317 +3305,6 @@ public static Vector512 RSqrt(Vector512 a) #endregion - #region Sin - - [MethodImpl(256 | 512)] - public static Vector64 Sin(Vector64 a) - { - if (Vector64.IsHardwareAccelerated) - { - return simd_math.Sin(a); - } - if (Vector128.IsHardwareAccelerated) - { - return simd_math.Sin(a.ToVector128()).GetLower(); - } - return Vector64.Create( - a.GetElement(0).sin(), - a.GetElement(1).sin() - ); - } - - [MethodImpl(256 | 512)] - public static Vector128 Sin(Vector128 a) - { - if (Vector128.IsHardwareAccelerated) - { - return simd_math.Sin(a); - } - return Vector128.Create( - Sin(a.GetLower()), - Sin(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector256 Sin(Vector256 a) - { - if (Vector256.IsHardwareAccelerated) - { - return simd_math.Sin(a); - } - return Vector256.Create( - Sin(a.GetLower()), - Sin(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector512 Sin(Vector512 a) - { - if (Vector512.IsHardwareAccelerated) - { - return simd_math.Sin(a); - } - return Vector512.Create( - Sin(a.GetLower()), - Sin(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector128 Sin(Vector128 a) - { - if (Vector128.IsHardwareAccelerated) - { - return simd_math.Sin(a); - } - return Vector128.Create( - a.GetElement(0).sin(), - a.GetElement(1).sin() - ); - } - - [MethodImpl(256 | 512)] - public static Vector256 Sin(Vector256 a) - { - if (Vector256.IsHardwareAccelerated) - { - return simd_math.Sin(a); - } - return Vector256.Create( - Sin(a.GetLower()), - Sin(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector512 Sin(Vector512 a) - { - if (Vector512.IsHardwareAccelerated) - { - return simd_math.Sin(a); - } - return Vector512.Create( - Sin(a.GetLower()), - Sin(a.GetUpper()) - ); - } - - #endregion - - #region Cos - - [MethodImpl(256 | 512)] - public static Vector64 Cos(Vector64 a) - { - if (Vector64.IsHardwareAccelerated) - { - return simd_math.Cos(a); - } - if (Vector128.IsHardwareAccelerated) - { - return simd_math.Cos(a.ToVector128()).GetLower(); - } - return Vector64.Create( - a.GetElement(0).cos(), - a.GetElement(1).cos() - ); - } - - [MethodImpl(256 | 512)] - public static Vector128 Cos(Vector128 a) - { - if (Vector128.IsHardwareAccelerated) - { - return simd_math.Cos(a); - } - return Vector128.Create( - Cos(a.GetLower()), - Cos(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector256 Cos(Vector256 a) - { - if (Vector256.IsHardwareAccelerated) - { - return simd_math.Cos(a); - } - return Vector256.Create( - Cos(a.GetLower()), - Cos(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector512 Cos(Vector512 a) - { - if (Vector512.IsHardwareAccelerated) - { - return simd_math.Cos(a); - } - return Vector512.Create( - Cos(a.GetLower()), - Cos(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector128 Cos(Vector128 a) - { - if (Vector128.IsHardwareAccelerated) - { - return simd_math.Cos(a); - } - return Vector128.Create( - a.GetElement(0).cos(), - a.GetElement(1).cos() - ); - } - - [MethodImpl(256 | 512)] - public static Vector256 Cos(Vector256 a) - { - if (Vector256.IsHardwareAccelerated) - { - return simd_math.Cos(a); - } - return Vector256.Create( - Cos(a.GetLower()), - Cos(a.GetUpper()) - ); - } - - [MethodImpl(256 | 512)] - public static Vector512 Cos(Vector512 a) - { - if (Vector512.IsHardwareAccelerated) - { - return simd_math.Cos(a); - } - return Vector512.Create( - Cos(a.GetLower()), - Cos(a.GetUpper()) - ); - } - - #endregion - - #region SinCos - - [MethodImpl(256 | 512)] - public static (Vector64 sin, Vector64 cos) SinCos(Vector64 a) - { - if (Vector128.IsHardwareAccelerated) - { - var r = simd_math.SinCos(Vector128.Create(a, a)); - return (r.GetLower(), r.GetUpper()); - } - if (Vector64.IsHardwareAccelerated) - { - return (Sin(a), Cos(a)); - } - var v0 = a.GetElement(0).sincos(); - var v1 = a.GetElement(1).sincos(); - return (Vector64.Create(v0.sin, v1.sin), Vector64.Create(v0.cos, v1.cos)); - } - - [MethodImpl(256 | 512)] - public static (Vector128 sin, Vector128 cos) SinCos(Vector128 a) - { - if (Vector256.IsHardwareAccelerated) - { - var r = simd_math.SinCos(Vector256.Create(a, a)); - return (r.GetLower(), r.GetUpper()); - } - if (Vector128.IsHardwareAccelerated) - { - return (Sin(a), Cos(a)); - } - var v0 = SinCos(a.GetLower()); - var v1 = SinCos(a.GetUpper()); - return (Vector128.Create(v0.sin, v1.sin), Vector128.Create(v0.cos, v1.cos)); - } - - [MethodImpl(256 | 512)] - public static (Vector256 sin, Vector256 cos) SinCos(Vector256 a) - { - if (Vector512.IsHardwareAccelerated) - { - var r = simd_math.SinCos(Vector512.Create(a, a)); - return (r.GetLower(), r.GetUpper()); - } - if (Vector256.IsHardwareAccelerated) - { - return (Sin(a), Cos(a)); - } - var v0 = SinCos(a.GetLower()); - var v1 = SinCos(a.GetUpper()); - return (Vector256.Create(v0.sin, v1.sin), Vector256.Create(v0.cos, v1.cos)); - } - - [MethodImpl(256 | 512)] - public static (Vector512 sin, Vector512 cos) SinCos(Vector512 a) - { - if (Vector512.IsHardwareAccelerated) - { - return (Sin(a), Cos(a)); - } - var v0 = SinCos(a.GetLower()); - var v1 = SinCos(a.GetUpper()); - return (Vector512.Create(v0.sin, v1.sin), Vector512.Create(v0.cos, v1.cos)); - } - - [MethodImpl(256 | 512)] - public static (Vector128 sin, Vector128 cos) SinCos(Vector128 a) - { - if (Vector256.IsHardwareAccelerated) - { - var r = simd_math.SinCos(Vector256.Create(a, a)); - return (r.GetLower(), r.GetUpper()); - } - if (Vector128.IsHardwareAccelerated) - { - return (Sin(a), Cos(a)); - } - var v0 = a.GetElement(0).sincos(); - var v1 = a.GetElement(1).sincos(); - return (Vector128.Create(v0.sin, v1.sin), Vector128.Create(v0.cos, v1.cos)); - } - - [MethodImpl(256 | 512)] - public static (Vector256 sin, Vector256 cos) SinCos(Vector256 a) - { - if (Vector512.IsHardwareAccelerated) - { - var r = simd_math.SinCos(Vector512.Create(a, a)); - return (r.GetLower(), r.GetUpper()); - } - if (Vector256.IsHardwareAccelerated) - { - return (Sin(a), Cos(a)); - } - var v0 = SinCos(a.GetLower()); - var v1 = SinCos(a.GetUpper()); - return (Vector256.Create(v0.sin, v1.sin), Vector256.Create(v0.cos, v1.cos)); - } - - [MethodImpl(256 | 512)] - public static (Vector512 sin, Vector512 cos) SinCos(Vector512 a) - { - if (Vector512.IsHardwareAccelerated) - { - return (Sin(a), Cos(a)); - } - var v0 = SinCos(a.GetLower()); - var v1 = SinCos(a.GetUpper()); - return (Vector512.Create(v0.sin, v1.sin), Vector512.Create(v0.cos, v1.cos)); - } - - #endregion - #region Tan [MethodImpl(256 | 512)] diff --git a/Coplt.Mathematics/simd/simd.math.tri.double.cs b/Coplt.Mathematics/simd/simd.math.tri.double.cs index c29a365..3c2fb71 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.double.cs +++ b/Coplt.Mathematics/simd/simd.math.tri.double.cs @@ -4,153 +4,6 @@ namespace Coplt.Mathematics.Simd; public static partial class simd_math { - #region Sin Cos - - #region SinCos - - [MethodImpl(256 | 512)] - public static Vector128 SinCos(Vector128 x) => Sin(x + Vector128.Create(0.0, math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static Vector256SinCos(Vector256 x) => Sin(x + Vector256.Create(0.0, 0.0, math.D_Half_PI, math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static Vector512 SinCos(Vector512 x) => - Sin(x + Vector512.Create(0.0, 0.0, 0.0, 0.0, math.D_Half_PI, math.D_Half_PI, math.D_Half_PI, math.D_Half_PI)); - - #endregion - - #region Vector128 - - [MethodImpl(256 | 512)] - public static Vector128 Cos(Vector128 x) => Sin(x + Vector128.Create(math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static Vector128 Sin(Vector128 x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = Vector128.GreaterThan(xt, Vector128.Create(math.D_PI)); - xt -= is_neg & Vector128.Create(math.D_PI); - - is_neg &= Vector128.Create(-2.0); - is_neg += Vector128.One; - - var is_nan = simd.Ne(x, x); - is_nan += Vector128.GreaterThan(x, Vector128.Create(f64.MaxValue)); - is_nan += Vector128.LessThan(x, Vector128.Create(f64.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = Vector128.Create(math.D_Half_PI) - Vector128.Abs(xt - Vector128.Create(math.D_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, Vector128.Create(-0.0000000000007384998082865), Vector128.Create(0.000000000160490521296459)); - r = simd.Fma(r, sq, Vector128.Create(-0.00000002505191090496049)); - r = simd.Fma(r, sq, Vector128.Create(0.00000275573170815073144)); - r = simd.Fma(r, sq, Vector128.Create(-0.00019841269828860068271)); - r = simd.Fma(r, sq, Vector128.Create(0.008333333333299304989001)); - r = simd.Fma(r, sq, Vector128.Create(-0.166666666666663509013977)); - r = simd.Fma(r, sq, Vector128.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - - #region Vector256 - - [MethodImpl(256 | 512)] - public static Vector256 Cos(Vector256 x) => Sin(x + Vector256.Create(math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static Vector256 Sin(Vector256 x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = Vector256.GreaterThan(xt, Vector256.Create(math.D_PI)); - xt -= is_neg & Vector256.Create(math.D_PI); - - is_neg &= Vector256.Create(-2.0); - is_neg += Vector256.One; - - var is_nan = simd.Ne(x, x); - is_nan += Vector256.GreaterThan(x, Vector256.Create(f64.MaxValue)); - is_nan += Vector256.LessThan(x, Vector256.Create(f64.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = Vector256.Create(math.D_Half_PI) - Vector256.Abs(xt - Vector256.Create(math.D_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, Vector256.Create(-0.0000000000007384998082865), Vector256.Create(0.000000000160490521296459)); - r = simd.Fma(r, sq, Vector256.Create(-0.00000002505191090496049)); - r = simd.Fma(r, sq, Vector256.Create(0.00000275573170815073144)); - r = simd.Fma(r, sq, Vector256.Create(-0.00019841269828860068271)); - r = simd.Fma(r, sq, Vector256.Create(0.008333333333299304989001)); - r = simd.Fma(r, sq, Vector256.Create(-0.166666666666663509013977)); - r = simd.Fma(r, sq, Vector256.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - - #region Vector512 - - [MethodImpl(256 | 512)] - public static Vector512 Cos(Vector512 x) => Sin(x + Vector512.Create(math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static Vector512 Sin(Vector512 x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = Vector512.GreaterThan(xt, Vector512.Create(math.D_PI)); - xt -= is_neg & Vector512.Create(math.D_PI); - - is_neg &= Vector512.Create(-2.0); - is_neg += Vector512.One; - - var is_nan = simd.Ne(x, x); - is_nan += Vector512.GreaterThan(x, Vector512.Create(f64.MaxValue)); - is_nan += Vector512.LessThan(x, Vector512.Create(f64.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = Vector512.Create(math.D_Half_PI) - Vector512.Abs(xt - Vector512.Create(math.D_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, Vector512.Create(-0.0000000000007384998082865), Vector512.Create(0.000000000160490521296459)); - r = simd.Fma(r, sq, Vector512.Create(-0.00000002505191090496049)); - r = simd.Fma(r, sq, Vector512.Create(0.00000275573170815073144)); - r = simd.Fma(r, sq, Vector512.Create(-0.00019841269828860068271)); - r = simd.Fma(r, sq, Vector512.Create(0.008333333333299304989001)); - r = simd.Fma(r, sq, Vector512.Create(-0.166666666666663509013977)); - r = simd.Fma(r, sq, Vector512.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - - #endregion - #region Tan #region Vector128 diff --git a/Coplt.Mathematics/simd/simd.math.tri.double.tt b/Coplt.Mathematics/simd/simd.math.tri.double.tt index 82c7de5..1935def 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.double.tt +++ b/Coplt.Mathematics/simd/simd.math.tri.double.tt @@ -20,76 +20,6 @@ namespace Coplt.Mathematics.Simd; public static partial class simd_math { - #region Sin Cos - - #region SinCos - - [MethodImpl(256 | 512)] - public static <#= vt128 #> SinCos(<#= vt128 #> x) => Sin(x + <#= v128 #>.Create(0.0, math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static <#= vt256 #>SinCos(<#= vt256 #> x) => Sin(x + <#= v256 #>.Create(0.0, 0.0, math.D_Half_PI, math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static <#= vt512 #> SinCos(<#= vt512 #> x) => - Sin(x + <#= v512 #>.Create(0.0, 0.0, 0.0, 0.0, math.D_Half_PI, math.D_Half_PI, math.D_Half_PI, math.D_Half_PI)); - - #endregion - -<# - foreach (var size in sizes) - { - var vector = $"Vector{size}"; - var vt = $"{vector}<{type}>"; -#> - #region <#= vt #> - - [MethodImpl(256 | 512)] - public static <#= vt #> Cos(<#= vt #> x) => Sin(x + <#= vector #>.Create(math.D_Half_PI)); - - [MethodImpl(256 | 512)] - public static <#= vt #> Sin(<#= vt #> x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = <#= vector #>.GreaterThan(xt, <#= vector #>.Create(math.D_PI)); - xt -= is_neg & <#= vector #>.Create(math.D_PI); - - is_neg &= <#= vector #>.Create(-2.0); - is_neg += <#= vt #>.One; - - var is_nan = simd.Ne(x, x); - is_nan += <#= vector #>.GreaterThan(x, <#= vector #>.Create(f64.MaxValue)); - is_nan += <#= vector #>.LessThan(x, <#= vector #>.Create(f64.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = <#= vector #>.Create(math.D_Half_PI) - <#= vector #>.Abs(xt - <#= vector #>.Create(math.D_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, <#= vector #>.Create(-0.0000000000007384998082865), <#= vector #>.Create(0.000000000160490521296459)); - r = simd.Fma(r, sq, <#= vector #>.Create(-0.00000002505191090496049)); - r = simd.Fma(r, sq, <#= vector #>.Create(0.00000275573170815073144)); - r = simd.Fma(r, sq, <#= vector #>.Create(-0.00019841269828860068271)); - r = simd.Fma(r, sq, <#= vector #>.Create(0.008333333333299304989001)); - r = simd.Fma(r, sq, <#= vector #>.Create(-0.166666666666663509013977)); - r = simd.Fma(r, sq, <#= vt #>.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - -<# - } -#> - #endregion - #region Tan <# diff --git a/Coplt.Mathematics/simd/simd.math.tri.float.cs b/Coplt.Mathematics/simd/simd.math.tri.float.cs index 76bc7b5..1d7cce8 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.float.cs +++ b/Coplt.Mathematics/simd/simd.math.tri.float.cs @@ -4,215 +4,6 @@ namespace Coplt.Mathematics.Simd; public static partial class simd_math { - #region Sin Cos - - #region SinCos - - [MethodImpl(512)] - public static Vector64 SinCos(Vector64 x) => Sin_impl(x + Vector64.Create(0.0f, math.F_Half_PI)); - - [MethodImpl(512)] - public static Vector128 SinCos(Vector128 x) => Sin_impl(x + Vector128.Create(0.0f, 0.0f, math.F_Half_PI, math.F_Half_PI)); - - [MethodImpl(512)] - public static Vector256 SinCos(Vector256 x) => - Sin_impl(x + Vector256.Create(0.0f, 0.0f, 0.0f, 0.0f, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI)); - - [MethodImpl(512)] - public static Vector512 SinCos(Vector512 x) => - Sin_impl(x + Vector512.Create( - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI - )); - - #endregion - - #region Vector64 - - [MethodImpl(512)] - public static Vector64 Cos(Vector64 x) => Sin_impl(x + Vector64.Create(math.F_Half_PI)); - - [MethodImpl(512)] - public static Vector64 Sin(Vector64 x) => Sin_impl(x); - - [MethodImpl(256 | 512)] - private static Vector64 Sin_impl(Vector64 x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = Vector64.GreaterThan(xt, Vector64.Create(math.F_PI)); - xt -= is_neg & Vector64.Create(math.F_PI); - - is_neg &= Vector64.Create(-2.0f); - is_neg += Vector64.One; - - var is_nan = simd.Ne(x, x); - is_nan += Vector64.GreaterThan(x, Vector64.Create(f32.MaxValue)); - is_nan += Vector64.LessThan(x, Vector64.Create(f32.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = Vector64.Create(math.F_Half_PI) - Vector64.Abs(xt - Vector64.Create(math.F_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, Vector64.Create(-0.0000000000007384998082865f), Vector64.Create(0.000000000160490521296459f)); - r = simd.Fma(r, sq, Vector64.Create(-0.00000002505191090496049f)); - r = simd.Fma(r, sq, Vector64.Create(0.00000275573170815073144f)); - r = simd.Fma(r, sq, Vector64.Create(-0.00019841269828860068271f)); - r = simd.Fma(r, sq, Vector64.Create(0.008333333333299304989001f)); - r = simd.Fma(r, sq, Vector64.Create(-0.166666666666663509013977f)); - r = simd.Fma(r, sq, Vector64.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - - #region Vector128 - - [MethodImpl(512)] - public static Vector128 Cos(Vector128 x) => Sin_impl(x + Vector128.Create(math.F_Half_PI)); - - [MethodImpl(512)] - public static Vector128 Sin(Vector128 x) => Sin_impl(x); - - [MethodImpl(256 | 512)] - private static Vector128 Sin_impl(Vector128 x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = Vector128.GreaterThan(xt, Vector128.Create(math.F_PI)); - xt -= is_neg & Vector128.Create(math.F_PI); - - is_neg &= Vector128.Create(-2.0f); - is_neg += Vector128.One; - - var is_nan = simd.Ne(x, x); - is_nan += Vector128.GreaterThan(x, Vector128.Create(f32.MaxValue)); - is_nan += Vector128.LessThan(x, Vector128.Create(f32.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = Vector128.Create(math.F_Half_PI) - Vector128.Abs(xt - Vector128.Create(math.F_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, Vector128.Create(-0.0000000000007384998082865f), Vector128.Create(0.000000000160490521296459f)); - r = simd.Fma(r, sq, Vector128.Create(-0.00000002505191090496049f)); - r = simd.Fma(r, sq, Vector128.Create(0.00000275573170815073144f)); - r = simd.Fma(r, sq, Vector128.Create(-0.00019841269828860068271f)); - r = simd.Fma(r, sq, Vector128.Create(0.008333333333299304989001f)); - r = simd.Fma(r, sq, Vector128.Create(-0.166666666666663509013977f)); - r = simd.Fma(r, sq, Vector128.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - - #region Vector256 - - [MethodImpl(512)] - public static Vector256 Cos(Vector256 x) => Sin_impl(x + Vector256.Create(math.F_Half_PI)); - - [MethodImpl(512)] - public static Vector256 Sin(Vector256 x) => Sin_impl(x); - - [MethodImpl(256 | 512)] - private static Vector256 Sin_impl(Vector256 x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = Vector256.GreaterThan(xt, Vector256.Create(math.F_PI)); - xt -= is_neg & Vector256.Create(math.F_PI); - - is_neg &= Vector256.Create(-2.0f); - is_neg += Vector256.One; - - var is_nan = simd.Ne(x, x); - is_nan += Vector256.GreaterThan(x, Vector256.Create(f32.MaxValue)); - is_nan += Vector256.LessThan(x, Vector256.Create(f32.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = Vector256.Create(math.F_Half_PI) - Vector256.Abs(xt - Vector256.Create(math.F_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, Vector256.Create(-0.0000000000007384998082865f), Vector256.Create(0.000000000160490521296459f)); - r = simd.Fma(r, sq, Vector256.Create(-0.00000002505191090496049f)); - r = simd.Fma(r, sq, Vector256.Create(0.00000275573170815073144f)); - r = simd.Fma(r, sq, Vector256.Create(-0.00019841269828860068271f)); - r = simd.Fma(r, sq, Vector256.Create(0.008333333333299304989001f)); - r = simd.Fma(r, sq, Vector256.Create(-0.166666666666663509013977f)); - r = simd.Fma(r, sq, Vector256.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - - #region Vector512 - - [MethodImpl(512)] - public static Vector512 Cos(Vector512 x) => Sin_impl(x + Vector512.Create(math.F_Half_PI)); - - [MethodImpl(512)] - public static Vector512 Sin(Vector512 x) => Sin_impl(x); - - [MethodImpl(256 | 512)] - private static Vector512 Sin_impl(Vector512 x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = Vector512.GreaterThan(xt, Vector512.Create(math.F_PI)); - xt -= is_neg & Vector512.Create(math.F_PI); - - is_neg &= Vector512.Create(-2.0f); - is_neg += Vector512.One; - - var is_nan = simd.Ne(x, x); - is_nan += Vector512.GreaterThan(x, Vector512.Create(f32.MaxValue)); - is_nan += Vector512.LessThan(x, Vector512.Create(f32.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = Vector512.Create(math.F_Half_PI) - Vector512.Abs(xt - Vector512.Create(math.F_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, Vector512.Create(-0.0000000000007384998082865f), Vector512.Create(0.000000000160490521296459f)); - r = simd.Fma(r, sq, Vector512.Create(-0.00000002505191090496049f)); - r = simd.Fma(r, sq, Vector512.Create(0.00000275573170815073144f)); - r = simd.Fma(r, sq, Vector512.Create(-0.00019841269828860068271f)); - r = simd.Fma(r, sq, Vector512.Create(0.008333333333299304989001f)); - r = simd.Fma(r, sq, Vector512.Create(-0.166666666666663509013977f)); - r = simd.Fma(r, sq, Vector512.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - - #endregion - #region Tan #region Vector64 diff --git a/Coplt.Mathematics/simd/simd.math.tri.float.tt b/Coplt.Mathematics/simd/simd.math.tri.float.tt index c59522a..c9c2b40 100644 --- a/Coplt.Mathematics/simd/simd.math.tri.float.tt +++ b/Coplt.Mathematics/simd/simd.math.tri.float.tt @@ -22,86 +22,6 @@ namespace Coplt.Mathematics.Simd; public static partial class simd_math { - #region Sin Cos - - #region SinCos - - [MethodImpl(512)] - public static <#= vt64 #> SinCos(<#= vt64 #> x) => Sin_impl(x + <#= v64 #>.Create(0.0f, math.F_Half_PI)); - - [MethodImpl(512)] - public static <#= vt128 #> SinCos(<#= vt128 #> x) => Sin_impl(x + <#= v128 #>.Create(0.0f, 0.0f, math.F_Half_PI, math.F_Half_PI)); - - [MethodImpl(512)] - public static <#= vt256 #> SinCos(<#= vt256 #> x) => - Sin_impl(x + <#= v256 #>.Create(0.0f, 0.0f, 0.0f, 0.0f, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI)); - - [MethodImpl(512)] - public static <#= vt512 #> SinCos(<#= vt512 #> x) => - Sin_impl(x + <#= v512 #>.Create( - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI, math.F_Half_PI - )); - - #endregion - -<# - foreach (var size in sizes) - { - var vector = $"Vector{size}"; - var vt = $"{vector}<{type}>"; -#> - #region <#= vt #> - - [MethodImpl(512)] - public static <#= vt #> Cos(<#= vt #> x) => Sin_impl(x + <#= vector #>.Create(math.F_Half_PI)); - - [MethodImpl(512)] - public static <#= vt #> Sin(<#= vt #> x) => Sin_impl(x); - - [MethodImpl(256 | 512)] - private static <#= vt #> Sin_impl(<#= vt #> x) - { - // Since sin() is periodic around 2pi, this converts x into the range of [0, 2pi] - var xt = Wrap0To2Pi(x); - - // Since sin() in [0, 2pi] is an odd function around pi, this converts the range to [0, pi], then stores whether or not the result needs to be negated in is_neg. - var is_neg = <#= vector #>.GreaterThan(xt, <#= vector #>.Create(math.F_PI)); - xt -= is_neg & <#= vector #>.Create(math.F_PI); - - is_neg &= <#= vector #>.Create(-2.0f); - is_neg += <#= vt #>.One; - - var is_nan = simd.Ne(x, x); - is_nan += <#= vector #>.GreaterThan(x, <#= vector #>.Create(f32.MaxValue)); - is_nan += <#= vector #>.LessThan(x, <#= vector #>.Create(f32.MinValue)); - - // Since sin() on [0, pi] is an even function around pi/2, this "folds" the range into [0, pi/2]. I.e. 3pi/5 becomes 2pi/5. - xt = <#= vector #>.Create(math.F_Half_PI) - <#= vector #>.Abs(xt - <#= vector #>.Create(math.F_Half_PI)); - - var sq = xt * xt; - var r = simd.Fma(sq, <#= vector #>.Create(-0.0000000000007384998082865f), <#= vector #>.Create(0.000000000160490521296459f)); - r = simd.Fma(r, sq, <#= vector #>.Create(-0.00000002505191090496049f)); - r = simd.Fma(r, sq, <#= vector #>.Create(0.00000275573170815073144f)); - r = simd.Fma(r, sq, <#= vector #>.Create(-0.00019841269828860068271f)); - r = simd.Fma(r, sq, <#= vector #>.Create(0.008333333333299304989001f)); - r = simd.Fma(r, sq, <#= vector #>.Create(-0.166666666666663509013977f)); - r = simd.Fma(r, sq, <#= vt #>.One); - - r *= xt; - - r = simd.Fma(r, is_neg, is_nan); - - return r; - } - - #endregion - -<# - } -#> - #endregion - #region Tan <# diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs index 9b8add8..6c89ef7 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs @@ -171,7 +171,7 @@ public static float2 faceForward([This] float2 n, float2 i, float2 ng) => public static float2 sin([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.Sin(a.vector)); + return new(Vector64.Sin(a.vector)); return new(a.x.sin(), a.y.sin()); } @@ -179,7 +179,7 @@ public static float2 sin([This] float2 a) public static float2 cos([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.Cos(a.vector)); + return new(Vector64.Cos(a.vector)); return new(a.x.cos(), a.y.cos()); } @@ -188,7 +188,7 @@ public static (float2 sin, float2 cos) sincos([This] float2 a) { if (Vector64.IsHardwareAccelerated) { - var (sin, cos) = simd.SinCos(a.vector); + var (sin, cos) = Vector64.SinCos(a.vector); return (new(sin), new(cos)); } a.x.sincos(out var sin0, out var cos0); @@ -204,7 +204,7 @@ public static void sincos([This] float2 a, out float2 sin, out float2 cos) { if (Vector64.IsHardwareAccelerated) { - (sin.vector, cos.vector) = simd.SinCos(a.vector); + (sin.vector, cos.vector) = Vector64.SinCos(a.vector); return; } a.x.sincos(out var sin0, out var cos0); @@ -480,7 +480,7 @@ public static float3 faceForward([This] float3 n, float3 i, float3 ng) => public static float3 sin([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Sin(a.vector)); + return new(Vector128.Sin(a.vector)); return new(a.x.sin(), a.y.sin(), a.z.sin()); } @@ -488,7 +488,7 @@ public static float3 sin([This] float3 a) public static float3 cos([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Cos(a.vector)); + return new(Vector128.Cos(a.vector)); return new(a.x.cos(), a.y.cos(), a.z.cos()); } @@ -497,7 +497,7 @@ public static (float3 sin, float3 cos) sincos([This] float3 a) { if (Vector128.IsHardwareAccelerated) { - var (sin, cos) = simd.SinCos(a.vector); + var (sin, cos) = Vector128.SinCos(a.vector); return (new(sin), new(cos)); } a.x.sincos(out var sin0, out var cos0); @@ -514,7 +514,7 @@ public static void sincos([This] float3 a, out float3 sin, out float3 cos) { if (Vector128.IsHardwareAccelerated) { - (sin.vector, cos.vector) = simd.SinCos(a.vector); + (sin.vector, cos.vector) = Vector128.SinCos(a.vector); return; } a.x.sincos(out var sin0, out var cos0); @@ -791,7 +791,7 @@ public static float4 faceForward([This] float4 n, float4 i, float4 ng) => public static float4 sin([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Sin(a.vector)); + return new(Vector128.Sin(a.vector)); return new(a.x.sin(), a.y.sin(), a.z.sin(), a.w.sin()); } @@ -799,7 +799,7 @@ public static float4 sin([This] float4 a) public static float4 cos([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Cos(a.vector)); + return new(Vector128.Cos(a.vector)); return new(a.x.cos(), a.y.cos(), a.z.cos(), a.w.cos()); } @@ -808,7 +808,7 @@ public static (float4 sin, float4 cos) sincos([This] float4 a) { if (Vector128.IsHardwareAccelerated) { - var (sin, cos) = simd.SinCos(a.vector); + var (sin, cos) = Vector128.SinCos(a.vector); return (new(sin), new(cos)); } a.x.sincos(out var sin0, out var cos0); @@ -826,7 +826,7 @@ public static void sincos([This] float4 a, out float4 sin, out float4 cos) { if (Vector128.IsHardwareAccelerated) { - (sin.vector, cos.vector) = simd.SinCos(a.vector); + (sin.vector, cos.vector) = Vector128.SinCos(a.vector); return; } a.x.sincos(out var sin0, out var cos0); @@ -1104,7 +1104,7 @@ public static double2 faceForward([This] double2 n, double2 i, double2 ng) => public static double2 sin([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Sin(a.vector)); + return new(Vector128.Sin(a.vector)); return new(a.x.sin(), a.y.sin()); } @@ -1112,7 +1112,7 @@ public static double2 sin([This] double2 a) public static double2 cos([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Cos(a.vector)); + return new(Vector128.Cos(a.vector)); return new(a.x.cos(), a.y.cos()); } @@ -1121,7 +1121,7 @@ public static (double2 sin, double2 cos) sincos([This] double2 a) { if (Vector128.IsHardwareAccelerated) { - var (sin, cos) = simd.SinCos(a.vector); + var (sin, cos) = Vector128.SinCos(a.vector); return (new(sin), new(cos)); } a.x.sincos(out var sin0, out var cos0); @@ -1137,7 +1137,7 @@ public static void sincos([This] double2 a, out double2 sin, out double2 cos) { if (Vector128.IsHardwareAccelerated) { - (sin.vector, cos.vector) = simd.SinCos(a.vector); + (sin.vector, cos.vector) = Vector128.SinCos(a.vector); return; } a.x.sincos(out var sin0, out var cos0); @@ -1413,7 +1413,7 @@ public static double3 faceForward([This] double3 n, double3 i, double3 ng) => public static double3 sin([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Sin(a.vector)); + return new(Vector256.Sin(a.vector)); return new(a.x.sin(), a.y.sin(), a.z.sin()); } @@ -1421,7 +1421,7 @@ public static double3 sin([This] double3 a) public static double3 cos([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Cos(a.vector)); + return new(Vector256.Cos(a.vector)); return new(a.x.cos(), a.y.cos(), a.z.cos()); } @@ -1430,7 +1430,7 @@ public static (double3 sin, double3 cos) sincos([This] double3 a) { if (Vector256.IsHardwareAccelerated) { - var (sin, cos) = simd.SinCos(a.vector); + var (sin, cos) = Vector256.SinCos(a.vector); return (new(sin), new(cos)); } a.x.sincos(out var sin0, out var cos0); @@ -1447,7 +1447,7 @@ public static void sincos([This] double3 a, out double3 sin, out double3 cos) { if (Vector256.IsHardwareAccelerated) { - (sin.vector, cos.vector) = simd.SinCos(a.vector); + (sin.vector, cos.vector) = Vector256.SinCos(a.vector); return; } a.x.sincos(out var sin0, out var cos0); @@ -1724,7 +1724,7 @@ public static double4 faceForward([This] double4 n, double4 i, double4 ng) => public static double4 sin([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Sin(a.vector)); + return new(Vector256.Sin(a.vector)); return new(a.x.sin(), a.y.sin(), a.z.sin(), a.w.sin()); } @@ -1732,7 +1732,7 @@ public static double4 sin([This] double4 a) public static double4 cos([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Cos(a.vector)); + return new(Vector256.Cos(a.vector)); return new(a.x.cos(), a.y.cos(), a.z.cos(), a.w.cos()); } @@ -1741,7 +1741,7 @@ public static (double4 sin, double4 cos) sincos([This] double4 a) { if (Vector256.IsHardwareAccelerated) { - var (sin, cos) = simd.SinCos(a.vector); + var (sin, cos) = Vector256.SinCos(a.vector); return (new(sin), new(cos)); } a.x.sincos(out var sin0, out var cos0); @@ -1759,7 +1759,7 @@ public static void sincos([This] double4 a, out double4 sin, out double4 cos) { if (Vector256.IsHardwareAccelerated) { - (sin.vector, cos.vector) = simd.SinCos(a.vector); + (sin.vector, cos.vector) = Vector256.SinCos(a.vector); return; } a.x.sincos(out var sin0, out var cos0); diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt index d04db1c..eb323d6 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt @@ -303,7 +303,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Sin(a.vector)); + return new(Vector<#= bitSize #>.Sin(a.vector)); <# } #> @@ -318,7 +318,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Cos(a.vector)); + return new(Vector<#= bitSize #>.Cos(a.vector)); <# } #> @@ -334,7 +334,7 @@ public static partial class math #> if (Vector<#= bitSize #>.IsHardwareAccelerated) { - var (sin, cos) = simd.SinCos(a.vector); + var (sin, cos) = Vector<#= bitSize #>.SinCos(a.vector); return (new(sin), new(cos)); } <# @@ -357,7 +357,7 @@ public static partial class math #> if (Vector<#= bitSize #>.IsHardwareAccelerated) { - (sin.vector, cos.vector) = simd.SinCos(a.vector); + (sin.vector, cos.vector) = Vector<#= bitSize #>.SinCos(a.vector); return; } <# diff --git a/Tests/Functions/Cos.cs b/Tests/Functions/Cos.cs new file mode 100644 index 0000000..f4454ef --- /dev/null +++ b/Tests/Functions/Cos.cs @@ -0,0 +1,28 @@ +using System.Runtime.Intrinsics; +using Coplt.Mathematics; +using Coplt.Mathematics.Simd; + +namespace Tests.Functions; + +public class TestCos +{ + [Test] + public void TestFloat4([Random(-10f, 10.0f, 100)] float x) + { + var a = math.cos(new float4(x)); + var b = MathF.Cos(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } + + [Test] + public void TestDouble4([Random(-10, 10.0, 100)] double x) + { + var a = math.cos(new double4(x)); + var b = Math.Cos(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } +} diff --git a/Tests/Functions/Sin.cs b/Tests/Functions/Sin.cs new file mode 100644 index 0000000..fa2c290 --- /dev/null +++ b/Tests/Functions/Sin.cs @@ -0,0 +1,28 @@ +using System.Runtime.Intrinsics; +using Coplt.Mathematics; +using Coplt.Mathematics.Simd; + +namespace Tests.Functions; + +public class TestSin +{ + [Test] + public void TestFloat4([Random(-10f, 10.0f, 100)] float x) + { + var a = math.sin(new float4(x)); + var b = MathF.Sin(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } + + [Test] + public void TestDouble4([Random(-10, 10.0, 100)] double x) + { + var a = math.sin(new double4(x)); + var b = Math.Sin(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } +} diff --git a/Tests/TestSinCos.cs b/Tests/TestSinCos.cs deleted file mode 100644 index c9fee86..0000000 --- a/Tests/TestSinCos.cs +++ /dev/null @@ -1,56 +0,0 @@ -// using System.Runtime.Intrinsics; -// using Coplt.Mathematics; -// -// #if NET8_0_OR_GREATER -// using Coplt.Mathematics.Simd; -// namespace Tests; -// -// [Parallelizable] -// public class TestSinCos -// { -// [Test] -// [Parallelizable] -// public void FloatTestSin([Random(-10f, 10.0f, 100)] float x) -// { -// var a = simd.Sin(new float4(x).UnsafeGetInner()).GetElement(0); -// var b = MathF.Sin(x); -// Console.WriteLine($"{a}"); -// Console.WriteLine($"{b}"); -// Assert.That(b, Is.EqualTo(a).Within(5000).Ulps); -// } -// -// [Test] -// [Parallelizable] -// public void DoubleTestSin([Random(-10, 100.0, 100)] double x) -// { -// var a = simd.Sin(new double4(x).UnsafeGetInner()).GetElement(0); -// var b = Math.Sin(x); -// Console.WriteLine($"{a}"); -// Console.WriteLine($"{b}"); -// Assert.That(b, Is.EqualTo(a).Within(5000).Ulps); -// } -// -// [Test] -// [Parallelizable] -// public void FloatTestCos([Random(-10f, 10.0f, 100)] float x) -// { -// var a = simd.Cos(new float4(x).UnsafeGetInner()).GetElement(0); -// var b = MathF.Cos(x); -// Console.WriteLine($"{a}"); -// Console.WriteLine($"{b}"); -// Assert.That(b, Is.EqualTo(a).Within(5000).Ulps); -// } -// -// [Test] -// [Parallelizable] -// public void DoubleTestCos([Random(-10, 100.0, 100)] double x) -// { -// var a = simd.Cos(new double4(x).UnsafeGetInner()).GetElement(0); -// var b = Math.Cos(x); -// Console.WriteLine($"{a}"); -// Console.WriteLine($"{b}"); -// Assert.That(b, Is.EqualTo(a).Within(5000).Ulps); -// } -// } -// -// #endif From b7c72a4f5e96162e7f3b935fd8c0f9463852164c Mon Sep 17 00:00:00 2001 From: U2A5F Date: Thu, 9 Jul 2026 15:41:37 +0800 Subject: [PATCH 5/5] Log Log2 Exp --- .../vec/arith/vec.arith.float.bin.cs | 60 ++++++++-------- .../vec/arith/vec.arith.float.bin.tt | 12 ++-- README.md | 12 ---- Tests/Functions/Cos.cs | 4 +- Tests/Functions/Exp.cs | 29 ++++++++ Tests/Functions/Log.cs | 69 +++++++++++++++++++ Tests/Functions/Sin.cs | 4 +- 7 files changed, 138 insertions(+), 52 deletions(-) create mode 100644 Tests/Functions/Exp.cs create mode 100644 Tests/Functions/Log.cs diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs index 6c89ef7..8522257 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.cs @@ -44,7 +44,7 @@ public static b32v2 isNegInf([This] float2 a) public static float2 log([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.Log(a.vector)); + return new(Vector64.Log(a.vector)); return new(a.x.log(), a.y.log()); } @@ -52,7 +52,7 @@ public static float2 log([This] float2 a) public static float2 log2([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.Log2(a.vector)); + return new(Vector64.Log2(a.vector)); return new(a.x.log2(), a.y.log2()); } @@ -60,7 +60,7 @@ public static float2 log2([This] float2 a) public static float2 log([This] float2 a, float2 b) { if (Vector64.IsHardwareAccelerated) - return new(simd.Log(a.vector) / simd.Log(b.vector)); + return new(Vector64.Log(a.vector) / Vector64.Log(b.vector)); return new(a.x.log(b.x), a.y.log(b.y)); } @@ -68,7 +68,7 @@ public static float2 log([This] float2 a, float2 b) public static float2 log10([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.Log10(a.vector)); + return log2(a) * (0.6931471805599453094172321214581765680755001343602552541206800094f / 2.3025850929940456840179914546843642076011014886287729760333279009f); return new(a.x.log10(), a.y.log10()); } @@ -76,7 +76,7 @@ public static float2 log10([This] float2 a) public static float2 exp([This] float2 a) { if (Vector64.IsHardwareAccelerated) - return new(simd.Exp(a.vector)); + return new(Vector64.Exp(a.vector)); return new(a.x.exp(), a.y.exp()); } @@ -353,7 +353,7 @@ public static b32v3 isNegInf([This] float3 a) public static float3 log([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log(a.vector)); + return new(Vector128.Log(a.vector)); return new(a.x.log(), a.y.log(), a.z.log()); } @@ -361,7 +361,7 @@ public static float3 log([This] float3 a) public static float3 log2([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log2(a.vector)); + return new(Vector128.Log2(a.vector)); return new(a.x.log2(), a.y.log2(), a.z.log2()); } @@ -369,7 +369,7 @@ public static float3 log2([This] float3 a) public static float3 log([This] float3 a, float3 b) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log(a.vector) / simd.Log(b.vector)); + return new(Vector128.Log(a.vector) / Vector128.Log(b.vector)); return new(a.x.log(b.x), a.y.log(b.y), a.z.log(b.z)); } @@ -377,7 +377,7 @@ public static float3 log([This] float3 a, float3 b) public static float3 log10([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log10(a.vector)); + return log2(a) * (0.6931471805599453094172321214581765680755001343602552541206800094f / 2.3025850929940456840179914546843642076011014886287729760333279009f); return new(a.x.log10(), a.y.log10(), a.z.log10()); } @@ -385,7 +385,7 @@ public static float3 log10([This] float3 a) public static float3 exp([This] float3 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Exp(a.vector)); + return new(Vector128.Exp(a.vector)); return new(a.x.exp(), a.y.exp(), a.z.exp()); } @@ -664,7 +664,7 @@ public static b32v4 isNegInf([This] float4 a) public static float4 log([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log(a.vector)); + return new(Vector128.Log(a.vector)); return new(a.x.log(), a.y.log(), a.z.log(), a.w.log()); } @@ -672,7 +672,7 @@ public static float4 log([This] float4 a) public static float4 log2([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log2(a.vector)); + return new(Vector128.Log2(a.vector)); return new(a.x.log2(), a.y.log2(), a.z.log2(), a.w.log2()); } @@ -680,7 +680,7 @@ public static float4 log2([This] float4 a) public static float4 log([This] float4 a, float4 b) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log(a.vector) / simd.Log(b.vector)); + return new(Vector128.Log(a.vector) / Vector128.Log(b.vector)); return new(a.x.log(b.x), a.y.log(b.y), a.z.log(b.z), a.w.log(b.w)); } @@ -688,7 +688,7 @@ public static float4 log([This] float4 a, float4 b) public static float4 log10([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log10(a.vector)); + return log2(a) * (0.6931471805599453094172321214581765680755001343602552541206800094f / 2.3025850929940456840179914546843642076011014886287729760333279009f); return new(a.x.log10(), a.y.log10(), a.z.log10(), a.w.log10()); } @@ -696,7 +696,7 @@ public static float4 log10([This] float4 a) public static float4 exp([This] float4 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Exp(a.vector)); + return new(Vector128.Exp(a.vector)); return new(a.x.exp(), a.y.exp(), a.z.exp(), a.w.exp()); } @@ -977,7 +977,7 @@ public static b64v2 isNegInf([This] double2 a) public static double2 log([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log(a.vector)); + return new(Vector128.Log(a.vector)); return new(a.x.log(), a.y.log()); } @@ -985,7 +985,7 @@ public static double2 log([This] double2 a) public static double2 log2([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log2(a.vector)); + return new(Vector128.Log2(a.vector)); return new(a.x.log2(), a.y.log2()); } @@ -993,7 +993,7 @@ public static double2 log2([This] double2 a) public static double2 log([This] double2 a, double2 b) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log(a.vector) / simd.Log(b.vector)); + return new(Vector128.Log(a.vector) / Vector128.Log(b.vector)); return new(a.x.log(b.x), a.y.log(b.y)); } @@ -1001,7 +1001,7 @@ public static double2 log([This] double2 a, double2 b) public static double2 log10([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Log10(a.vector)); + return log2(a) * (0.6931471805599453094172321214581765680755001343602552541206800094 / 2.3025850929940456840179914546843642076011014886287729760333279009); return new(a.x.log10(), a.y.log10()); } @@ -1009,7 +1009,7 @@ public static double2 log10([This] double2 a) public static double2 exp([This] double2 a) { if (Vector128.IsHardwareAccelerated) - return new(simd.Exp(a.vector)); + return new(Vector128.Exp(a.vector)); return new(a.x.exp(), a.y.exp()); } @@ -1286,7 +1286,7 @@ public static b64v3 isNegInf([This] double3 a) public static double3 log([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log(a.vector)); + return new(Vector256.Log(a.vector)); return new(a.x.log(), a.y.log(), a.z.log()); } @@ -1294,7 +1294,7 @@ public static double3 log([This] double3 a) public static double3 log2([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log2(a.vector)); + return new(Vector256.Log2(a.vector)); return new(a.x.log2(), a.y.log2(), a.z.log2()); } @@ -1302,7 +1302,7 @@ public static double3 log2([This] double3 a) public static double3 log([This] double3 a, double3 b) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log(a.vector) / simd.Log(b.vector)); + return new(Vector256.Log(a.vector) / Vector256.Log(b.vector)); return new(a.x.log(b.x), a.y.log(b.y), a.z.log(b.z)); } @@ -1310,7 +1310,7 @@ public static double3 log([This] double3 a, double3 b) public static double3 log10([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log10(a.vector)); + return log2(a) * (0.6931471805599453094172321214581765680755001343602552541206800094 / 2.3025850929940456840179914546843642076011014886287729760333279009); return new(a.x.log10(), a.y.log10(), a.z.log10()); } @@ -1318,7 +1318,7 @@ public static double3 log10([This] double3 a) public static double3 exp([This] double3 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Exp(a.vector)); + return new(Vector256.Exp(a.vector)); return new(a.x.exp(), a.y.exp(), a.z.exp()); } @@ -1597,7 +1597,7 @@ public static b64v4 isNegInf([This] double4 a) public static double4 log([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log(a.vector)); + return new(Vector256.Log(a.vector)); return new(a.x.log(), a.y.log(), a.z.log(), a.w.log()); } @@ -1605,7 +1605,7 @@ public static double4 log([This] double4 a) public static double4 log2([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log2(a.vector)); + return new(Vector256.Log2(a.vector)); return new(a.x.log2(), a.y.log2(), a.z.log2(), a.w.log2()); } @@ -1613,7 +1613,7 @@ public static double4 log2([This] double4 a) public static double4 log([This] double4 a, double4 b) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log(a.vector) / simd.Log(b.vector)); + return new(Vector256.Log(a.vector) / Vector256.Log(b.vector)); return new(a.x.log(b.x), a.y.log(b.y), a.z.log(b.z), a.w.log(b.w)); } @@ -1621,7 +1621,7 @@ public static double4 log([This] double4 a, double4 b) public static double4 log10([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Log10(a.vector)); + return log2(a) * (0.6931471805599453094172321214581765680755001343602552541206800094 / 2.3025850929940456840179914546843642076011014886287729760333279009); return new(a.x.log10(), a.y.log10(), a.z.log10(), a.w.log10()); } @@ -1629,7 +1629,7 @@ public static double4 log10([This] double4 a) public static double4 exp([This] double4 a) { if (Vector256.IsHardwareAccelerated) - return new(simd.Exp(a.vector)); + return new(Vector256.Exp(a.vector)); return new(a.x.exp(), a.y.exp(), a.z.exp(), a.w.exp()); } diff --git a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt index eb323d6..e341ac1 100644 --- a/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt +++ b/Coplt.Mathematics/vec/arith/vec.arith.float.bin.tt @@ -90,7 +90,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Log(a.vector)); + return new(Vector<#= bitSize #>.Log(a.vector)); <# } #> @@ -106,7 +106,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Log2(a.vector)); + return new(Vector<#= bitSize #>.Log2(a.vector)); <# } #> @@ -122,7 +122,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Log(a.vector) / simd.Log(b.vector)); + return new(Vector<#= bitSize #>.Log(a.vector) / Vector<#= bitSize #>.Log(b.vector)); <# } #> @@ -138,7 +138,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Log10(a.vector)); + return log2(a) * (0.6931471805599453094172321214581765680755001343602552541206800094<#= typ.suffix #> / 2.3025850929940456840179914546843642076011014886287729760333279009<#= typ.suffix #>); <# } #> @@ -154,7 +154,7 @@ public static partial class math { #> if (Vector<#= bitSize #>.IsHardwareAccelerated) - return new(simd.Exp(a.vector)); + return new(Vector<#= bitSize #>.Exp(a.vector)); <# } #> @@ -538,7 +538,7 @@ public static partial class math public static <#= typeName #> chgsign([This] <#= typeName #> a, <#= typeName #> b) { var sig = new <#= typ.maskType #><#= i #>(<#= - typ.name switch { "half" => "0x8000", "float" => "0x8000_0000", "double" => "0x8000_0000_0000_0000", _ => "" } #>).asf(); + typ.name switch { "half" => "0x8000", "float" => "0x8000_0000", "double" => "0x8000_0000_0000_0000", _ => "" } #>).asf(); return (b & sig) ^ a; } } diff --git a/README.md b/README.md index baa9a67..526e702 100644 --- a/README.md +++ b/README.md @@ -19,18 +19,6 @@ hlsl-style linear algebra library > > 3. Lower precision than C# system library -### Function ULPs (vs C# system library) - -| function | float | double | -|----------|-------|--------| -| log2 | 1 | 1 | -| asin | 2 | 2 | -| acos | 2 | 2 | -| atan | 2 | 2 | -| atan2 | 2 | 2 | - -- The function that needs to be rewritten due to insufficient precision is not in the table - ## Todo - [ ] tests diff --git a/Tests/Functions/Cos.cs b/Tests/Functions/Cos.cs index f4454ef..ce63128 100644 --- a/Tests/Functions/Cos.cs +++ b/Tests/Functions/Cos.cs @@ -6,7 +6,7 @@ namespace Tests.Functions; public class TestCos { - [Test] + [Test, Parallelizable] public void TestFloat4([Random(-10f, 10.0f, 100)] float x) { var a = math.cos(new float4(x)); @@ -16,7 +16,7 @@ public void TestFloat4([Random(-10f, 10.0f, 100)] float x) Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); } - [Test] + [Test, Parallelizable] public void TestDouble4([Random(-10, 10.0, 100)] double x) { var a = math.cos(new double4(x)); diff --git a/Tests/Functions/Exp.cs b/Tests/Functions/Exp.cs new file mode 100644 index 0000000..77484b9 --- /dev/null +++ b/Tests/Functions/Exp.cs @@ -0,0 +1,29 @@ +using System.Runtime.Intrinsics; +using Coplt.Mathematics; +using Coplt.Mathematics.Simd; + +namespace Tests.Functions; + +[Parallelizable] +public class TestExp +{ + [Test, Parallelizable] + public void TestLogFloat4([Random(0.000_1f, 1_000_000.0f, 1000)] float x) + { + var a = math.exp(new float4(x)); + var b = MathF.Exp(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } + + [Test, Parallelizable] + public void TestLogDouble4([Random(0.000_1, 1_000_000.0, 1000)] double x) + { + var a = math.exp(new double4(x)); + var b = Math.Exp(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } +} diff --git a/Tests/Functions/Log.cs b/Tests/Functions/Log.cs new file mode 100644 index 0000000..389f0a7 --- /dev/null +++ b/Tests/Functions/Log.cs @@ -0,0 +1,69 @@ +using System.Runtime.Intrinsics; +using Coplt.Mathematics; +using Coplt.Mathematics.Simd; + +namespace Tests.Functions; + +[Parallelizable] +public class TestLog +{ + [Test, Parallelizable] + public void TestLogFloat4([Random(0.000_1f, 1_000_000.0f, 1000)] float x) + { + var a = math.log(new float4(x)); + var b = MathF.Log(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } + + [Test, Parallelizable] + public void TestLogDouble4([Random(0.000_1, 1_000_000.0, 1000)] double x) + { + var a = math.log(new double4(x)); + var b = Math.Log(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } + + [Test, Parallelizable] + public void TestLog2Float4([Random(0.000_1f, 1_000_000.0f, 1000)] float x) + { + var a = math.log2(new float4(x)); + var b = MathF.Log2(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } + + [Test, Parallelizable] + public void TestLog2Double4([Random(0.000_1, 1_000_000.0, 1000)] double x) + { + var a = math.log2(new double4(x)); + var b = Math.Log2(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); + } + + [Test, Parallelizable] + public void TestLog10Float4([Random(0.000_1f, 1_000_000.0f, 1000)] float x) + { + var a = math.log10(new float4(x)); + var b = MathF.Log10(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(4).Ulps); + } + + [Test, Parallelizable] + public void TestLog10Double4([Random(0.000_1, 1_000_000.0, 1000)] double x) + { + var a = math.log10(new double4(x)); + var b = Math.Log10(x); + Console.WriteLine($"{a}"); + Console.WriteLine($"{b}"); + Assert.That(b, Is.EqualTo(a.x).Within(4).Ulps); + } +} diff --git a/Tests/Functions/Sin.cs b/Tests/Functions/Sin.cs index fa2c290..1c1ca40 100644 --- a/Tests/Functions/Sin.cs +++ b/Tests/Functions/Sin.cs @@ -6,7 +6,7 @@ namespace Tests.Functions; public class TestSin { - [Test] + [Test, Parallelizable] public void TestFloat4([Random(-10f, 10.0f, 100)] float x) { var a = math.sin(new float4(x)); @@ -16,7 +16,7 @@ public void TestFloat4([Random(-10f, 10.0f, 100)] float x) Assert.That(b, Is.EqualTo(a.x).Within(1).Ulps); } - [Test] + [Test, Parallelizable] public void TestDouble4([Random(-10, 10.0, 100)] double x) { var a = math.sin(new double4(x));