From 655d243ce7e69c692ee77b6c5493dff8b97f6b3a Mon Sep 17 00:00:00 2001 From: DMP9 Date: Wed, 27 Nov 2019 18:04:35 +0000 Subject: [PATCH 01/10] D VectorOps --- sources/Directory.Build.props | 1 + sources/MathSharp/MathSharp.csproj | 4 - .../VectorDouble/VectorOperations.cs | 162 ++++++++++++++++-- 3 files changed, 150 insertions(+), 17 deletions(-) diff --git a/sources/Directory.Build.props b/sources/Directory.Build.props index 89031a5..98f11cb 100644 --- a/sources/Directory.Build.props +++ b/sources/Directory.Build.props @@ -13,6 +13,7 @@ $(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props sources + true diff --git a/sources/MathSharp/MathSharp.csproj b/sources/MathSharp/MathSharp.csproj index 24b67f2..c3a41a5 100644 --- a/sources/MathSharp/MathSharp.csproj +++ b/sources/MathSharp/MathSharp.csproj @@ -4,8 +4,4 @@ netcoreapp3.0 false - - - - diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs index f1d56cf..8ee40fc 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs @@ -22,6 +22,9 @@ public static partial class Vector // For anyone looking at codegen, it is actually // [v]cmpps xmm0, xmm0, xmm0, 0x0 // which is functionally identical + /// + /// Gets a new Vector256<double> with all elements initialized to one. + /// public static Vector256 OneDouble { get @@ -31,18 +34,36 @@ public static Vector256 OneDouble } } + /// + /// Gets a new Vector256<double> with all elements initialized to zero. + /// public static Vector256 ZeroDouble => Vector256.Zero; #region Normalize + /// + /// Scales the Vector2D to unit length. + /// + /// The Vector2D to normalize. + /// A normalized vector. [MethodImpl(MaxOpt)] public static Vector256 Normalize2D(Vector256 vector) => Divide(vector, Length2D(vector)); + /// + /// Scales the Vector3D to unit length. + /// + /// The Vector3D to normalize. + /// A normalized vector. [MethodImpl(MaxOpt)] public static Vector256 Normalize3D(Vector256 vector) => Divide(vector, Length3D(vector)); + /// + /// Scales the Vector4D to unit length. + /// + /// The Vector4D to normalize. + /// A normalized vector. [MethodImpl(MaxOpt)] public static Vector256 Normalize4D(Vector256 vector) => Divide(vector, Length4D(vector)); @@ -50,15 +71,29 @@ public static Vector256 Normalize4D(Vector256 vector) #endregion #region Length - + /// + /// Returns the length of the given Vector2D. + /// + /// The input vector. + /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 Length2D(Vector256 vector) => Sqrt(DotProduct2D(vector, vector)); + /// + /// Returns the length of the given Vector3D. + /// + /// The input vector. + /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 Length3D(Vector256 vector) => Sqrt(DotProduct3D(vector, vector)); + /// + /// Returns the length of the given Vector4D. + /// + /// The input vector. + /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 Length4D(Vector256 vector) => Sqrt(DotProduct4D(vector, vector)); @@ -66,15 +101,29 @@ public static Vector256 Length4D(Vector256 vector) #endregion #region LengthSquared - + /// + /// Returns the length of the given Vector2D squared. + /// + /// The input vector. + /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 LengthSquared2D(Vector256 vector) => DotProduct2D(vector, vector); + /// + /// Returns the length of the given Vector3D squared. + /// + /// The input vector. + /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 LengthSquared3D(Vector256 vector) => DotProduct3D(vector, vector); + /// + /// Returns the length of the given Vector4D squared. + /// + /// The input vector. + /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 LengthSquared4D(Vector256 vector) => DotProduct4D(vector, vector); @@ -83,7 +132,12 @@ public static Vector256 LengthSquared4D(Vector256 vector) #region DotProduct - + /// + /// Returns the dot product of the two given vectors. + /// + /// The first input vector. + /// The second input vector. + /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] public static Vector256 DotProduct2D(Vector256 left, Vector256 right) { @@ -113,8 +167,13 @@ public static Vector256 DotProduct2D(Vector256 left, Vector256 + /// Returns the dot product of the two given vectors. + /// + /// The first input vector. + /// The second input vector. + /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] public static Vector256 DotProduct3D(Vector256 left, Vector256 right) { @@ -138,8 +197,13 @@ public static Vector256 DotProduct3D(Vector256 left, Vector256 + /// Returns the dot product of the two given vectors. + /// + /// The first input vector. + /// The second input vector. + /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] public static Vector256 DotProduct4D(Vector256 left, Vector256 right) { @@ -163,8 +227,13 @@ public static Vector256 DotProduct4D(Vector256 left, Vector256 + /// Returns the cross product of the two given vectors. + /// + /// The first input vector. + /// The second input vector. + /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] public static Vector256 CrossProduct2D(Vector256 left, Vector256 right) { @@ -194,8 +263,13 @@ public static Vector256 CrossProduct2D(Vector256 left, Vector256 return CrossProduct2D_Software(left, right); } - + /// + /// Returns the cross product of the two given vectors. + /// + /// The first input vector. + /// The second input vector. + /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] public static Vector256 CrossProduct3D(Vector256 left, Vector256 right) { @@ -252,6 +326,13 @@ public static Vector256 CrossProduct3D(Vector256 left, Vector256 return CrossProduct3D_Software(left, right); } + /// + /// Returns the cross product of the three given vectors. + /// + /// The first input vector. + /// The second input vector. + /// The third input vector. + /// The dot product of the two input vectors. // TODO [MethodImpl(MaxOpt)] public static Vector256 CrossProduct4D(Vector256 one, Vector256 two, Vector256 three) @@ -264,18 +345,32 @@ public static Vector256 CrossProduct4D(Vector256 one, Vector256< #endregion #region Distance - + /// + /// Computes the euclidean distance between two vectors. + /// + /// The first vector. + /// The second vector. + /// The distance between the two vectors. [MethodImpl(MaxOpt)] public static Vector256 Distance2D(Vector256 left, Vector256 right) => Length2D(Subtract(left, right)); - + /// + /// Computes the euclidean distance between two vectors. + /// + /// The first vector. + /// The second vector. + /// The distance between the two vectors. [MethodImpl(MaxOpt)] public static Vector256 Distance3D(Vector256 left, Vector256 right) => Length3D(Subtract(left, right)); - - + /// + /// Computes the euclidean distance between two vectors. + /// + /// The first vector. + /// The second vector. + /// The distance between the two vectors. [MethodImpl(MaxOpt)] public static Vector256 Distance4D(Vector256 left, Vector256 right) => Length4D(Subtract(left, right)); @@ -284,16 +379,32 @@ public static Vector256 Distance4D(Vector256 left, Vector256 + /// Compute the euclidean distance between two vectors squared. + /// + /// The first vector. + /// The second vector. + /// The distance between the two vectors. [MethodImpl(MaxOpt)] public static Vector256 DistanceSquared2D(Vector256 left, Vector256 right) => LengthSquared2D(Subtract(left, right)); + /// + /// Compute the euclidean distance between two vectors squared. + /// + /// The first vector. + /// The second vector. + /// The distance between the two vectors. [MethodImpl(MaxOpt)] public static Vector256 DistanceSquared3D(Vector256 left, Vector256 right) => LengthSquared3D(Subtract(left, right)); - - + /// + /// Compute the euclidean distance between two vectors squared. + /// + /// The first vector. + /// The second vector. + /// The distance between the two vectors. [MethodImpl(MaxOpt)] public static Vector256 DistanceSquared4D(Vector256 left, Vector256 right) => LengthSquared4D(Subtract(left, right)); @@ -302,6 +413,13 @@ public static Vector256 DistanceSquared4D(Vector256 left, Vector #region Lerp + /// + /// Returns a new vector that is a linear blend of the two given vectors. + /// + /// The first input vector. + /// The second input vector. + /// The blend factor. a when blend=0, b when blend=1. + /// The linear interpolated blend of the two vectors. [MethodImpl(MaxOpt)] public static Vector256 Lerp(Vector256 from, Vector256 to, double weight) { @@ -318,6 +436,12 @@ public static Vector256 Lerp(Vector256 from, Vector256 t #region Reflect + /// + /// Calculates the reflection of an incident ray. + /// + /// The incident ray's vector. + /// The normal of the mirror upon which the ray is reflecting. + /// The vector of the reflected ray. public static Vector256 Reflect2D(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal @@ -327,6 +451,12 @@ public static Vector256 Reflect2D(Vector256 incident, Vector256< return Subtract(incident, tmp); } + /// + /// Calculates the reflection of an incident ray. + /// + /// The incident ray's vector. + /// The normal of the mirror upon which the ray is reflecting. + /// The vector of the reflected ray. public static Vector256 Reflect3D(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal @@ -336,6 +466,12 @@ public static Vector256 Reflect3D(Vector256 incident, Vector256< return Subtract(incident, tmp); } + /// + /// Calculates the reflection of an incident ray. + /// + /// The incident ray's vector. + /// The normal of the mirror upon which the ray is reflecting. + /// The vector of the reflected ray. public static Vector256 Reflect4D(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal From 5c055fd52bc0ee5a51a8b91a9fcaa5c827f8a3a7 Mon Sep 17 00:00:00 2001 From: DMP9 Date: Wed, 27 Nov 2019 18:11:30 +0000 Subject: [PATCH 02/10] D Trig --- .../VectorDouble/Trigonometry.cs | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs index 0f5d592..8f0afb0 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs @@ -17,6 +17,11 @@ public static partial class Vector private static readonly Vector256 SinCoefficient1D = Vector256.Create(-2.3889859e-08d, -0.16665852d, +0.0083139502d, -0.00018524670d); private const double SinCoefficient1DScalar = -2.3889859e-08d; + /// + /// Returns the sine of the specified angle. + /// + /// The angle. + /// The sine of the given angle. [MethodImpl(MaxOpt)] public static Vector256 Sin(Vector256 vector) { @@ -71,6 +76,11 @@ static Vector256 SoftwareFallback(Vector256 vector) } } + /// + /// Returns the approximate sine of the specified angle. + /// + /// The angle. + /// The approximate sine of the given angle. [MethodImpl(MaxOpt)] public static Vector256 SinApprox(Vector256 vector) { @@ -113,6 +123,11 @@ public static Vector256 SinApprox(Vector256 vector) private static readonly Vector256 CosCoefficient1D = Vector256.Create(-2.6051615e-07d, -0.49992746d, +0.041493919d, -0.0012712436d); private const double CosCoefficient1DScalar = -2.6051615e-07d; + /// + /// Returns the cosine of the specified angle. + /// + /// The angle. + /// The cosine of the given angle. [MethodImpl(MaxOpt)] public static Vector256 Cos(Vector256 vector) { @@ -170,6 +185,11 @@ static Vector256 SoftwareFallback(Vector256 vector) } } + /// + /// Returns the approximate cosine of the specified angle. + /// + /// The angle. + /// The approximate cosine of the given angle. [MethodImpl(MaxOpt)] public static Vector256 CosApprox(Vector256 vector) { @@ -215,6 +235,11 @@ public static Vector256 CosApprox(Vector256 vector) private static readonly Vector256 TanCoefficients1D = Vector256.Create(4.981943399e-7d, -1.333835001e-1d, 3.424887824e-3d, -1.786170734e-5d); private static readonly Vector256 TanConstantsD = Vector256.Create(1.570796371d, 6.077100628e-11d, 0.000244140625d, 0.63661977228d); + /// + /// Returns the tangent of the specified angle. + /// + /// The angle. + /// The tangent of the given angle. [MethodImpl(MaxOpt)] public static Vector256 Tan(Vector256 vector) { @@ -294,6 +319,11 @@ static Vector256 SoftwareFallback(Vector256 vector) private static readonly Vector256 TanEstCoefficientsD = Vector256.Create(2.484d, -1.954923183e-1d, 2.467401101d, ScalarDoubleConstants.OneDivPi); + /// + /// Returns the approximate tangent of the specified angle. + /// + /// The angle. + /// The approximate tangent of the given angle. [MethodImpl(MaxOpt)] public static Vector256 TanApprox(Vector256 vector) { @@ -324,6 +354,12 @@ public static Vector256 TanApprox(Vector256 vector) return Tan(vector); } + /// + /// Calculates both the sine and cosine of the given angle. + /// + /// The angle. + /// The sine of the angle. + /// The cosine of the angle. [MethodImpl(MaxOpt)] public static void SinCos(Vector256 vector, out Vector256 sin, out Vector256 cos) { @@ -400,7 +436,12 @@ static void SoftwareFallback(Vector256 vector, out Vector256 sin cos = Cos(vector); } } - + /// + /// Calculates both the approximate sine and cosine of the given angle. + /// + /// The angle. + /// The approximate sine of the angle. + /// The approximate cosine of the angle. [MethodImpl(MaxOpt)] public static void SinCosApprox(Vector256 vector, out Vector256 sin, out Vector256 cos) { From 05aa115986529e6a84fc31790457cee7154eb48b Mon Sep 17 00:00:00 2001 From: Dylan Perks Date: Sun, 1 Dec 2019 19:40:15 +0000 Subject: [PATCH 03/10] This is 1.0.0-pre --- Directory.Build.props | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index f9399d5..d98f68f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -38,23 +38,21 @@ John Kelly and Contributors $(BaseArtifactsPath)bin/$(BaseArtifactsPathSuffix)/ - johnkellyoxford + John Kelly $(BaseArtifactsPath)pkg/$(BaseArtifactsPathSuffix)/$(Configuration)/ MathSharp - 0.0.1 - alpha + 1.0.0 + pre - $(MSBuildThisFileDirectory)MathSharp.snk - Copyright � John Kelly and Contributors - A high speed vector maths library + Copyright (C) John Kelly and Contributors + MathSharp is a vector and matrix library written in C# using hardware intrinsics. Thanks to hardware acceleration, MathSharp is significantly faster than most mathematics libraries out there. strict false true preview - 00240000048000009400000006020000002400005253413100040000010001000586cd22205c2991de00dea27c3455744874d5b9c4532ccee2bf8fa9b55752af42fa6170f641c20d1501cd3b9e6d22a1327cdaf19eb8eba23e8ed350a60930e7286417916e3a3a39798e69d8d521ac3af4c720cbcca2f2fbf5cee2c0b1c6be08ebba9051399148c663c3408513be9a2ff96e7816bb1b3713d1f30e13fa2e66a9 en-GB true MIT @@ -74,4 +72,4 @@ - \ No newline at end of file + From cfb440355525a60e6ee5f8f147fa7b5b6f3d61e1 Mon Sep 17 00:00:00 2001 From: DMP9 Date: Sun, 1 Dec 2019 19:41:57 +0000 Subject: [PATCH 04/10] wip --- .../Vector/VectorFloatingPoint/VectorDouble/Conversions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Conversions.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Conversions.cs index 3466448..15e5515 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Conversions.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Conversions.cs @@ -13,6 +13,11 @@ public static unsafe partial class Vector { #region Loads + /// + /// Creates a new Vector256<double> from a pointer to 4 doubles. + /// + /// + /// [MethodImpl(MaxOpt)] public static Vector256 FromVector4DAligned(double* p) => FromVector4D(p); From 52a1ab5f1ee4c54b8fd568e2851a5e2060837f2d Mon Sep 17 00:00:00 2001 From: Dylan Perks Date: Wed, 11 Dec 2019 16:05:08 +0000 Subject: [PATCH 05/10] This is 2.0 ;-; --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index d98f68f..65ab0a1 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -41,7 +41,7 @@ John Kelly $(BaseArtifactsPath)pkg/$(BaseArtifactsPathSuffix)/$(Configuration)/ MathSharp - 1.0.0 + 2.0.0 pre From e8889209c7fdbb7dc2265f67637039d325f0fb65 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 14 Dec 2019 16:42:46 +0000 Subject: [PATCH 06/10] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index d4960a5..a063508 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,6 @@ [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/john-h-k/MathSharp/blob/master/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/john-h-k/MathSharp.svg)](https://GitHub.com/john-h-k/MathSharp/issues/) -[![GitHub stars](https://img.shields.io/github/stars/john-h-k/MathSharp.svg?style=social&label=Star&maxAge=2592000)](https://GitHub.com/john-h-k/MathSharp/stargazers/) - |Configuration|Windows x86|Windows x64|Ubuntu 1604 x64|Mac OS x64| From 1f0f80390d0ae5280dac60ae10cdae54a0f68bcb Mon Sep 17 00:00:00 2001 From: John Date: Thu, 20 Feb 2020 20:07:27 +0000 Subject: [PATCH 07/10] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a063508..fb05cb4 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,8 @@ Vector4 + Vector4; ### Results (within margin of error between MathSharp and System.Numerics) -![Vector Addition Benchmark](assets/Benchmarks/VectorAdditionBenchmark-barplot.png) + + | Method | Mean | Error | StdDev | |--------------- |----------:|----------:|----------:| From 0ebf7031ab1fd05d3c52183d9c3bc6d0c8e17d71 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 27 Jun 2020 13:50:53 +0100 Subject: [PATCH 08/10] Refactor --- docs/Comparisons-And-Selections.md | 97 +++++++++++++++++++ docs/Introduction.md | 66 +++++++++++++ docs/Storage.md | 27 ++++++ .../Vector/Single/CameraClassBenchmark.cs | 23 ++++- .../Vector/Single/SelectionBenchmark.cs | 62 ++++++++++++ .../Vector/Single/SineWaveBenchmark.cs | 1 + .../MathSharp.Interactive.csproj | 6 +- samples/MathSharp.Interactive/Program.cs | 12 +-- sources/MathSharp/MathSharp.csproj | 2 +- .../Matrix/MatrixSingle/BasicMaths.cs | 42 +++++++- .../Matrix/MatrixSingle/MatrixOperations.cs | 10 +- sources/MathSharp/Quaternion/Quaternion.cs | 6 +- .../MathSharp/Vector/Shared/BitComparisons.cs | 48 ++++----- .../Vector/Shared/BitOperations.T.cs | 23 ++--- .../MathSharp/Vector/Shared/IsSupported.cs | 2 +- .../VectorFloatingPoint/VectorConstants.cs | 53 +++++----- .../VectorOperations.SoftwareFallbacks.cs | 30 +++--- .../VectorDouble/Trigonometry.cs | 2 +- .../VectorDouble/VectorOperations.cs | 42 ++++---- .../Conversions.SystemNumerics.cs | 12 +-- .../VectorSingle/Conversions.cs | 7 +- .../VectorSingle/HwVector.cs | 17 ++++ .../VectorOperations.SoftwareFallbacks.cs | 12 +-- .../VectorSingle/Trigonometry.cs | 58 +++++------ .../VectorSingle/VectorOperations.cs | 46 ++++----- .../MathSharp.UnitTests.csproj | 2 +- .../VectorOperations/CrossProduct.cs | 18 ++-- .../VectorOperations/DotProduct.cs | 12 +-- .../VectorOperations/CrossProduct.cs | 18 ++-- .../VectorOperations/DotProduct.cs | 12 +-- 30 files changed, 544 insertions(+), 224 deletions(-) create mode 100644 docs/Comparisons-And-Selections.md create mode 100644 docs/Introduction.md create mode 100644 docs/Storage.md create mode 100644 samples/MathSharp.Interactive/Benchmarks/Vector/Single/SelectionBenchmark.cs create mode 100644 sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs diff --git a/docs/Comparisons-And-Selections.md b/docs/Comparisons-And-Selections.md new file mode 100644 index 0000000..8c32ac5 --- /dev/null +++ b/docs/Comparisons-And-Selections.md @@ -0,0 +1,97 @@ +# Comparisons + +MathSharp offers all the comparisons you'd expect - but they don't necessarily work in the way you'd expect from working with other libraries. +Most comparison results return the same type you give them, rather than `bool` or multiple `bool`s. You might find this confusing, but it'll make sense soon. + +Let's start with the simple comparisons. You want to check if all or any elements of a vector are true or false for a comparison. This is really easily achieved with extension methods. +For example - test if 2 vectors are equal: + +```cs +public bool AreEqual(Vector128 left, Vector128 right) +{ + var comp = Vector.CompareEqual(left, right); + return comp.AllTrue(); // returns true if all elements in the comparison are true, else false +} +``` + +Tada! It's that simple. The 4 simplest comparison extensions are: + +```cs +AllTrue() - true if all elements of the comparison are true +AllFalse() - true if all elements of the comparison are false +AllFalse() - true if any elements of the comparison are true +AnyFalse() - true if any elements of the comparison are false +``` + +First, a quick brush up on bitwise operations. A bitwise `and`/`&`, results in a bit being set if both inputs are set. Else it is zero. +A bitwise `or`/`|`, results in a bit being set if either or both inputs are set. If both are zero, it is zero. E.g + +```cs +// 0b indicates a binary literal. & is and, | is or +0b_1 & 0b_1 -> 1 +0b_0 & 0b_1 -> 0 +0b_1 & 0b_0 -> 0 +0b_0 & 0b_0 -> 0 + +0b_1 | 0b_1 -> 1 +0b_0 | 0b_1 -> 1 +0b_1 | 0b_0 -> 1 +0b_0 | 0b_0 -> 0 +``` + +Also remember that all values on your computer are binary. Floating point types are complex, but they're still a chunk of binary data and nothing more. +So, let's give an example operation we want to do. Say we have a vector, and we want to multiply all numbers on it by another vector, if they are equal to the numbers in the other vector, else, we want to square root them. +E,g `<99, -5, 6, -2.3>, <99, 7, 0.1, -2.3>` would become `<99 * 99, Sqrt(-5), Sqrt(6), -2.3 * -2.3>`. Let's write this using `System.Numerics` + +```cs +public Vector4 Foo(Vector4 left, Vector4 right) +{ + var mul = left * right; + var sqrt = Vector4.SquareRoot(mul); + + // No way to vectorise this :() + var x = left.X == right.X ? left.X * right.X : MathF.Sqrt(left.X); + var y = left.Y == right.Y ? left.Y * right.Y : MathF.Sqrt(left.Y); + var z = left.Z == right.Z ? left.Z * right.Z : MathF.Sqrt(left.Z); + var w = left.W == right.W ? left.W * right.W : MathF.Sqrt(left.W); + return new Vector4(x, y, z, w); +} +``` + +On my system, this takes about 3 nanoseconds. Not bad eh! + +Now let's look at MathSharp implementation: + +```cs +public Vector128 Foo(Vector128 left, Vector128 right) +{ + var comp = Vector.CompareEqual(left, right); + var mul = Vector.Multiply(left, right); + var sqrt = Vector.Sqrt(mul); + + return Vector.Select(sqrt, mul, comp); +} +``` + +Again on my system, this takes 0.3 nanoseconds. That's a 10x speedup! +So, what does it do? + +First, it does the comparison. `Vector.CompareEqual` returns a `Vector128`, as mentioned above. However, what's important is what is in that return. +Each element is either all-1s or all-0s as binary. This means, that you can use them as masks. For example, to select all elements of a vector that are equal to another, and zero the rest, you just do + +```cs +Vector.And(left, Vector.CompareEqual(left, right)); +``` + +E.g, with `<1, 2, 3, 4>` and `<1, 3, 3, 5>`, the comparison returns `<0xFFFFFFFF, 0, 0xFFFFFFFF, 0>`. When we perform the `and`, as we learnt above, the elements with 0 are discarded, and the ones with `0xFFFFFFFF` (which is all bits set) are kept. + +Given the commonness of this operation, MathSharp provides 3 selection helper methods: + +```cs +SelectWhereTrue(selector, vector) +SelectWhereFalse(selector, vector) +Select(selector, left, right) +``` + +`SelectWhereTrue` and `SelectWhereFalse` are reasonably self explanatory. They select elements from `vector` which correspond to `true` elements of the `selector` (usually created with a `Vector.Compare...` method). +`Select` works like a ternary expression, selecting elements from `left` where `selector` is true, and from `right` where `selector` is `false`. In the above example, we select the multiplied value when the values are equal, else we select the square root value. \ No newline at end of file diff --git a/docs/Introduction.md b/docs/Introduction.md new file mode 100644 index 0000000..7b92e2e --- /dev/null +++ b/docs/Introduction.md @@ -0,0 +1,66 @@ +# What is MathSharp + +MathSharp is a library designed around blazing-fast, platform-agnostic linear algebra and 3D maths. + +## What are the advantages of MathSharp over its competitors? + +MathSharp is faster! Check our [benchmarks](https://github.com/john-h-k/MathSharp/blob/master/README.md). We offer a more complete feature set than `System.Numerics`, with faster inclusion of new features (such as colour and collision support, which are currently in the works). We also offer fully-fledged double-precision vector, quaternion, and matrix types in .NET Core 3.0, which `System.Numerics` doesn't. + +## That sounds great, but what does using MathSharp look like? + +Let's take a relatively simple example. You have some code, using the `System.Numeric`s types, that just finds the cross product of 2 pairs of vectors, then finds the dot of that. + +```cs +public void DotAndCross(Vector3 left0, Vector3 left1, Vector3 right0, Vector3 right1, out Vector3 result) +{ + var leftDot = new Vector3(Vector3.Dot(left0, left1)); + var rightDot = new Vector3(Vector3.Dot(right0, right1)); + result = Vector3.Cross(leftDot, rightDot); +} +``` + +So, the first step is take the incoming `Vector3` params by reference. This isn't always necessary, but it allows you to take advantage of better loading on some platforms. + +Then, we convert the `System.Numerics` types to the native SIMD types by using MathSharp's extension methods. `Load()` takes a `Vector3`, and returns a `Vector128`. +We then use the static methods in `MathSharp.Vector` to perform our operations. Here, we want to perform a 3D dot and cross. + +We then finally use the `Vector.Store` method to store out SIMD type into our storage type. + +```cs +using MathSharp; // Include at the top + +public void DotAndCross(in Vector3 left0, in Vector3 left1, in Vector3 right0, in Vector3 right1, out Vector3 result) +{ + var leftDot = Vector.Dot3D(left0.Load(), left1.Load()); + var rightDot = Vector.Dot3D(right0.Load(), right1.Load()); + + Vector.Store(Vector.Cross3D(leftDot, rightDot), out result); +} +``` + +Tada! You've just used MathSharp without even making a breaking change. This is still a great way to use it - but not the best. + +The idiomatic, fastest way to use MathSharp, is to pass around the SIMD types as arguments and returns, and use the so-called storage types - such as `System.Numerics` and `OpenTk.Maths` types, as well as your custom storage types, for fields and members of other types. For more information about this as well as creating your own storage types, check out [storage](storage.md). For example, rewriting the above method to be idiomatic MathSharp would be + +```cs +using MathSharp; // Include at the top + +public Vector128 DotAndCross(Vector128 left0, Vector128 left1, Vector128 right0, Vector128 right1) +{ + var leftDot = Vector.Dot3D(left0, left1); + var rightDot = Vector.Dot3D(right0, right1); + + return Vector.Cross3D(leftDot, rightDot); +} +``` + +The key MathSharp types are: + +* `Vector` - a static class containing methods to work with vectors +* `Matrix` - a static class containing methods to work with matrixes +* `Quaternion` - a static class containing methods to work with quaternions +* `MatrixSingle` - a struct used to represent a single-precision 4x4 matrix SIMD type + +Comparisons in MathSharp are extremely powerful - allowing you to perform a far wide variety +of comparison and selection operations, and to use those comparisons in ways that other libraries simply don't. If you've ever worked with SIMD before, these comparisons will be intuitive to you. If not, they're still easy to learn, and unlock a wide range of operations. Check out our [comparisons](comparisons-and-selections.md) doc for more. + diff --git a/docs/Storage.md b/docs/Storage.md new file mode 100644 index 0000000..10bf00e --- /dev/null +++ b/docs/Storage.md @@ -0,0 +1,27 @@ +# Storage + +MathSharp operations are designed to occur with locals and arguments, which are located on the stack or SIMD registers, allowing them to be fast and efficient. Because of this, +the types worked with are generally larger than you would expect or have specific alignment requirements, and don't distinguish between different dimensions. Generally, you should use other types +for fields and members of types, and then use SIMD types for passing parameters or returns. This will result in the best performance and the minimum number of conversions between storage and SIMD types. + +By default, MathSharp supports using the `System.Numerics` types as storage types, and provides `Load()` extension methods in `Vector, Matrix, Quaternion`, and `Store(out T store)` methods too. +Writing your own storage types is trivial. Use the `FromVector` and `ToVector` methods to convert the types. As an example, here is a custom Vector3 storage type. + +```cs +public struct MyVec3 +{ + public float X, Y, Z; + + public Vector128 Load() => Vector.FromVector3D(in x); +} + +public static class MyVec3Extensions +{ + public static void Store(this Vector128 vector, out MyVec3 vec3) => Vector.ToVector3D(vector, vec3); +} +``` + +You can use the aligned variants of these methods (e.g `FromVector3DAligned`) if you can guarantee the passed value is always 16 byte aligned for `float`s, and 32 byte aligned for `double`s. + +Passing by `in` is very important, because it ensures you are actually passing a reference. We don't take `ref` because we want to allow readonly members to be passed. +The load and from methods also have pointer overloads. Where these can be called without pinning, they should be used for potential performance benefits. \ No newline at end of file diff --git a/samples/MathSharp.Interactive/Benchmarks/Vector/Single/CameraClassBenchmark.cs b/samples/MathSharp.Interactive/Benchmarks/Vector/Single/CameraClassBenchmark.cs index 85c7b9c..fcb76e4 100644 --- a/samples/MathSharp.Interactive/Benchmarks/Vector/Single/CameraClassBenchmark.cs +++ b/samples/MathSharp.Interactive/Benchmarks/Vector/Single/CameraClassBenchmark.cs @@ -5,7 +5,7 @@ namespace MathSharp.Interactive.Benchmarks.Vector.Single { using Vector = MathSharp.Vector; - using Vector3 = OpenTK.Vector3; + using Vector3 = System.Numerics.Vector3; public class CameraClassBenchmark { @@ -21,7 +21,7 @@ public class CameraClassBenchmark [GlobalSetup] public void Setup() { - _pitch = 11f; + _pitch = 11f; _yaw = 0.008888f; _unitY = Vector128.Create(0f, 1f, 0f, 0f); _unitYWrapper = _unitY; @@ -38,12 +38,27 @@ public Vector128 MathSharp() { Vector128 front = _mathSharpFront; front = Vector.Normalize3D(front); - Vector128 right = Vector.Normalize3D(Vector.CrossProduct3D(_unitY, front)); + Vector128 right = Vector.Normalize3D(Vector.Cross3D(_unitY, front)); - Vector128 up = Vector.Normalize3D(Vector.CrossProduct3D(front, right)); + Vector128 up = Vector.Normalize3D(Vector.Cross3D(front, right)); return up; } + public void DotAndCross(Vector3 left0, Vector3 left1, Vector3 right0, Vector3 right1, out Vector3 result) + { + var leftDot = new Vector3(Vector3.Dot(left0, left1)); + var rightDot = new Vector3(Vector3.Dot(right0, right1)); + result = Vector3.Cross(leftDot, rightDot); + } + + public void DotAndCross(in Vector3 left0, in Vector3 left1, in Vector3 right0, in Vector3 right1, out Vector3 result) + { + var leftDot = Vector.Dot3D(left0.Load(), left1.Load()); + var rightDot = Vector.Dot3D(right0.Load(), right1.Load()); + + Vector.Store(Vector.Cross3D(leftDot, rightDot), out result); + } + [Benchmark] public Vector3 OpenTkMath() { diff --git a/samples/MathSharp.Interactive/Benchmarks/Vector/Single/SelectionBenchmark.cs b/samples/MathSharp.Interactive/Benchmarks/Vector/Single/SelectionBenchmark.cs new file mode 100644 index 0000000..29ab602 --- /dev/null +++ b/samples/MathSharp.Interactive/Benchmarks/Vector/Single/SelectionBenchmark.cs @@ -0,0 +1,62 @@ +using BenchmarkDotNet.Attributes; +using System; +using System.Collections.Generic; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Text; + +using MVector = MathSharp.Vector; + +namespace MathSharp.Interactive.Benchmarks.Vector.Single +{ + public class SelectionBenchmark + { + private Vector4 _value = new Vector4(99, -5, 6, -2.3f); + private Vector4 _multiply = new Vector4(99, 7, 0.1f, -2.3f); + + + private Vector128 _value1 = Vector128.Create(99, -5, 6, -2.3f); + private Vector128 _multiply1 = Vector128.Create(99, 7, 0.1f, -2.3f); + + [Benchmark] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public Vector4 SysNumeric() => Foo(_value, _multiply); + + [Benchmark] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public Vector128 MathSharp() => Foo(_value1, _multiply1); + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public Vector4 Foo(Vector4 left, Vector4 right) + { + var mul = left * right; + var sqrt = Vector4.SquareRoot(mul); + // No way to vectorise this :( + var x = left.X == right.X ? left.X * right.X : sqrt.X; + var y = left.Y == right.Y ? left.Y * right.Y : sqrt.Y; + var z = left.Z == right.Z ? left.Z * right.Z : sqrt.Z; + var w = left.W == right.W ? left.W * right.W : sqrt.W; + return new Vector4(x, y, z, w); + } + + //[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + //public static Vector128 MulNegAndAbs_MathSharp(Vector128 value, Vector128 multiply) + //{ + // var mul = Sse.Multiply(Sse.Xor(value, Vector128.Create(int.MinValue).AsSingle()), multiply); + // mul = Sse.Max(mul, value); + // return Sse.And(mul, Vector128.Create(~int.MinValue).AsSingle()); + //} + + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public Vector128 Foo(Vector128 left, Vector128 right) + { + var comp = MVector.CompareEqual(left, right); + var mul = MVector.Multiply(left, right); + var sqrt = MVector.Sqrt(mul); + + return MVector.Select(comp, mul, sqrt); + } + } +} diff --git a/samples/MathSharp.Interactive/Benchmarks/Vector/Single/SineWaveBenchmark.cs b/samples/MathSharp.Interactive/Benchmarks/Vector/Single/SineWaveBenchmark.cs index 3d4bcb3..84755b9 100644 --- a/samples/MathSharp.Interactive/Benchmarks/Vector/Single/SineWaveBenchmark.cs +++ b/samples/MathSharp.Interactive/Benchmarks/Vector/Single/SineWaveBenchmark.cs @@ -1,4 +1,5 @@ using BenchmarkDotNet.Attributes; +using OpenTK; using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/samples/MathSharp.Interactive/MathSharp.Interactive.csproj b/samples/MathSharp.Interactive/MathSharp.Interactive.csproj index 9545180..c520811 100644 --- a/samples/MathSharp.Interactive/MathSharp.Interactive.csproj +++ b/samples/MathSharp.Interactive/MathSharp.Interactive.csproj @@ -3,8 +3,8 @@ 1573;1591;NU1701;CS0649;CS1591; Exe - netcoreapp3.0 - preview + netcoreapp3.1 + 8.0 false @@ -17,7 +17,7 @@ - + diff --git a/samples/MathSharp.Interactive/Program.cs b/samples/MathSharp.Interactive/Program.cs index 8fb05ff..5724b1e 100644 --- a/samples/MathSharp.Interactive/Program.cs +++ b/samples/MathSharp.Interactive/Program.cs @@ -7,6 +7,10 @@ using System.Runtime.Intrinsics.X86; using MathSharp.StorageTypes; using MathSharp; +using MathSharp.Interactive.Benchmarks.Vector.Single; + +using Vector4 = System.Numerics.Vector4; +using BenchmarkDotNet.Running; namespace MathSharp.Interactive { @@ -17,13 +21,7 @@ internal unsafe class Program public static void Main(string[] args) { - Console.WriteLine(StaticReadonly); - Unsafe.AsRef(StaticReadonly.GetPinnableReference()) = 'B'; - Console.WriteLine(StaticReadonly); - - Console.WriteLine(Const); - Unsafe.AsRef(Const.GetPinnableReference()) = 'B'; - Console.WriteLine(Const); + BenchmarkRunner.Run(); } public static ref byte Ref(Span span) => ref span.GetPinnableReference(); diff --git a/sources/MathSharp/MathSharp.csproj b/sources/MathSharp/MathSharp.csproj index c3a41a5..b9bf984 100644 --- a/sources/MathSharp/MathSharp.csproj +++ b/sources/MathSharp/MathSharp.csproj @@ -1,7 +1,7 @@  - netcoreapp3.0 + netcoreapp3.1 false diff --git a/sources/MathSharp/Matrix/MatrixSingle/BasicMaths.cs b/sources/MathSharp/Matrix/MatrixSingle/BasicMaths.cs index 61889b1..ab75366 100644 --- a/sources/MathSharp/Matrix/MatrixSingle/BasicMaths.cs +++ b/sources/MathSharp/Matrix/MatrixSingle/BasicMaths.cs @@ -9,6 +9,12 @@ public static partial class Matrix private const MethodImplOptions MaxOpt = MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization; + /// + /// Performs an element-wise matrix addition on the 2 s + /// + /// The left matrix to add + /// The right matrix to add + /// A with its components added [MethodImpl(MaxOpt)] public static MatrixSingle Add(in MatrixSingle left, in MatrixSingle right) => new MatrixSingle( @@ -18,6 +24,12 @@ public static MatrixSingle Add(in MatrixSingle left, in MatrixSingle right) => Vector.Add(left._v3, right._v3) ); + /// + /// Performs an element-wise matrix addition on the 2 s + /// + /// The left matrix to add + /// The right matrix to add + /// A with its components added [MethodImpl(MaxOpt)] public static unsafe MatrixSingle Add(MatrixSingle* left, MatrixSingle* right) => new MatrixSingle( @@ -27,7 +39,12 @@ public static unsafe MatrixSingle Add(MatrixSingle* left, MatrixSingle* right) = Vector.Add(left->_v3, right->_v3) ); - + /// + /// Performs an element-wise matrix subtraction on the 2 s + /// + /// The left matrix to subtract + /// The right matrix to subtract + /// A with its components subtracted [MethodImpl(MaxOpt)] public static MatrixSingle Subtract(in MatrixSingle left, in MatrixSingle right) => new MatrixSingle( @@ -38,6 +55,11 @@ public static MatrixSingle Subtract(in MatrixSingle left, in MatrixSingle right) ); + /// + /// Performs an element-wise negation on a s + /// + /// The matrix to negate + /// A with its components negated [MethodImpl(MaxOpt)] public static MatrixSingle Negate(in MatrixSingle matrix) => new MatrixSingle( @@ -47,6 +69,12 @@ public static MatrixSingle Negate(in MatrixSingle matrix) => Vector.Negate(matrix._v3) ); + /// + /// Performs an element-wise matrix multiplication on the 2 s + /// + /// The left matrix to multiply + /// The right matrix to multiply + /// A with its components multiplied [MethodImpl(MaxOpt)] public static MatrixSingle ScalarMultiply(in MatrixSingle left, Vector128 vectorOfScalar) => new MatrixSingle( @@ -57,11 +85,21 @@ public static MatrixSingle ScalarMultiply(in MatrixSingle left, Vector128 ); + /// + /// Performs an element-wise matrix multiplication on a and a + /// + /// The left matrix to multiply + /// The scalar to multiply it by + /// A new with its components added [MethodImpl(MaxOpt)] public static MatrixSingle ScalarMultiply(in MatrixSingle left, float scalar) => ScalarMultiply(left, Vector128.Create(scalar)); - + /// + /// Transposes a + /// + /// The matrix to transpose + /// A new , transposed [MethodImpl(MaxOpt)] public static MatrixSingle Transpose(in MatrixSingle matrix) { diff --git a/sources/MathSharp/Matrix/MatrixSingle/MatrixOperations.cs b/sources/MathSharp/Matrix/MatrixSingle/MatrixOperations.cs index a5327b1..068f73d 100644 --- a/sources/MathSharp/Matrix/MatrixSingle/MatrixOperations.cs +++ b/sources/MathSharp/Matrix/MatrixSingle/MatrixOperations.cs @@ -137,9 +137,9 @@ public static MatrixSingle CreateBillboard(Vector128 objectPosition, Vect ? Vector.Negate(cameraForwardVector) : Multiply(z, Divide(SingleConstants.AllBitsSet, Sqrt(norm))); - Vector128 x = Normalize3D(CrossProduct3D(cameraUpVector, z)); + Vector128 x = Normalize3D(Cross3D(cameraUpVector, z)); - Vector128 y = CrossProduct3D(z, x); + Vector128 y = Cross3D(z, x); // We need W to be zero for x, y, and z, and 1.0f for objectPosition. They are currently undefined x = And(x, SingleConstants.MaskW); @@ -274,14 +274,14 @@ public static unsafe bool Decompose(MatrixSingle matrix, out Vector128 sc Rank3Decompose(out _, out _, out int cc, absX, absY, absZ); - *pVectorBasis[b] = CrossProduct3D(*pVectorBasis[a], *pCanonicalBasis[cc]); + *pVectorBasis[b] = Cross3D(*pVectorBasis[a], *pCanonicalBasis[cc]); } *pVectorBasis[b] = Normalize3D(*pVectorBasis[b]); if (Unsafe.Add(ref pFloat0, c) < DecomposeEpsilon) { - *pVectorBasis[c] = CrossProduct3D(*pVectorBasis[a], *pVectorBasis[b]); + *pVectorBasis[c] = Cross3D(*pVectorBasis[a], *pVectorBasis[b]); } *pVectorBasis[c] = Normalize3D(*pVectorBasis[c]); @@ -348,7 +348,7 @@ public static Vector128 Determinant(MatrixSingle matrix) r = FastNegateMultiplyAdd(v1, p1, r); r = FastMultiplyAdd(v2, p2, r); - return DotProduct4D(s, r); + return Dot4D(s, r); } [MethodImpl(MaxOpt)] diff --git a/sources/MathSharp/Quaternion/Quaternion.cs b/sources/MathSharp/Quaternion/Quaternion.cs index f049a79..d78026c 100644 --- a/sources/MathSharp/Quaternion/Quaternion.cs +++ b/sources/MathSharp/Quaternion/Quaternion.cs @@ -30,7 +30,7 @@ public static Vector128 Inverse(Vector128 quaternion) } public static Vector128 DotProduct(Vector128 left, Vector128 right) - => Vector.DotProduct4D(left, right); + => Vector.Dot4D(left, right); public static Vector128 Add(Vector128 left, Vector128 right) => Vector.Add(left, right); @@ -69,7 +69,7 @@ public static Vector128 Slerp(Vector128 left, Vector128 rig var cosOmega = DotProduct(left, right); var control = Vector.CompareLessThan(cosOmega, Vector128.Zero); - var sign = Vector.Select(Vector.SingleConstants.One, Vector.SingleConstants.NegativeOne, control); + var sign = Vector.Select(control, Vector.SingleConstants.NegativeOne, Vector.SingleConstants.One); cosOmega = Vector.Multiply(cosOmega, sign); @@ -90,7 +90,7 @@ public static Vector128 Slerp(Vector128 left, Vector128 rig s0 = Vector.Sin(s0); s0 = Vector.Divide(s0, sinOmega); - s0 = Vector.Select(v01, s0, control); + s0 = Vector.Select(control, s0, v01); var s1 = Vector.FillWithY(s0); s0 = Vector.FillWithX(s0); diff --git a/sources/MathSharp/Vector/Shared/BitComparisons.cs b/sources/MathSharp/Vector/Shared/BitComparisons.cs index 2a42c0e..fd851e1 100644 --- a/sources/MathSharp/Vector/Shared/BitComparisons.cs +++ b/sources/MathSharp/Vector/Shared/BitComparisons.cs @@ -8,11 +8,11 @@ namespace MathSharp public static partial class Vector { [MethodImpl(MaxOpt)] - public static Vector128 CompareBit8Equal(Vector128 left, Vector128 right) - => CompareBit8Equal(left.AsSByte(), right.AsSByte()).AsByte(); + public static Vector128 CompareEqual(Vector128 left, Vector128 right) + => CompareEqual(left.AsSByte(), right.AsSByte()).AsByte(); [MethodImpl(MaxOpt)] - public static Vector128 CompareBit8Equal(Vector128 left, Vector128 right) + public static Vector128 CompareEqual(Vector128 left, Vector128 right) { if (Sse2.IsSupported) { @@ -35,11 +35,11 @@ static Vector128 SoftwareFallback(Vector128 left, Vector128 } [MethodImpl(MaxOpt)] - public static Vector256 CompareBit8Equal(Vector256 left, Vector256 right) - => CompareBit8Equal(left.AsSByte(), right.AsSByte()).AsByte(); + public static Vector256 CompareEqual(Vector256 left, Vector256 right) + => CompareEqual(left.AsSByte(), right.AsSByte()).AsByte(); [MethodImpl(MaxOpt)] - public static Vector256 CompareBit8Equal(Vector256 left, Vector256 right) + public static Vector256 CompareEqual(Vector256 left, Vector256 right) { if (Avx2.IsSupported) { @@ -62,11 +62,11 @@ static Vector256 SoftwareFallback(Vector256 left, Vector256 } [MethodImpl(MaxOpt)] - public static Vector128 CompareBit16Equal(Vector128 left, Vector128 right) - => CompareBit16Equal(left.AsInt16(), right.AsInt16()).AsUInt16(); + public static Vector128 CompareEqual(Vector128 left, Vector128 right) + => CompareEqual(left.AsInt16(), right.AsInt16()).AsUInt16(); [MethodImpl(MaxOpt)] - public static Vector128 CompareBit16Equal(Vector128 left, Vector128 right) + public static Vector128 CompareEqual(Vector128 left, Vector128 right) { if (Sse2.IsSupported) { @@ -89,11 +89,11 @@ static Vector128 SoftwareFallback(Vector128 left, Vector128 } [MethodImpl(MaxOpt)] - public static Vector256 CompareBit16Equal(Vector256 left, Vector256 right) - => CompareBit16Equal(left.AsInt16(), right.AsInt16()).AsUInt16(); + public static Vector256 CompareEqual(Vector256 left, Vector256 right) + => CompareEqual(left.AsInt16(), right.AsInt16()).AsUInt16(); [MethodImpl(MaxOpt)] - public static Vector256 CompareBit16Equal(Vector256 left, Vector256 right) + public static Vector256 CompareEqual(Vector256 left, Vector256 right) { if (Avx2.IsSupported) { @@ -116,11 +116,11 @@ static Vector256 SoftwareFallback(Vector256 left, Vector256 } [MethodImpl(MaxOpt)] - public static Vector128 CompareBit32Equal(Vector128 left, Vector128 right) - => CompareBit32Equal(left.AsInt32(), right.AsInt32()).AsUInt32(); + public static Vector128 CompareEqual(Vector128 left, Vector128 right) + => CompareEqual(left.AsInt32(), right.AsInt32()).AsUInt32(); [MethodImpl(MaxOpt)] - public static Vector128 CompareBit32Equal(Vector128 left, Vector128 right) + public static Vector128 CompareEqual(Vector128 left, Vector128 right) { if (Sse2.IsSupported) { @@ -143,11 +143,11 @@ static Vector128 SoftwareFallback(Vector128 left, Vector128 right } [MethodImpl(MaxOpt)] - public static Vector256 CompareBit32Equal(Vector256 left, Vector256 right) - => CompareBit32Equal(left.AsInt32(), right.AsInt32()).AsUInt32(); + public static Vector256 CompareEqual(Vector256 left, Vector256 right) + => CompareEqual(left.AsInt32(), right.AsInt32()).AsUInt32(); [MethodImpl(MaxOpt)] - public static Vector256 CompareBit32Equal(Vector256 left, Vector256 right) + public static Vector256 CompareEqual(Vector256 left, Vector256 right) { if (Avx2.IsSupported) { @@ -170,11 +170,11 @@ static Vector256 SoftwareFallback(Vector256 left, Vector256 right } [MethodImpl(MaxOpt)] - public static Vector128 CompareBit64Equal(Vector128 left, Vector128 right) - => CompareBit64Equal(left.AsInt64(), right.AsInt64()).AsUInt64(); + public static Vector128 CompareEqual(Vector128 left, Vector128 right) + => CompareEqual(left.AsInt64(), right.AsInt64()).AsUInt64(); [MethodImpl(MaxOpt)] - public static Vector128 CompareBit64Equal(Vector128 left, Vector128 right) + public static Vector128 CompareEqual(Vector128 left, Vector128 right) { if (Sse41.IsSupported) { @@ -197,11 +197,11 @@ static Vector128 SoftwareFallback(Vector128 left, Vector128 ri } [MethodImpl(MaxOpt)] - public static Vector256 CompareBit64Equal(Vector256 left, Vector256 right) - => CompareBit64Equal(left.AsInt64(), right.AsInt64()).AsUInt64(); + public static Vector256 CompareEqual(Vector256 left, Vector256 right) + => CompareEqual(left.AsInt64(), right.AsInt64()).AsUInt64(); [MethodImpl(MaxOpt)] - public static Vector256 CompareBit64Equal(Vector256 left, Vector256 right) + public static Vector256 CompareEqual(Vector256 left, Vector256 right) { if (Avx2.IsSupported) { diff --git a/sources/MathSharp/Vector/Shared/BitOperations.T.cs b/sources/MathSharp/Vector/Shared/BitOperations.T.cs index ac60e90..ed8fef9 100644 --- a/sources/MathSharp/Vector/Shared/BitOperations.T.cs +++ b/sources/MathSharp/Vector/Shared/BitOperations.T.cs @@ -13,29 +13,30 @@ public static partial class Vector /// /// The type of each element in and /// The type of each element in - /// The vector where elements are chosen from if the equivalent element in is false - /// The vector where elements are chosen from if the equivalent element in is true /// The selector used to select elements from and + /// The vector where elements are chosen from if the equivalent element in is + /// The vector where elements are chosen from if the equivalent element in is /// A new with the elements selected by [MethodImpl(MaxOpt)] - public static Vector128 Select(Vector128 left, Vector128 right, Vector128 selector) + public static Vector128 Select(Vector128 selector, Vector128 left, Vector128 right) where T : struct where U : struct { if (Sse41.IsSupported) { + // BlendVariable takes what to insert if false, then if true if (typeof(T) == typeof(float)) { - return Sse41.BlendVariable(left.AsSingle(), right.AsSingle(), selector.AsSingle()).As(); + return Sse41.BlendVariable(right.AsSingle(), left.AsSingle(), selector.AsSingle()).As(); } else if (typeof(T) == typeof(double)) { - return Sse41.BlendVariable(left.AsDouble(), right.AsDouble(), selector.AsDouble()).As(); + return Sse41.BlendVariable(right.AsDouble(), left.AsDouble(), selector.AsDouble()).As(); } - return Sse41.BlendVariable(left.AsByte(), right.AsByte(), selector.AsByte()).As(); + return Sse41.BlendVariable(right.AsByte(), left.AsByte(), selector.AsByte()).As(); } - return Or(And(selector.As(), right), AndNot(selector.As(), left)); + return Or(And(selector.As(), left), AndNot(selector.As(), right)); } /// @@ -44,11 +45,11 @@ public static Vector128 Select(Vector128 left, Vector128 right, V /// /// The type of each element in /// The type of each element in - /// The vector to select elements from /// The vector to use to select elements from + /// The vector to select elements from /// A new with the elements selected by retained and the others zeroed [MethodImpl(MaxOpt)] - public static Vector128 SelectWhereTrue(Vector128 vector, Vector128 selector) + public static Vector128 SelectWhereTrue(Vector128 selector, Vector128 vector) where T : struct where U : struct => And(selector.As(), vector); @@ -58,11 +59,11 @@ public static Vector128 SelectWhereTrue(Vector128 vector, Vector128< /// /// The type of each element in /// The type of each element in - /// The vector to select elements from /// The vector to use to select elements from + /// The vector to select elements from /// A new with the elements selected by retained and the others zeroed [MethodImpl(MaxOpt)] - public static Vector128 SelectWhereFalse(Vector128 vector, Vector128 selector) + public static Vector128 SelectWhereFalse(Vector128 selector, Vector128 vector) where T : struct where U : struct => AndNot(selector.As(), vector); diff --git a/sources/MathSharp/Vector/Shared/IsSupported.cs b/sources/MathSharp/Vector/Shared/IsSupported.cs index 601d1f4..c611e07 100644 --- a/sources/MathSharp/Vector/Shared/IsSupported.cs +++ b/sources/MathSharp/Vector/Shared/IsSupported.cs @@ -71,7 +71,7 @@ public static bool IsHwAccelerated(VectorSize vectorSize) return vectorSize switch { VectorSize.V64 => false, - VectorSize.V128 => Sse.IsSupported, + VectorSize.V128 => Sse.IsSupported /* || AdvSimd.IsSupported */, VectorSize.V256 => Avx.IsSupported }; } diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorConstants.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorConstants.cs index d04fdb4..9054a52 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorConstants.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorConstants.cs @@ -61,39 +61,42 @@ public static Vector128 AllBitsSet } } - public static readonly Vector128 MaskSign = Vector128.Create(int.MaxValue).AsSingle(); - public static readonly Vector128 MaskNotSign = Vector128.Create(~int.MaxValue).AsSingle(); + public static Vector128 MaskSign => Vector128.Create(int.MinValue).AsSingle(); + //{ + // get { var i = int.MinValue; return Avx2.BroadcastScalarToVector128(&i).AsSingle(); } + //} + public static Vector128 MaskNotSign => Vector128.Create(~int.MaxValue).AsSingle(); // ReSharper disable InconsistentNaming - public static readonly Vector128 MaskNotSignXZ = Vector128.Create(~int.MaxValue, 0, ~int.MaxValue, 0).AsSingle(); - public static readonly Vector128 MaskNotSignYW = Vector128.Create(0, ~int.MaxValue, 0, ~int.MaxValue).AsSingle(); + public static Vector128 MaskNotSignXZ => Vector128.Create(~int.MaxValue, 0, ~int.MaxValue, 0).AsSingle(); + public static Vector128 MaskNotSignYW => Vector128.Create(0, ~int.MaxValue, 0, ~int.MaxValue).AsSingle(); - public static readonly Vector128 MaskX = Vector128.Create(+0, -1, -1, -1).AsSingle(); - public static readonly Vector128 MaskY = Vector128.Create(-1, +0, -1, -1).AsSingle(); - public static readonly Vector128 MaskZ = Vector128.Create(-1, -1, +0, -1).AsSingle(); - public static readonly Vector128 MaskW = Vector128.Create(-1, -1, -1, +0).AsSingle(); + public static Vector128 MaskX => Vector128.Create(+0, -1, -1, -1).AsSingle(); + public static Vector128 MaskY => Vector128.Create(-1, +0, -1, -1).AsSingle(); + public static Vector128 MaskZ => Vector128.Create(-1, -1, +0, -1).AsSingle(); + public static Vector128 MaskW => Vector128.Create(-1, -1, -1, +0).AsSingle(); - public static readonly Vector128 MaskXY = Vector128.Create(+0, +0, -1, -1).AsSingle(); - public static readonly Vector128 MaskZW = Vector128.Create(-1, -1, +0, +0).AsSingle(); + public static Vector128 MaskXY => Vector128.Create(+0, +0, -1, -1).AsSingle(); + public static Vector128 MaskZW => Vector128.Create(-1, -1, +0, +0).AsSingle(); - public static readonly Vector128 MaskXYZ = Vector128.Create(+0, +0, +0, -1).AsSingle(); - public static readonly Vector128 MaskYZW = Vector128.Create(-1, +0, +0, +0).AsSingle(); + public static Vector128 MaskXYZ => Vector128.Create(+0, +0, +0, -1).AsSingle(); + public static Vector128 MaskYZW => Vector128.Create(-1, +0, +0, +0).AsSingle(); - public static readonly Vector128 MaskXYZW = Vector128.Create(0).AsSingle(); + public static Vector128 MaskXYZW => Vector128.Create(0).AsSingle(); // ReSharper restore InconsistentNaming - public static readonly Vector128 UnitX = Vector128.Create(1f, 0f, 0f, 0f); - public static readonly Vector128 UnitY = Vector128.Create(0f, 1f, 0f, 0f); - public static readonly Vector128 UnitZ = Vector128.Create(0f, 0f, 1f, 0f); - public static readonly Vector128 UnitW = Vector128.Create(0f, 0f, 0f, 1f); - - public static readonly Vector128 OneDivPi = Vector128.Create(ScalarSingleConstants.OneDivPi); - public static readonly Vector128 OneDiv2Pi = Vector128.Create(ScalarSingleConstants.OneDiv2Pi); - public static readonly Vector128 Pi2 = Vector128.Create(ScalarSingleConstants.Pi2); - public static readonly Vector128 Pi = Vector128.Create(ScalarSingleConstants.Pi); - public static readonly Vector128 PiDiv2 = Vector128.Create(ScalarSingleConstants.PiDiv2); - public static readonly Vector128 PiDiv4 = Vector128.Create(ScalarSingleConstants.PiDiv4); - public static readonly Vector128 ThreePiDiv4 = Vector128.Create(ScalarSingleConstants.ThreePiDiv4); + public static Vector128 UnitX => Vector128.Create(1f, 0f, 0f, 0f); + public static Vector128 UnitY => Vector128.Create(0f, 1f, 0f, 0f); + public static Vector128 UnitZ => Vector128.Create(0f, 0f, 1f, 0f); + public static Vector128 UnitW => Vector128.Create(0f, 0f, 0f, 1f); + + public static Vector128 OneDivPi => Vector128.Create(ScalarSingleConstants.OneDivPi); + public static Vector128 OneDiv2Pi => Vector128.Create(ScalarSingleConstants.OneDiv2Pi); + public static Vector128 Pi2 => Vector128.Create(ScalarSingleConstants.Pi2); + public static Vector128 Pi => Vector128.Create(ScalarSingleConstants.Pi); + public static Vector128 PiDiv2 => Vector128.Create(ScalarSingleConstants.PiDiv2); + public static Vector128 PiDiv4 => Vector128.Create(ScalarSingleConstants.PiDiv4); + public static Vector128 ThreePiDiv4 => Vector128.Create(ScalarSingleConstants.ThreePiDiv4); } public static class SingleConstants256 diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs index dc9c91e..2e9de98 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs @@ -45,21 +45,21 @@ public static Vector256 Normalize4D_Software(Vector256 vector) [MethodImpl(MaxOpt)] public static Vector256 Length2D_Software(Vector256 vector) { - return Sqrt_Software(DotProduct2D_Software(vector, vector)); + return Sqrt_Software(Dot2D_Software(vector, vector)); } [MethodImpl(MaxOpt)] public static Vector256 Length3D_Software(Vector256 vector) { // No software fallback needed, these methods cover it - return Sqrt_Software(DotProduct3D_Software(vector, vector)); + return Sqrt_Software(Dot3D_Software(vector, vector)); } [MethodImpl(MaxOpt)] public static Vector256 Length4D_Software(Vector256 vector) { // No software fallback needed, these methods cover it - return Sqrt_Software(DotProduct4D_Software(vector, vector)); + return Sqrt_Software(Dot4D_Software(vector, vector)); } #endregion @@ -71,7 +71,7 @@ public static Vector256 Length4D_Software(Vector256 vector) #region DotProduct [MethodImpl(MaxOpt)] - public static Vector256 DotProduct2D_Software(Vector256 left, Vector256 right) + public static Vector256 Dot2D_Software(Vector256 left, Vector256 right) { return Vector256.Create( X(left) * X(right) @@ -80,7 +80,7 @@ public static Vector256 DotProduct2D_Software(Vector256 left, Ve } [MethodImpl(MaxOpt)] - public static Vector256 DotProduct3D_Software(Vector256 left, Vector256 right) + public static Vector256 Dot3D_Software(Vector256 left, Vector256 right) { return Vector256.Create( X(left) * X(right) @@ -90,7 +90,7 @@ public static Vector256 DotProduct3D_Software(Vector256 left, Ve } [MethodImpl(MaxOpt)] - public static Vector256 DotProduct4D_Software(Vector256 left, Vector256 right) + public static Vector256 Dot4D_Software(Vector256 left, Vector256 right) { return Vector256.Create( X(left) * X(right) @@ -105,14 +105,14 @@ public static Vector256 DotProduct4D_Software(Vector256 left, Ve #region CrossProduct [MethodImpl(MaxOpt)] - public static Vector256 CrossProduct2D_Software(Vector256 left, Vector256 right) + public static Vector256 Cross2D_Software(Vector256 left, Vector256 right) { return Vector256.Create((X(left) * Y(right) - Y(left) * X(right))); } [MethodImpl(MaxOpt)] - public static Vector256 CrossProduct3D_Software(Vector256 left, Vector256 right) + public static Vector256 Cross3D_Software(Vector256 left, Vector256 right) { /* Cross product of A(x, y, z, _) and B(x, y, z, _) is * @@ -128,7 +128,7 @@ public static Vector256 CrossProduct3D_Software(Vector256 left, } [MethodImpl(MaxOpt)] - public static Vector256 CrossProduct4D_Software(Vector256 one, Vector256 two, Vector256 three) + public static Vector256 Cross4D_Software(Vector256 one, Vector256 two, Vector256 three) { double x = (Z(two) * W(three) - W(two) * Z(three)) * Y(one) - @@ -198,7 +198,7 @@ public static Vector256 DistanceSquared2D_Software(Vector256 lef { Vector256 diff = Subtract_Software(left, right); - return DotProduct2D_Software(diff, diff); + return Dot2D_Software(diff, diff); } [MethodImpl(MaxOpt)] @@ -206,7 +206,7 @@ public static Vector256 DistanceSquared3D_Software(Vector256 lef { Vector256 diff = Subtract_Software(left, right); - return DotProduct3D_Software(diff, diff); + return Dot3D_Software(diff, diff); } [MethodImpl(MaxOpt)] @@ -214,7 +214,7 @@ public static Vector256 DistanceSquared4D_Software(Vector256 lef { Vector256 diff = Subtract_Software(left, right); - return DotProduct4D_Software(diff, diff); + return Dot4D_Software(diff, diff); } #endregion @@ -243,7 +243,7 @@ public static Vector256 Lerp_Software(Vector256 from, Vector256< public static Vector256 Reflect2D_Software(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector256 tmp = DotProduct2D_Software(incident, normal); + Vector256 tmp = Dot2D_Software(incident, normal); tmp = Add_Software(tmp, tmp); tmp = Multiply_Software(tmp, normal); return Subtract_Software(incident, tmp); @@ -252,7 +252,7 @@ public static Vector256 Reflect2D_Software(Vector256 incident, V public static Vector256 Reflect3D_Software(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector256 tmp = DotProduct3D_Software(incident, normal); + Vector256 tmp = Dot3D_Software(incident, normal); tmp = Add_Software(tmp, tmp); tmp = Multiply_Software(tmp, normal); return Subtract_Software(incident, tmp); @@ -261,7 +261,7 @@ public static Vector256 Reflect3D_Software(Vector256 incident, V public static Vector256 Reflect4D_Software(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector256 tmp = DotProduct4D_Software(incident, normal); + Vector256 tmp = Dot4D_Software(incident, normal); tmp = Add_Software(tmp, tmp); tmp = Multiply_Software(tmp, normal); return Subtract_Software(incident, tmp); diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs index 8f0afb0..8a01d1b 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/Trigonometry.cs @@ -274,7 +274,7 @@ public static Vector256 Tan(Vector256 vector) var t0 = FillWithX(TanCoefficients0D); var vbIsEven = And(vb, DoubleConstants.Epsilon).AsInt64(); - vbIsEven = CompareBit64Equal(vbIsEven, Vector256.Zero); + vbIsEven = CompareEqual(vbIsEven, Vector256.Zero); var n = FastMultiplyAdd(vc2, t7, t6); var d = FastMultiplyAdd(vc2, t4, t3); diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs index 8ee40fc..893059d 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorDouble/VectorOperations.cs @@ -78,7 +78,7 @@ public static Vector256 Normalize4D(Vector256 vector) /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 Length2D(Vector256 vector) - => Sqrt(DotProduct2D(vector, vector)); + => Sqrt(Dot2D(vector, vector)); /// /// Returns the length of the given Vector3D. @@ -87,7 +87,7 @@ public static Vector256 Length2D(Vector256 vector) /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 Length3D(Vector256 vector) - => Sqrt(DotProduct3D(vector, vector)); + => Sqrt(Dot3D(vector, vector)); /// /// Returns the length of the given Vector4D. @@ -96,7 +96,7 @@ public static Vector256 Length3D(Vector256 vector) /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 Length4D(Vector256 vector) - => Sqrt(DotProduct4D(vector, vector)); + => Sqrt(Dot4D(vector, vector)); #endregion @@ -108,7 +108,7 @@ public static Vector256 Length4D(Vector256 vector) /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 LengthSquared2D(Vector256 vector) - => DotProduct2D(vector, vector); + => Dot2D(vector, vector); /// /// Returns the length of the given Vector3D squared. @@ -117,7 +117,7 @@ public static Vector256 LengthSquared2D(Vector256 vector) /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 LengthSquared3D(Vector256 vector) - => DotProduct3D(vector, vector); + => Dot3D(vector, vector); /// /// Returns the length of the given Vector4D squared. @@ -126,7 +126,7 @@ public static Vector256 LengthSquared3D(Vector256 vector) /// The length vector. [MethodImpl(MaxOpt)] public static Vector256 LengthSquared4D(Vector256 vector) - => DotProduct4D(vector, vector); + => Dot4D(vector, vector); #endregion @@ -139,7 +139,7 @@ public static Vector256 LengthSquared4D(Vector256 vector) /// The second input vector. /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] - public static Vector256 DotProduct2D(Vector256 left, Vector256 right) + public static Vector256 Dot2D(Vector256 left, Vector256 right) { // SSE4.1 has a native dot product instruction, dppd if (Sse41.IsSupported) @@ -165,7 +165,7 @@ public static Vector256 DotProduct2D(Vector256 left, Vector256 @@ -175,7 +175,7 @@ public static Vector256 DotProduct2D(Vector256 left, Vector256The second input vector. /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] - public static Vector256 DotProduct3D(Vector256 left, Vector256 right) + public static Vector256 Dot3D(Vector256 left, Vector256 right) { // We can use AVX to vectorize the multiplication if (Avx.IsSupported) @@ -195,7 +195,7 @@ public static Vector256 DotProduct3D(Vector256 left, Vector256 @@ -205,7 +205,7 @@ public static Vector256 DotProduct3D(Vector256 left, Vector256The second input vector. /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] - public static Vector256 DotProduct4D(Vector256 left, Vector256 right) + public static Vector256 Dot4D(Vector256 left, Vector256 right) { if (Avx.IsSupported) { @@ -221,7 +221,7 @@ public static Vector256 DotProduct4D(Vector256 left, Vector256 DotProduct4D(Vector256 left, Vector256The second input vector. /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] - public static Vector256 CrossProduct2D(Vector256 left, Vector256 right) + public static Vector256 Cross2D(Vector256 left, Vector256 right) { /* Cross product of A(x, y, _, _) and B(x, y, _, _) is * 'E = (Ax * By) - (Ay * Bx)' @@ -261,7 +261,7 @@ public static Vector256 CrossProduct2D(Vector256 left, Vector256 return Avx.Shuffle(permute, permute, ShuffleValues.XXXX); } - return CrossProduct2D_Software(left, right); + return Cross2D_Software(left, right); } /// @@ -271,7 +271,7 @@ public static Vector256 CrossProduct2D(Vector256 left, Vector256 /// The second input vector. /// The dot product of the two input vectors. [MethodImpl(MaxOpt)] - public static Vector256 CrossProduct3D(Vector256 left, Vector256 right) + public static Vector256 Cross3D(Vector256 left, Vector256 right) { if (Avx2.IsSupported) { @@ -323,7 +323,7 @@ public static Vector256 CrossProduct3D(Vector256 left, Vector256 // TODO reuse vectors (minimal register usage) - potentially prevent any stack spilling } - return CrossProduct3D_Software(left, right); + return Cross3D_Software(left, right); } /// @@ -335,11 +335,11 @@ public static Vector256 CrossProduct3D(Vector256 left, Vector256 /// The dot product of the two input vectors. // TODO [MethodImpl(MaxOpt)] - public static Vector256 CrossProduct4D(Vector256 one, Vector256 two, Vector256 three) + public static Vector256 Cross4D(Vector256 one, Vector256 two, Vector256 three) { // hardware - return SoftwareFallbacks.CrossProduct4D_Software(one, two, three); + return SoftwareFallbacks.Cross4D_Software(one, two, three); } #endregion @@ -445,7 +445,7 @@ public static Vector256 Lerp(Vector256 from, Vector256 t public static Vector256 Reflect2D(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector256 tmp = DotProduct2D(incident, normal); + Vector256 tmp = Dot2D(incident, normal); tmp = Add(tmp, tmp); tmp = Multiply(tmp, normal); return Subtract(incident, tmp); @@ -460,7 +460,7 @@ public static Vector256 Reflect2D(Vector256 incident, Vector256< public static Vector256 Reflect3D(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector256 tmp = DotProduct3D(incident, normal); + Vector256 tmp = Dot3D(incident, normal); tmp = Add(tmp, tmp); tmp = Multiply(tmp, normal); return Subtract(incident, tmp); @@ -475,7 +475,7 @@ public static Vector256 Reflect3D(Vector256 incident, Vector256< public static Vector256 Reflect4D(Vector256 incident, Vector256 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector256 tmp = DotProduct4D(incident, normal); + Vector256 tmp = Dot4D(incident, normal); tmp = Add(tmp, tmp); tmp = Multiply(tmp, normal); return Subtract(incident, tmp); diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.SystemNumerics.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.SystemNumerics.cs index 1e3916f..71eca8e 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.SystemNumerics.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.SystemNumerics.cs @@ -7,21 +7,21 @@ namespace MathSharp public static unsafe partial class Vector { [MethodImpl(MaxOpt)] - public static Vector128 Load(this Vector4 vector) + public static Vector128 Load(this in Vector4 vector) { - return FromVector4D(&vector.X); + return FromVector4D(in vector.X); } [MethodImpl(MaxOpt)] - public static Vector128 Load(this Vector3 vector) + public static Vector128 Load(this in Vector3 vector) { - return FromVector3DAligned(&vector.X); // Vector3 is special cased to be 16 bytes on the stack to allow this + return FromVector3DAligned(in vector.X); // Vector3 is special cased to be 16 bytes on the stack to allow this } [MethodImpl(MaxOpt)] - public static Vector128 Load(this Vector2 vector) + public static Vector128 Load(this in Vector2 vector) { - return FromVector2D(&vector.X); + return FromVector2D(in vector.X); } public static void Store(this Vector128 vector, out Vector4 destination) diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.cs index 5d5ab9d..d0241e9 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Conversions.cs @@ -53,12 +53,7 @@ public static Vector128 FromVector2DAligned(float* p) [MethodImpl(MaxOpt)] public static Vector128 FromVector4D(in float p) - { - fixed (float* pp = &p) - { - return FromVector4D(pp); - } - } + => Unsafe.As>(ref Unsafe.AsRef(in p)); [MethodImpl(MaxOpt)] public static Vector128 FromVector4D(float* p) diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs new file mode 100644 index 0000000..30ec5e8 --- /dev/null +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Intrinsics; +using System.Text; + +namespace MathSharp.Vector.VectorFloatingPoint.VectorSingle +{ + public readonly struct HwVector + { + private readonly Vector128 Value; + + public static HwVector operator + (HwVector left, HwVector right) + { + return Vector.Add(left, right); + } + } +} diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs index 40f9ef9..b0cbd61 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/SoftwareFallbacks/VectorOperations.SoftwareFallbacks.cs @@ -14,7 +14,7 @@ internal static partial class SoftwareFallbacks #region DotProduct [MethodImpl(MaxOpt)] - public static Vector128 DotProduct2D_Software(Vector128 left, Vector128 right) + public static Vector128 Dot2D_Software(Vector128 left, Vector128 right) { return Vector128.Create( X(left) * X(right) + @@ -23,7 +23,7 @@ public static Vector128 DotProduct2D_Software(Vector128 left, Vect } [MethodImpl(MaxOpt)] - public static Vector128 DotProduct3D_Software(Vector128 left, Vector128 right) + public static Vector128 Dot3D_Software(Vector128 left, Vector128 right) { return Vector128.Create( X(left) * X(right) @@ -33,7 +33,7 @@ public static Vector128 DotProduct3D_Software(Vector128 left, Vect } [MethodImpl(MaxOpt)] - public static Vector128 DotProduct4D_Software(Vector128 left, Vector128 right) + public static Vector128 Dot4D_Software(Vector128 left, Vector128 right) { return Vector128.Create( X(left) * X(right) @@ -48,13 +48,13 @@ public static Vector128 DotProduct4D_Software(Vector128 left, Vect #region CrossProduct [MethodImpl(MaxOpt)] - public static Vector128 CrossProduct2D_Software(Vector128 left, Vector128 right) + public static Vector128 Cross2D_Software(Vector128 left, Vector128 right) { return Vector128.Create((X(left) * Y(right) - Y(left) * X(right))); } [MethodImpl(MaxOpt)] - public static Vector128 CrossProduct3D_Software(Vector128 left, Vector128 right) + public static Vector128 Cross3D_Software(Vector128 left, Vector128 right) { /* Cross product of A(x, y, z, _) and B(x, y, z, _) is * @@ -70,7 +70,7 @@ public static Vector128 CrossProduct3D_Software(Vector128 left, Ve } [MethodImpl(MaxOpt)] - public static Vector128 CrossProduct4D_Software(Vector128 one, Vector128 two, Vector128 three) + public static Vector128 Cross4D_Software(Vector128 one, Vector128 two, Vector128 three) { var x1 = X(one); var x2 = X(two); diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Trigonometry.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Trigonometry.cs index d05afe4..9395dd9 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Trigonometry.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/Trigonometry.cs @@ -34,7 +34,7 @@ public static Vector128 Sin(Vector128 vector) Vector128 neg = Subtract(tmp, vec); Vector128 comp = CompareLessThanOrEqual(abs, SingleConstants.PiDiv2); - vec = Select(neg, vec, comp); + vec = Select(comp, vec, neg); Vector128 vectorSquared = Square(vec); @@ -87,7 +87,7 @@ public static Vector128 SinApprox(Vector128 vector) Vector128 neg = Subtract(tmp, vec); Vector128 comp = CompareLessThanOrEqual(abs, SingleConstants.PiDiv2); - vec = Select(neg, vec, comp); + vec = Select(comp, vec, neg); Vector128 vectorSquared = Square(vec); @@ -131,11 +131,11 @@ public static Vector128 Cos(Vector128 vector) Vector128 comp = CompareLessThanOrEqual(abs, SingleConstants.PiDiv2); - vec = Select(neg, vec, comp); + vec = Select(comp, vec, neg); Vector128 vectorSquared = Square(vec); - vec = Select(SingleConstants.NegativeOne, SingleConstants.One, comp); + vec = Select(comp, SingleConstants.One, SingleConstants.NegativeOne); // Polynomial approx Vector128 cc0 = CosCoefficient0; @@ -188,11 +188,11 @@ public static Vector128 CosApprox(Vector128 vector) Vector128 comp = CompareLessThanOrEqual(abs, SingleConstants.PiDiv2); - vec = Select(neg, vec, comp); + vec = Select(comp, vec, neg); Vector128 vectorSquared = Square(vec); - vec = Select(SingleConstants.NegativeOne, SingleConstants.One, comp); + vec = Select(comp, SingleConstants.One, SingleConstants.NegativeOne); // Fast polynomial approx var cc1 = CosCoefficient1; @@ -250,7 +250,7 @@ public static Vector128 Tan(Vector128 vector) var t0 = FillWithX(TanCoefficients0); var vbIsEven = And(vb, SingleConstants.Epsilon).AsInt32(); - vbIsEven = CompareBit32Equal(vbIsEven, Vector128.Zero); + vbIsEven = CompareEqual(vbIsEven, Vector128.Zero); var n = FastMultiplyAdd(vc2, t7, t6); var d = FastMultiplyAdd(vc2, t4, t3); @@ -264,8 +264,8 @@ public static Vector128 Tan(Vector128 vector) d = FastMultiplyAdd(vc2, d, t0); - n = Select(n, vc, nearZero); - d = Select(d, SingleConstants.One, nearZero); + n = Select(nearZero, vc, n); + d = Select(nearZero, SingleConstants.One, d); var r0 = Negate(n); var r1 = Divide(n, d); @@ -273,9 +273,9 @@ public static Vector128 Tan(Vector128 vector) var isZero = CompareEqual(vector, Vector128.Zero); - var result = Select(r0, r1, vbIsEven); + var result = Select(vbIsEven, r1, r0); - result = Select(result, Vector128.Zero, isZero); + result = Select(isZero, Vector128.Zero, result); return result; } @@ -342,11 +342,11 @@ public static void SinCos(Vector128 vector, out Vector128 sin, out Vector128 comp = CompareLessThanOrEqual(abs, SingleConstants.PiDiv2); - vec = Select(neg, vec, comp); + vec = Select(comp, vec, neg); Vector128 vectorSquared = Square(vec); - var cosVec = Select(SingleConstants.NegativeOne, SingleConstants.One, comp); + var cosVec = Select(comp, SingleConstants.One, SingleConstants.NegativeOne); // Polynomial approx @@ -419,10 +419,10 @@ public static void SinCosApprox(Vector128 vector, out Vector128 si Vector128 comp = CompareLessThanOrEqual(abs, SingleConstants.PiDiv2); - vec = Select(neg, vec, comp); + vec = Select(comp, vec, neg); Vector128 vectorSquared = Square(vec); - var cosVec = Select(SingleConstants.NegativeOne, SingleConstants.One, comp); + var cosVec = Select(comp, SingleConstants.One, SingleConstants.NegativeOne); // Fast polynomial approx @@ -482,7 +482,7 @@ public static Vector128 ATan2(Vector128 left, Vector128 rig var yEqualsZero = CompareEqual(left, SingleConstants.Zero); var xEqualsZero = CompareEqual(right, SingleConstants.Zero); var rightIsPositive = ExtractSign(right); - rightIsPositive = CompareBit32Equal(rightIsPositive.AsInt32(), Vector128.Zero).AsSingle(); + rightIsPositive = CompareEqual(rightIsPositive.AsInt32(), Vector128.Zero).AsSingle(); var yEqualsInfinity = IsInfinite(left); var xEqualsInfinity = IsInfinite(right); @@ -492,22 +492,22 @@ public static Vector128 ATan2(Vector128 left, Vector128 rig piDiv4 = Or(piDiv4, ySign); threePiDiv4 = Or(threePiDiv4, ySign); - var r1 = Select(pi, ySign, rightIsPositive); - var r2 = Select(aTanResultValid, piDiv2, xEqualsZero); - var r3 = Select(r2, r1, yEqualsZero); - var r4 = Select(threePiDiv4, piDiv4, rightIsPositive); - var r5 = Select(piDiv2, r4, xEqualsInfinity); - var result = Select(r3, r5, yEqualsInfinity); - aTanResultValid = CompareBit32Equal(result.AsInt32(), aTanResultValid.AsInt32()).AsSingle(); + var r1 = Select(rightIsPositive, ySign, pi); + var r2 = Select(xEqualsZero, piDiv2, aTanResultValid); + var r3 = Select(yEqualsZero, r1, r2); + var r4 = Select(rightIsPositive, piDiv4, threePiDiv4); + var r5 = Select(xEqualsInfinity, r4, piDiv2); + var result = Select(yEqualsInfinity, r5, r3); + aTanResultValid = CompareEqual(result.AsInt32(), aTanResultValid.AsInt32()).AsSingle(); var v = Divide(left, right); var r0 = ATan(v); - r1 = Select(pi, SingleConstants.NegativeZero, rightIsPositive); + r1 = Select(rightIsPositive, SingleConstants.NegativeZero, pi); r2 = Add(r0, r1); - return Select(result, r2, aTanResultValid); + return Select(aTanResultValid, r2, result); } return SoftwareFallback(left, right); @@ -530,13 +530,13 @@ public static Vector128 ATan(Vector128 vector) var abs = Abs(vector); var inv = Divide(SingleConstants.One, vector); var comp = CompareGreaterThan(vector, SingleConstants.One); - var sign = Select(SingleConstants.NegativeOne, SingleConstants.One, comp); + var sign = Select(comp, SingleConstants.One, SingleConstants.NegativeOne); comp = CompareLessThanOrEqual(abs, SingleConstants.One); - sign = Select(sign, SingleConstants.Zero, comp); + sign = Select(comp, SingleConstants.Zero, sign); - var vec = Select(inv, vector, comp); + var vec = Select(comp, vector, inv); var vecSquared = Square(vec); @@ -578,7 +578,7 @@ public static Vector128 ATan(Vector128 vector) var result1 = FastMultiplySubtract(sign, SingleConstants.PiDiv2, result); comp = CompareEqual(sign, SingleConstants.Zero); - result = Select(result1, result, comp); + result = Select(comp, result, result1); return result; } } diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/VectorOperations.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/VectorOperations.cs index 169470e..4152269 100644 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/VectorOperations.cs +++ b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/VectorOperations.cs @@ -55,15 +55,15 @@ public static Vector128 NormalizeApprox4D(Vector128 vector) [MethodImpl(MaxOpt)] public static Vector128 Length2D(Vector128 vector) - => Sqrt(DotProduct2D(vector, vector)); + => Sqrt(Dot2D(vector, vector)); [MethodImpl(MaxOpt)] public static Vector128 Length3D(Vector128 vector) - => Sqrt(DotProduct3D(vector, vector)); + => Sqrt(Dot3D(vector, vector)); [MethodImpl(MaxOpt)] public static Vector128 Length4D(Vector128 vector) - => Sqrt(DotProduct4D(vector, vector)); + => Sqrt(Dot4D(vector, vector)); #endregion @@ -71,15 +71,15 @@ public static Vector128 Length4D(Vector128 vector) [MethodImpl(MaxOpt)] public static Vector128 LengthSquared2D(Vector128 vector) - => DotProduct2D(vector, vector); + => Dot2D(vector, vector); [MethodImpl(MaxOpt)] public static Vector128 LengthSquared3D(Vector128 vector) - => DotProduct3D(vector, vector); + => Dot3D(vector, vector); [MethodImpl(MaxOpt)] public static Vector128 LengthSquared4D(Vector128 vector) - => DotProduct4D(vector, vector); + => Dot4D(vector, vector); #endregion @@ -87,7 +87,7 @@ public static Vector128 LengthSquared4D(Vector128 vector) [MethodImpl(MaxOpt)] - public static Vector128 DotProduct2D(Vector128 left, Vector128 right) + public static Vector128 Dot2D(Vector128 left, Vector128 right) { // SSE4.1 has a native dot product instruction, dpps if (Sse41.IsSupported) @@ -125,12 +125,12 @@ public static Vector128 DotProduct2D(Vector128 left, Vector128 DotProduct3D(Vector128 left, Vector128 right) + public static Vector128 Dot3D(Vector128 left, Vector128 right) { // SSE4.1 has a native dot product instruction, dpps if (Sse41.IsSupported) @@ -170,12 +170,12 @@ public static Vector128 DotProduct3D(Vector128 left, Vector128 DotProduct4D(Vector128 left, Vector128 right) + public static Vector128 Dot4D(Vector128 left, Vector128 right) { if (Sse41.IsSupported) { @@ -206,7 +206,7 @@ public static Vector128 DotProduct4D(Vector128 left, Vector128 DotProduct4D(Vector128 left, Vector128 CrossProduct2D(Vector128 left, Vector128 right) + public static Vector128 Cross2D(Vector128 left, Vector128 right) { /* Cross product of A(x, y, _, _) and B(x, y, _, _) is * 'E = (Ax * By) - (Ay * Bx)' @@ -241,12 +241,12 @@ public static Vector128 CrossProduct2D(Vector128 left, Vector128 CrossProduct3D(Vector128 left, Vector128 right) + public static Vector128 Cross3D(Vector128 left, Vector128 right) { if (Sse.IsSupported) { @@ -293,12 +293,12 @@ public static Vector128 CrossProduct3D(Vector128 left, Vector128 CrossProduct4D(Vector128 one, Vector128 two, Vector128 three) + public static Vector128 Cross4D(Vector128 one, Vector128 two, Vector128 three) { if (Sse.IsSupported) { @@ -351,12 +351,12 @@ public static Vector128 CrossProduct4D(Vector128 one, Vector128 CrossProduct4D_Software(Vector128 one, Vector128 two, Vector128 three) - => SoftwareFallbacks.CrossProduct4D_Software(one, two, three); + public static Vector128 Cross4D_Software(Vector128 one, Vector128 two, Vector128 three) + => SoftwareFallbacks.Cross4D_Software(one, two, three); #endregion @@ -429,7 +429,7 @@ public static Vector128 Lerp(Vector128 from, Vector128 to, public static Vector128 Reflect2D(Vector128 incident, Vector128 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector128 tmp = DotProduct2D(incident, normal); + Vector128 tmp = Dot2D(incident, normal); tmp = Add(tmp, tmp); tmp = Multiply(tmp, normal); return Subtract(incident, tmp); @@ -438,7 +438,7 @@ public static Vector128 Reflect2D(Vector128 incident, Vector128 Reflect3D(Vector128 incident, Vector128 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector128 tmp = DotProduct3D(incident, normal); + Vector128 tmp = Dot3D(incident, normal); tmp = Add(tmp, tmp); tmp = Multiply(tmp, normal); return Subtract(incident, tmp); @@ -447,7 +447,7 @@ public static Vector128 Reflect3D(Vector128 incident, Vector128 Reflect4D(Vector128 incident, Vector128 normal) { // reflection = incident - (2 * DotProduct(incident, normal)) * normal - Vector128 tmp = DotProduct4D(incident, normal); + Vector128 tmp = Dot4D(incident, normal); tmp = Add(tmp, tmp); tmp = Multiply(tmp, normal); return Subtract(incident, tmp); diff --git a/tests/MathSharp.UnitTests/MathSharp.UnitTests.csproj b/tests/MathSharp.UnitTests/MathSharp.UnitTests.csproj index 0c18bf7..2beaab7 100644 --- a/tests/MathSharp.UnitTests/MathSharp.UnitTests.csproj +++ b/tests/MathSharp.UnitTests/MathSharp.UnitTests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.0 + netcoreapp3.1 false diff --git a/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/CrossProduct.cs b/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/CrossProduct.cs index f5b693e..150d6ad 100644 --- a/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/CrossProduct.cs +++ b/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/CrossProduct.cs @@ -31,7 +31,7 @@ public static IEnumerable Data(VectorDimensions dimension) { var v1 = (Vector256)set[0]; var v2 = (Vector256)set[1]; - set[3] = TestHelpers.ByValToSlowVector2d(SoftwareFallbacks.CrossProduct2D_Software(v1, v2)); + set[3] = TestHelpers.ByValToSlowVector2d(SoftwareFallbacks.Cross2D_Software(v1, v2)); break; } @@ -39,7 +39,7 @@ public static IEnumerable Data(VectorDimensions dimension) { var v1 = (Vector256)set[0]; var v2 = (Vector256)set[1]; - set[3] = TestHelpers.ByValToSlowVector3d(SoftwareFallbacks.CrossProduct3D_Software(v1, v2)); + set[3] = TestHelpers.ByValToSlowVector3d(SoftwareFallbacks.Cross3D_Software(v1, v2)); break; } @@ -48,7 +48,7 @@ public static IEnumerable Data(VectorDimensions dimension) var v1 = (Vector256)set[0]; var v2 = (Vector256)set[1]; var v3 = (Vector256)set[2]; - set[3] = TestHelpers.ByValToSlowVector4d(SoftwareFallbacks.CrossProduct4D_Software(v1, v2, v3)); + set[3] = TestHelpers.ByValToSlowVector4d(SoftwareFallbacks.Cross4D_Software(v1, v2, v3)); break; } @@ -64,18 +64,18 @@ public static IEnumerable Data(VectorDimensions dimension) [Theory] [MemberData(nameof(Data), VectorDimensions.V2D)] - public static void CrossProduct2D_Theory(Vector256 left, Vector256 right, Vector256 discard, Vector2d expected) + public static void Cross2D_Theory(Vector256 left, Vector256 right, Vector256 discard, Vector2d expected) { - Vector256 result = Vector.CrossProduct2D(left, right); + Vector256 result = Vector.Cross2D(left, right); Assert.True(TestHelpers.AreEqual(expected, result), $"Expected {expected}, got {result}"); } [Theory] [MemberData(nameof(Data), VectorDimensions.V3D)] - public static void CrossProduct3D_Theory(Vector256 left, Vector256 right, Vector256 discard, Vector3d expected) + public static void Cross3D_Theory(Vector256 left, Vector256 right, Vector256 discard, Vector3d expected) { - Vector256 result = Vector.CrossProduct3D(left, right); + Vector256 result = Vector.Cross3D(left, right); Assert.True(TestHelpers.AreEqual(expected, result), $"Expected {expected}, got {result}"); } @@ -84,9 +84,9 @@ public static void CrossProduct3D_Theory(Vector256 left, Vector256 left, Vector256 right, Vector256 third, Vector4d expected) + public static void Cross4D_Theory(Vector256 left, Vector256 right, Vector256 third, Vector4d expected) { - Vector256 result = Vector.CrossProduct4D(left, right, third); + Vector256 result = Vector.Cross4D(left, right, third); Assert.True(TestHelpers.AreEqual(expected, result), $"Expected {expected}, got {result}"); } diff --git a/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/DotProduct.cs b/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/DotProduct.cs index 055c1d5..458c2bd 100644 --- a/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/DotProduct.cs +++ b/tests/MathSharp.UnitTests/VectorTests/VectorDouble/VectorOperations/DotProduct.cs @@ -64,27 +64,27 @@ public static IEnumerable Data(VectorDimensions dimension) [Theory] [MemberData(nameof(Data), VectorDimensions.V2D)] - public static void DotProduct2D_Theory(Vector256 left, Vector256 right, Vector2d expected) + public static void Dot2D_Theory(Vector256 left, Vector256 right, Vector2d expected) { - Vector256 result = Vector.DotProduct2D(left, right); + Vector256 result = Vector.Dot2D(left, right); Assert.True(TestHelpers.AreEqual(expected, result), $"Expected {expected}, got {result}"); } [Theory] [MemberData(nameof(Data), VectorDimensions.V3D)] - public static void DotProduct3D_Theory(Vector256 left, Vector256 right, Vector3d expected) + public static void Dot3D_Theory(Vector256 left, Vector256 right, Vector3d expected) { - Vector256 result = Vector.DotProduct3D(left, right); + Vector256 result = Vector.Dot3D(left, right); Assert.True(TestHelpers.AreEqual(expected, result), $"Expected {expected}, got {result}"); } [Theory] [MemberData(nameof(Data), VectorDimensions.V4D)] - public static void DotProduct4D_Theory(Vector256 left, Vector256 right, Vector4d expected) + public static void Dot4D_Theory(Vector256 left, Vector256 right, Vector4d expected) { - Vector256 result = Vector.DotProduct4D(left, right); + Vector256 result = Vector.Dot4D(left, right); Assert.True(TestHelpers.AreEqual(expected, result), $"Expected {expected}, got {result}"); } diff --git a/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/CrossProduct.cs b/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/CrossProduct.cs index 653be3d..e053ab9 100644 --- a/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/CrossProduct.cs +++ b/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/CrossProduct.cs @@ -32,7 +32,7 @@ public static IEnumerable Data(VectorDimensions dimension) { var v1 = (Vector128)set[0]; var v2 = (Vector128)set[1]; - set[3] = ByValToSlowVector2(SoftwareFallbacks.CrossProduct2D_Software(v1, v2)); + set[3] = ByValToSlowVector2(SoftwareFallbacks.Cross2D_Software(v1, v2)); break; } @@ -40,7 +40,7 @@ public static IEnumerable Data(VectorDimensions dimension) { var v1 = (Vector128)set[0]; var v2 = (Vector128)set[1]; - Vector128 res = SoftwareFallbacks.CrossProduct3D_Software(v1, v2); + Vector128 res = SoftwareFallbacks.Cross3D_Software(v1, v2); set[3] = ByValToSlowVector3(res); Vector3 correct = Vector3.Cross(ByValToSlowVector3(v1), ByValToSlowVector3(v2)); Assert.True(AreEqual(Vector3.Cross(ByValToSlowVector3(v1), ByValToSlowVector3(v2)), res), $"Expected {correct}, got {res}"); @@ -52,7 +52,7 @@ public static IEnumerable Data(VectorDimensions dimension) var v1 = (Vector128)set[0]; var v2 = (Vector128)set[1]; var v3 = (Vector128)set[2]; - set[3] = ByValToSlowVector4(SoftwareFallbacks.CrossProduct4D_Software(v1, v2, v3)); + set[3] = ByValToSlowVector4(SoftwareFallbacks.Cross4D_Software(v1, v2, v3)); break; } @@ -68,18 +68,18 @@ public static IEnumerable Data(VectorDimensions dimension) [Theory] [MemberData(nameof(Data), VectorDimensions.V2D)] - public static void CrossProduct2D_Theory(Vector128 left, Vector128 right, Vector128 discard, Vector2 expected) + public static void Cross2D_Theory(Vector128 left, Vector128 right, Vector128 discard, Vector2 expected) { - Vector128 result = Vector.CrossProduct2D(left, right); + Vector128 result = Vector.Cross2D(left, right); Assert.True(AreEqual(expected, result), $"Expected {expected}, got {result}"); } [Theory] [MemberData(nameof(Data), VectorDimensions.V3D)] - public static void CrossProduct3D_Theory(Vector128 left, Vector128 right, Vector128 discard, Vector3 expected) + public static void Cross3D_Theory(Vector128 left, Vector128 right, Vector128 discard, Vector3 expected) { - Vector128 result = Vector.CrossProduct3D(left, right); + Vector128 result = Vector.Cross3D(left, right); Assert.True(AreEqual(expected, result), $"Expected {expected}, got {result}"); } @@ -88,9 +88,9 @@ public static void CrossProduct3D_Theory(Vector128 left, Vector128 [Theory] [MemberData(nameof(Data), VectorDimensions.V4D)] - public static void CrossProduct4D_Theory(Vector128 left, Vector128 right, Vector128 third, Vector4 expected) + public static void Cross4D_Theory(Vector128 left, Vector128 right, Vector128 third, Vector4 expected) { - Vector128 result = Vector.CrossProduct4D(left, right, third); + Vector128 result = Vector.Cross4D(left, right, third); Assert.True(AreEqual(expected, result), $"Expected {expected}, got {result}"); } diff --git a/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/DotProduct.cs b/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/DotProduct.cs index 4b34d5b..7529bcb 100644 --- a/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/DotProduct.cs +++ b/tests/MathSharp.UnitTests/VectorTests/VectorSingle/VectorOperations/DotProduct.cs @@ -66,27 +66,27 @@ public static IEnumerable Data(VectorDimensions dimension) [Theory] [MemberData(nameof(Data), VectorDimensions.V2D)] - public static void DotProduct2D_Theory(Vector128 left, Vector128 right, Vector2 expected) + public static void Dot2D_Theory(Vector128 left, Vector128 right, Vector2 expected) { - Vector128 result = Vector.DotProduct2D(left, right); + Vector128 result = Vector.Dot2D(left, right); Assert.True(AreEqual(expected, result), $"Expected {expected}, got {result}"); } [Theory] [MemberData(nameof(Data), VectorDimensions.V3D)] - public static void DotProduct3D_Theory(Vector128 left, Vector128 right, Vector3 expected) + public static void Dot3D_Theory(Vector128 left, Vector128 right, Vector3 expected) { - Vector128 result = Vector.DotProduct3D(left, right); + Vector128 result = Vector.Dot3D(left, right); Assert.True(AreEqual(expected, result), $"Expected {expected}, got {result}"); } [Theory] [MemberData(nameof(Data), VectorDimensions.V4D)] - public static void DotProduct4D_Theory(Vector128 left, Vector128 right, Vector4 expected) + public static void Dot4D_Theory(Vector128 left, Vector128 right, Vector4 expected) { - Vector128 result = Vector.DotProduct4D(left, right); + Vector128 result = Vector.Dot4D(left, right); Assert.True(AreEqual(expected, result), $"Expected {expected}, got {result}"); } From 772479cb1349961fecb8ff1785beb3a556f4a2dc Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Oct 2022 22:01:38 +0100 Subject: [PATCH 09/10] Fix build issue --- sources/MathSharp/MathSharp.csproj | 2 +- .../VectorSingle/HwVector.cs | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) delete mode 100644 sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs diff --git a/sources/MathSharp/MathSharp.csproj b/sources/MathSharp/MathSharp.csproj index 75d4fcd..db11e10 100644 --- a/sources/MathSharp/MathSharp.csproj +++ b/sources/MathSharp/MathSharp.csproj @@ -1,6 +1,6 @@  - + netcoreapp3.1 false diff --git a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs b/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs deleted file mode 100644 index 30ec5e8..0000000 --- a/sources/MathSharp/Vector/VectorFloatingPoint/VectorSingle/HwVector.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.Intrinsics; -using System.Text; - -namespace MathSharp.Vector.VectorFloatingPoint.VectorSingle -{ - public readonly struct HwVector - { - private readonly Vector128 Value; - - public static HwVector operator + (HwVector left, HwVector right) - { - return Vector.Add(left, right); - } - } -} From 69672de21f0fdf71c52fd73df7f7c2b8b9527c3e Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Oct 2022 22:06:02 +0100 Subject: [PATCH 10/10] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index fb05cb4..18e8830 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # MathSharp +# Note: As of 2022 MathSharp is not recommended for general use +# Since its inception, the .NET intrinsics and vectors have increased in performance and functionality massively, and they are recommended for any new projects + [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/johnhk) [![Buy Me A Coffee](/assets/buymecoffee.png)](https://www.buymeacoffee.com/johnhk)