diff --git a/docs/articles/Interfaces.md b/docs/articles/Interfaces.md new file mode 100644 index 0000000..cdf91be --- /dev/null +++ b/docs/articles/Interfaces.md @@ -0,0 +1,110 @@ +# Exploring Geometric Interfaces in C# with NetFabric.Numerics + +If you're a C# developer interested in working with geometric types and coordinate systems, the `NetFabric.Numerics` package offers a powerful set of interfaces and data structures. In this article, we'll take a deep dive into the core interfaces provided by the package and explore how they can help you model geometric data efficiently. + +## ICoordinateSystem Interface + +Introducing the `ICoordinateSystem` interface, which plays a key role in providing access to coordinate information within a system. Here's the code snippet: + +```csharp +public interface ICoordinateSystem +{ + IReadOnlyList Coordinates { get; } +} +``` + +The `Coordinates` property returns an `IReadOnlyCollection + : IEquatable, + IEqualityOperators + where TSelf : struct, IGeometricBase? + where TCoordinateSystem : class, ICoordinateSystem +{ + TCoordinateSystem CoordinateSystem { get; } + + object this[int index] { get; } + + static abstract TSelf Zero { get; } + + public static bool IsZero(TSelf value) + => value.Equals(TSelf.Zero); +} +``` + +The definition implies that all geometric objects must be equatable, emeaning that they mus implement the generics version of `Equals` and also must implement all the equality operators. + +They must provide a `CoordinateSystem` property that returns and instance of class (reference type) that implements `ICoordinateSystem`. This allows the dynamic queries in realtime about the coordinate system the geometric object is defined in. + +Having it be a reference type and implement the singleton pattern, makes it more efficient to compare if two geometric object are from the same coordinate system. The equal operator will internally use the `ReferenceEquals`. + + +## Points in Space + +### IPoint Interface + +Building on the `IGeometricBase` interface, the `IPoint` interface is tailored for representing points in a coordinate system. It includes additional capabilities, such as finding the minimum and maximum values for points. Here's the definition of the `IPoint` interface: + +```csharp +namespace NetFabric.Numerics; + +public interface IPoint + : IGeometricBase, + IMinMaxValue + where TSelf : struct, IPoint? + where TCoordinateSystem : class, ICoordinateSystem +{ +} +``` + +The `IPoint` interface adds the ability to find the minimum and maximum values for points, which can be particularly useful in spatial applications. + +## Vectors in Space + +### IVector Interface + +Lastly, the `IVector` interface is designed for modeling vectors in a coordinate system. It encompasses a wide range of mathematical operations and comparisons. Here's how it's defined: + +```csharp +namespace NetFabric.Numerics; + +public interface IVector + : IGeometricBase, + IComparable, + IComparable, + IComparisonOperators, + IAdditiveIdentity, + IUnaryPlusOperators, + IAdditionOperators, + IUnaryNegationOperators, + ISubtractionOperators, + IMultiplyOperators, + IDivisionOperators, + IMinMaxValue + where TSelf : struct, IVector? + where TCoordinateSystem : class, ICoordinateSystem + where T : struct, INumber, IMinMaxValue +{ +} +``` + +The `IVector` interface is a versatile tool for working with vectors. It supports operations such as addition, subtraction, unary negation, and scalar multiplication, making it an essential foundation for vector mathematics. + +## Wrapping Up + +The `NetFabric.Numerics` package provides a robust set of interfaces for modeling geometric data and coordinate systems in C#. By adhering to these interfaces and following the coding guidelines you've specified, you can build efficient and maintainable code for geometric calculations. Whether you're working on 2D or 3D graphics, physics simulations, or any other domain involving spatial data, these interfaces are a valuable resource for your C# projects. Happy coding! + +*Note: The code snippets provided in this article adhere to the coding guidelines specified, using up-to-date C# syntax and providing well-structured inline documentation where relevant.* \ No newline at end of file diff --git a/src/NetFabric.Numerics.Angle.UnitTests/NetFabric.Numerics.Angle.UnitTests.csproj b/src/NetFabric.Numerics.Angle.UnitTests/NetFabric.Numerics.Angle.UnitTests.csproj index d7c97dc..9b87103 100644 --- a/src/NetFabric.Numerics.Angle.UnitTests/NetFabric.Numerics.Angle.UnitTests.csproj +++ b/src/NetFabric.Numerics.Angle.UnitTests/NetFabric.Numerics.Angle.UnitTests.csproj @@ -1,7 +1,7 @@ - net7.0; net8.0 + net8.0 false true diff --git a/src/NetFabric.Numerics.Angle/NetFabric.Numerics.Angle.csproj b/src/NetFabric.Numerics.Angle/NetFabric.Numerics.Angle.csproj index 4e6f8b7..a6971ac 100644 --- a/src/NetFabric.Numerics.Angle/NetFabric.Numerics.Angle.csproj +++ b/src/NetFabric.Numerics.Angle/NetFabric.Numerics.Angle.csproj @@ -2,7 +2,7 @@ NetFabric.Numerics.Angle - net7.0; net8.0 + net8.0 true A strongly-typed representation of an angle. diff --git a/src/NetFabric.Numerics.Benchmarks/AdditionBenchmarks.cs b/src/NetFabric.Numerics.Benchmarks/AdditionBenchmarks.cs index 783af9f..1da29b8 100644 --- a/src/NetFabric.Numerics.Benchmarks/AdditionBenchmarks.cs +++ b/src/NetFabric.Numerics.Benchmarks/AdditionBenchmarks.cs @@ -14,9 +14,6 @@ public class AdditionBenchmarks Rectangular2D.Vector[]? rectangular2_long; Rectangular2D.Vector[]? rectangular2_float; Rectangular2D.Vector[]? rectangular2_double; - - Polar.Vector[]? polar_float; - Polar.Vector[]? polar_double; [Params(10_000)] public int Count { get; set; } @@ -31,9 +28,6 @@ public void GlobalSetup() rectangular2_float = GetEnumerable(Count).Select<(int x, int y), Rectangular2D.Vector>(item => new(item.x, item.y)).ToArray(); rectangular2_double = GetEnumerable(Count).Select<(int x, int y), Rectangular2D.Vector>(item => new(item.x, item.y)).ToArray(); - polar_float = GetEnumerable(Count).Select<(int x, int y), Polar.Vector>(item => new(item.x, new(item.y))).ToArray(); - polar_double = GetEnumerable(Count).Select<(int x, int y), Polar.Vector>(item => new(item.x, new(item.y))).ToArray(); - static IEnumerable<(int x, int y)> GetEnumerable(int count) { var random = new Random(42); @@ -64,15 +58,15 @@ public Rectangular2D.Vector Rectangular2D_Long() return sum; } - [BenchmarkCategory("Float")] - [Benchmark(Baseline = true)] - public Vector2 Vector2() - { - var sum = System.Numerics.Vector2.Zero; - foreach (var item in vector2!) - sum += item; - return sum; - } + // [BenchmarkCategory("Float")] + // [Benchmark(Baseline = true)] + // public Vector2 Vector2() + // { + // var sum = System.Numerics.Vector2.Zero; + // foreach (var item in vector2!) + // sum += item; + // return sum; + // } [BenchmarkCategory("Float")] [Benchmark] @@ -84,16 +78,6 @@ public Rectangular2D.Vector Rectangular2D_Float() return sum; } - [BenchmarkCategory("Float")] - [Benchmark] - public Polar.Vector Polar_Float() - { - var sum = Polar.Vector.Zero; - foreach (var item in polar_float!) - sum += item; - return sum; - } - [BenchmarkCategory("Double")] [Benchmark(Baseline = true)] public Rectangular2D.Vector Rectangular2D_Double() @@ -103,15 +87,4 @@ public Rectangular2D.Vector Rectangular2D_Double() sum += item; return sum; } - - [BenchmarkCategory("Double")] - [Benchmark] - public Polar.Vector Polar_Double() - { - var sum = Polar.Vector.Zero; - foreach (var item in polar_double!) - sum += item; - return sum; - } - } \ No newline at end of file diff --git a/src/NetFabric.Numerics.Benchmarks/AdditionVectorDoubleBenchmark.cs b/src/NetFabric.Numerics.Benchmarks/AdditionVectorDoubleBenchmark.cs deleted file mode 100644 index 5ce12f3..0000000 --- a/src/NetFabric.Numerics.Benchmarks/AdditionVectorDoubleBenchmark.cs +++ /dev/null @@ -1,69 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Configs; -using NetFabric.Numerics; - -namespace NetFabric.Numerics.Benchmarks; - -[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] -[CategoriesColumn] -public class AdditionVectorDoubleBenchmark -{ - Vector2[]? vectors2; - Vector3[]? vectors3; - Vector4[]? vectors4; - - [Params(1_000)] - public int Count { get; set; } - - [GlobalSetup] - public void GlobalSetup() - { - var random = new Random(42); - - vectors2 = new Vector2[Count]; - vectors3 = new Vector3[Count]; - vectors4 = new Vector4[Count]; - - for (var index = 0; index < Count; index++) - { - var x = random.Next(); - var y = random.Next(); - var z = random.Next(); - var w = random.Next(); - - vectors2[index] = new Vector2(x, y); - vectors3[index] = new Vector3(x, y, z); - vectors4[index] = new Vector4(x, y, z, w); - } - } - - [BenchmarkCategory("Vector2")] - [Benchmark] - public Vector2 NetFabricVector2() - { - var sum = Vector2.Zero; - foreach (var value in vectors2!) - sum += value; - return sum; - } - - [BenchmarkCategory("Vector3")] - [Benchmark] - public Vector3 NetFabricVector3() - { - var sum = Vector3.Zero; - foreach (var value in vectors3!) - sum += value; - return sum; - } - - [BenchmarkCategory("Vector4")] - [Benchmark] - public Vector4 NetFabricVector4() - { - var sum = Vector4.Zero; - foreach (var value in vectors4!) - sum += value; - return sum; - } -} \ No newline at end of file diff --git a/src/NetFabric.Numerics.Benchmarks/AdditionVectorFloatBenchmark.cs b/src/NetFabric.Numerics.Benchmarks/AdditionVectorFloatBenchmark.cs deleted file mode 100644 index 2dfaed4..0000000 --- a/src/NetFabric.Numerics.Benchmarks/AdditionVectorFloatBenchmark.cs +++ /dev/null @@ -1,113 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Configs; - -namespace NetFabric.Numerics.Benchmarks; - -[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] -[CategoriesColumn] -public class AdditionVectorFloatBenchmark -{ - NetFabric.Numerics.Vector2[]? netfabricVectors2; - System.Numerics.Vector2[]? systemVectors2; - - NetFabric.Numerics.Vector3[]? netfabricVectors3; - System.Numerics.Vector3[]? systemVectors3; - - NetFabric.Numerics.Vector4[]? netfabricVectors4; - System.Numerics.Vector4[]? systemVectors4; - - [Params(1_000)] - public int Count { get; set; } - - [GlobalSetup] - public void GlobalSetup() - { - var random = new Random(42); - - netfabricVectors2 = new NetFabric.Numerics.Vector2[Count]; - systemVectors2 = new System.Numerics.Vector2[Count]; - - netfabricVectors3 = new NetFabric.Numerics.Vector3[Count]; - systemVectors3 = new System.Numerics.Vector3[Count]; - - netfabricVectors4 = new NetFabric.Numerics.Vector4[Count]; - systemVectors4 = new System.Numerics.Vector4[Count]; - - for (var index = 0; index < Count; index++) - { - var x = random.Next(); - var y = random.Next(); - var z = random.Next(); - var w = random.Next(); - - netfabricVectors2[index] = new NetFabric.Numerics.Vector2(x, y); - systemVectors2[index] = new System.Numerics.Vector2(x, y); - - netfabricVectors3[index] = new NetFabric.Numerics.Vector3(x, y, z); - systemVectors3[index] = new System.Numerics.Vector3(x, y, z); - - netfabricVectors4[index] = new NetFabric.Numerics.Vector4(x, y, z, w); - systemVectors4[index] = new System.Numerics.Vector4(x, y, z, w); - } - } - - [BenchmarkCategory("Vector2")] - [Benchmark(Baseline = true)] - public System.Numerics.Vector2 SystemVector2() - { - var sum = System.Numerics.Vector2.Zero; - foreach (var value in systemVectors2!) - sum += value; - return sum; - } - - [BenchmarkCategory("Vector2")] - [Benchmark] - public NetFabric.Numerics.Vector2 NetFabricVector2() - { - var sum = NetFabric.Numerics.Vector2.Zero; - foreach (var value in netfabricVectors2!) - sum += value; - return sum; - } - - [BenchmarkCategory("Vector3")] - [Benchmark(Baseline = true)] - public System.Numerics.Vector3 SystemVector3() - { - var sum = System.Numerics.Vector3.Zero; - foreach (var value in systemVectors3!) - sum += value; - return sum; - } - - [BenchmarkCategory("Vector3")] - [Benchmark] - public NetFabric.Numerics.Vector3 NetFabricVector3() - { - var sum = NetFabric.Numerics.Vector3.Zero; - foreach (var value in netfabricVectors3!) - sum += value; - return sum; - } - - [BenchmarkCategory("Vector4")] - [Benchmark(Baseline = true)] - public System.Numerics.Vector4 SystemVector4() - { - var sum = System.Numerics.Vector4.Zero; - foreach (var value in systemVectors4!) - sum += value; - return sum; - } - - [BenchmarkCategory("Vector4")] - [Benchmark] - public NetFabric.Numerics.Vector4 NetFabricVector4() - { - var sum = NetFabric.Numerics.Vector4.Zero; - foreach (var value in netfabricVectors4!) - sum += value; - return sum; - } -} \ No newline at end of file diff --git a/src/NetFabric.Numerics.Benchmarks/EqualsVectorFloatBenchmark.cs b/src/NetFabric.Numerics.Benchmarks/EqualsVectorFloatBenchmark.cs deleted file mode 100644 index 477ef55..0000000 --- a/src/NetFabric.Numerics.Benchmarks/EqualsVectorFloatBenchmark.cs +++ /dev/null @@ -1,135 +0,0 @@ -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Configs; -using System.Numerics; - -namespace NetFabric.Numerics.Benchmarks; - -[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] -[CategoriesColumn] -public class EqualsVectorFloatBenchmark -{ - NetFabric.Numerics.Vector2[]? netfabricVector2; - System.Numerics.Vector2[]? systemVector2s; - - NetFabric.Numerics.Vector3[]? netfabricVector3; - System.Numerics.Vector3[]? systemVector3s; - - NetFabric.Numerics.Vector4[]? netfabricVector4; - System.Numerics.Vector4[]? systemVector4s; - - [Params(1_000)] - public int Count { get; set; } - - [GlobalSetup] - public void GlobalSetup() - { - var random = new Random(42); - - netfabricVector2 = new NetFabric.Numerics.Vector2[Count]; - systemVector2s = new System.Numerics.Vector2[Count]; - - netfabricVector3 = new NetFabric.Numerics.Vector3[Count]; - systemVector3s = new System.Numerics.Vector3[Count]; - - netfabricVector4 = new NetFabric.Numerics.Vector4[Count]; - systemVector4s = new System.Numerics.Vector4[Count]; - - for (var index = 0; index < Count; index++) - { - var x = random.Next(); - var y = random.Next(); - var z = random.Next(); - var w = random.Next(); - - netfabricVector2[index] = new NetFabric.Numerics.Vector2(x, y); - systemVector2s[index] = new System.Numerics.Vector2(x, y); - - netfabricVector3[index] = new NetFabric.Numerics.Vector3(x, y, z); - systemVector3s[index] = new System.Numerics.Vector3(x, y, z); - - netfabricVector4[index] = new NetFabric.Numerics.Vector4(x, y, z, w); - systemVector4s[index] = new System.Numerics.Vector4(x, y, z, w); - } - } - - [BenchmarkCategory("Vector2")] - [Benchmark(Baseline = true)] - public bool SystemVector2() - => Contains(systemVector2s!, System.Numerics.Vector2.Zero); - - [BenchmarkCategory("Vector2")] - [Benchmark] - public bool NetFabricVector2() - => Contains(netfabricVector2!, NetFabric.Numerics.Vector2.Zero); - - [BenchmarkCategory("Vector3")] - [Benchmark(Baseline = true)] - public bool SystemVector3() - => Contains(systemVector3s!, System.Numerics.Vector3.Zero); - - [BenchmarkCategory("Vector3")] - [Benchmark] - public bool NetFabricVector3() - => Contains(netfabricVector3!, NetFabric.Numerics.Vector3.Zero); - - [BenchmarkCategory("Vector4")] - [Benchmark(Baseline = true)] - public bool SystemVector4() - => Contains(systemVector4s!, System.Numerics.Vector4.Zero); - - [BenchmarkCategory("Vector4")] - [Benchmark] - public bool NetFabricVector4() - => Contains(netfabricVector4!, NetFabric.Numerics.Vector4.Zero); - - static bool Contains(System.Numerics.Vector2[] vectors, System.Numerics.Vector2 item) - { - foreach (var value in vectors) - if (value.Equals(item)) - return true; - return false; - } - - static bool Contains(Vector2[] vectors, Vector2 item) - where T : struct, INumber, IMinMaxValue - { - foreach (var value in vectors) - if (value.Equals(item)) - return true; - return false; - } - - static bool Contains(System.Numerics.Vector3[] vectors, System.Numerics.Vector3 item) - { - foreach (var value in vectors) - if (value.Equals(item)) - return true; - return false; - } - - static bool Contains(Vector3[] vectors, Vector3 item) - where T : struct, INumber, IMinMaxValue - { - foreach (var value in vectors) - if (value.Equals(item)) - return true; - return false; - } - - static bool Contains(System.Numerics.Vector4[] vectors, System.Numerics.Vector4 item) - { - foreach (var value in vectors) - if (value.Equals(item)) - return true; - return false; - } - - static bool Contains(Vector4[] vectors, Vector4 item) - where T : struct, INumber, IMinMaxValue - { - foreach (var value in vectors) - if (value.Equals(item)) - return true; - return false; - } -} \ No newline at end of file diff --git a/src/NetFabric.Numerics.Benchmarks/NetFabric.Numerics.Benchmarks.csproj b/src/NetFabric.Numerics.Benchmarks/NetFabric.Numerics.Benchmarks.csproj index 4027b47..a847842 100644 --- a/src/NetFabric.Numerics.Benchmarks/NetFabric.Numerics.Benchmarks.csproj +++ b/src/NetFabric.Numerics.Benchmarks/NetFabric.Numerics.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 false NetFabric.Numerics.Benchmarks diff --git a/src/NetFabric.Numerics.Benchmarks/Program.cs b/src/NetFabric.Numerics.Benchmarks/Program.cs index 8f2f86a..2c29333 100644 --- a/src/NetFabric.Numerics.Benchmarks/Program.cs +++ b/src/NetFabric.Numerics.Benchmarks/Program.cs @@ -9,18 +9,6 @@ using Perfolizer.Horology; using System.Runtime.Intrinsics; -var net70 = Job.Default - .WithRuntime(CoreRuntime.Core70) - .WithWarmupCount(1) - .WithIterationTime(TimeInterval.FromSeconds(0.25)) - .WithMaxIterationCount(20); - -var net80 = Job.Default - .WithRuntime(CoreRuntime.Core80) - .WithWarmupCount(1) - .WithIterationTime(TimeInterval.FromSeconds(0.25)) - .WithMaxIterationCount(20); - var config = DefaultConfig.Instance .WithSummaryStyle(SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend)) .HideColumns(Column.EnvironmentVariables, Column.RatioSD, Column.Error) @@ -28,23 +16,27 @@ // .AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig // (exportGithubMarkdown: true, printInstructionAddresses: false))) .AddExporter(MarkdownExporter.GitHub) - .AddJob(net70.WithEnvironmentVariable("DOTNET_EnableHWIntrinsic", "0").WithId(".NET 7 Scalar").AsBaseline()) - .AddJob(net80.WithEnvironmentVariable("DOTNET_EnableHWIntrinsic", "0").WithId(".NET 8 Scalar")); + .AddJob(Job.Default.WithId("Scalar") + .WithEnvironmentVariable("DOTNET_EnableHWIntrinsic", "0") + .AsBaseline()); +if (Vector128.IsHardwareAccelerated) +{ + config = config + .AddJob(Job.Default.WithId("Vector128") + .WithEnvironmentVariable("DOTNET_EnableAVX2", "0") + .WithEnvironmentVariable("DOTNET_EnableAVX512F", "0")); +} if (Vector256.IsHardwareAccelerated) { config = config - .AddJob(net70.WithId(".NET 7 Vector256")) - .AddJob(net80.WithId(".NET 8 Vector256")) - .AddJob(net70.WithEnvironmentVariable("DOTNET_EnableAVX2", "0").WithId(".NET 7 Vector128")) - .AddJob(net80.WithEnvironmentVariable("DOTNET_EnableAVX2", "0").WithId(".NET 8 Vector128")); - + .AddJob(Job.Default.WithId("Vector256") + .WithEnvironmentVariable("DOTNET_EnableAVX512F", "0")); } -else if (Vector128.IsHardwareAccelerated) +if (Vector512.IsHardwareAccelerated) { config = config - .AddJob(net70.WithId(".NET 7 Vector128")) - .AddJob(net80.WithId(".NET 8 Vector128")); + .AddJob(Job.Default.WithId("Vector512")); } BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); \ No newline at end of file diff --git a/src/NetFabric.Numerics.Geodesy.UnitTests/NetFabric.Numerics.Geodesy.UnitTests.csproj b/src/NetFabric.Numerics.Geodesy.UnitTests/NetFabric.Numerics.Geodesy.UnitTests.csproj index 80347b5..aae53b0 100644 --- a/src/NetFabric.Numerics.Geodesy.UnitTests/NetFabric.Numerics.Geodesy.UnitTests.csproj +++ b/src/NetFabric.Numerics.Geodesy.UnitTests/NetFabric.Numerics.Geodesy.UnitTests.csproj @@ -1,7 +1,7 @@  - net7.0; net8.0 + net8.0 false true diff --git a/src/NetFabric.Numerics.Geodesy/NetFabric.Numerics.Geodesy.csproj b/src/NetFabric.Numerics.Geodesy/NetFabric.Numerics.Geodesy.csproj index 47175f0..ca30c02 100644 --- a/src/NetFabric.Numerics.Geodesy/NetFabric.Numerics.Geodesy.csproj +++ b/src/NetFabric.Numerics.Geodesy/NetFabric.Numerics.Geodesy.csproj @@ -2,7 +2,7 @@ NetFabric.Numerics.Geodesy - net7.0 + net8.0 true 1.0.0-beta07 diff --git a/src/NetFabric.Numerics.UnitTests/NetFabric.Numerics.UnitTests.csproj b/src/NetFabric.Numerics.UnitTests/NetFabric.Numerics.UnitTests.csproj index 20e5d78..e9714c1 100644 --- a/src/NetFabric.Numerics.UnitTests/NetFabric.Numerics.UnitTests.csproj +++ b/src/NetFabric.Numerics.UnitTests/NetFabric.Numerics.UnitTests.csproj @@ -1,7 +1,7 @@ - net7.0; net8.0 + net8.0 false true diff --git a/src/NetFabric.Numerics/NetFabric.Numerics.csproj b/src/NetFabric.Numerics/NetFabric.Numerics.csproj index db4e582..2257074 100644 --- a/src/NetFabric.Numerics/NetFabric.Numerics.csproj +++ b/src/NetFabric.Numerics/NetFabric.Numerics.csproj @@ -2,7 +2,7 @@ NetFabric.Numerics - net7.0; net8.0 + net8.0 true 1.0.0-beta08 diff --git a/src/NetFabric.Numerics/Rectangular2D/Vector.cs b/src/NetFabric.Numerics/Rectangular2D/Vector.cs index 3f3c041..e6f09b5 100644 --- a/src/NetFabric.Numerics/Rectangular2D/Vector.cs +++ b/src/NetFabric.Numerics/Rectangular2D/Vector.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Runtime.Intrinsics; namespace NetFabric.Numerics.Rectangular2D; @@ -515,7 +516,33 @@ public static Vector Negate(in Vector right) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector Add(in Vector left, in Vector right) where T : struct, INumber, IMinMaxValue - => new(left.X + right.X, left.Y + right.Y); + { + if(Vector128.IsHardwareAccelerated) + { + if (typeof(T) == typeof(double)) + { + var vectorLeft = Unsafe.BitCast, Vector128>(left); + var vectorRight = Unsafe.BitCast, Vector128>(right); + return Unsafe.BitCast, Vector>(Vector128.Add(vectorLeft, vectorRight)); + } + + if (typeof(T) == typeof(long)) + { + var vectorLeft = Unsafe.BitCast, Vector128>(left); + var vectorRight = Unsafe.BitCast, Vector128>(right); + return Unsafe.BitCast, Vector>(Vector128.Add(vectorLeft, vectorRight)); + } + + if (typeof(T) == typeof(ulong)) + { + var vectorLeft = Unsafe.BitCast, Vector128>(left); + var vectorRight = Unsafe.BitCast, Vector128>(right); + return Unsafe.BitCast, Vector>(Vector128.Add(vectorLeft, vectorRight)); + } + } + + return new(left.X + right.X, left.Y + right.Y); + } /// /// Subtracts the second vector from the first vector component-wise and returns the result as a new Vector.