From 990f7663b98ec45bc86e72524acd72e5280d280f Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Mon, 10 Jul 2023 07:26:09 -0400 Subject: [PATCH 1/9] Added IPresets0d. Not huge at all. --- Nerd_STF/Mathematics/Abstract/IPresets0d.cs | 6 +++++ Nerd_STF/Nerd_STF.csproj | 27 +++------------------ 2 files changed, 9 insertions(+), 24 deletions(-) create mode 100644 Nerd_STF/Mathematics/Abstract/IPresets0d.cs diff --git a/Nerd_STF/Mathematics/Abstract/IPresets0d.cs b/Nerd_STF/Mathematics/Abstract/IPresets0d.cs new file mode 100644 index 0000000..1da7e1b --- /dev/null +++ b/Nerd_STF/Mathematics/Abstract/IPresets0d.cs @@ -0,0 +1,6 @@ +namespace Nerd_STF.Mathematics.Abstract; + +public interface IPresets0d where T : IPresets0d +{ + public static abstract T Unit { get; } +} diff --git a/Nerd_STF/Nerd_STF.csproj b/Nerd_STF/Nerd_STF.csproj index ee59f67..ed9ea85 100644 --- a/Nerd_STF/Nerd_STF.csproj +++ b/Nerd_STF/Nerd_STF.csproj @@ -12,35 +12,14 @@ Copyright (c) 2023 That_One_Nerd README.md https://github.com/That-One-Nerd/Nerd_STF - 2.4.0 + 2.5.0 c#;csharp;c sharp;math;mathematics;mathametics;maths;color;rgb;rgba;cmyk;cmyka;hsv;hsva;calculus;linear algebra;linalg;linearalgebra;matrix;matrix2x2;matrix 2x2;matrix3x3;matrix 3x3;matrix4x4;matrix 4x4;matrix multiplication;vector;vector2d;vector3d;vector2;vector3;float2;float3;float4;int2;int3;int4;angle;geometry;vert;line;polygon;triangle;quadrilateral;sphere;circle;number system;numbersystem;complex numbers;complex;2d numbers;2dnumbers;quaternions;4d numbers;4dnumbers - 2.4.0 + 2.4.1 Nerd_STF Nerd_STF MIT Logo Square.png - I've done a pretty good amount of stuff in this update, and I'm pretty proud of it. Good improvement. - -First of all, I've gone and added all of the applicable `Mathf` functions as an extension to the `Equation` delegate. That way if you want to say, calculate the square root of an entire equation, rather than going: -```csharp -Equation result = x => Mathf.Sqrt(equ(x)); -// Where `equ` is an `Equation` that represents the function we want to take the square root of. -``` -you can shorten it down and remove some of the weirdness. -```csharp -Equation result = equ.Sqrt(); -// Where `equ` is an `Equation` that represents the function we want to take the square root of. -``` - -It works for any common function you'd want to apply to an equation. - ---- - -Speaking of math functions (I guess that's the whole update, given the name), I'm now utilizing an implementation of CORDIC I made to calculate all trigonometric functions, hyperbolic trig functions, exponents, and logs. It's quite a neat process, and I could also have it completely wrong, but whatever I have, CORDIC or something else, works wonders, and is considerably faster than some other methods I tried. Of course, it's still nowhere near as fast as the built-in math functions, but they will always be on a whole other level. Maybe in the optimization update I'll bother to improve them, but they work quite well as-is for most use cases. - -I've also implemented taylor series into the `Calculus` class. It's not particularly useful is most cases, so I wouldn't bother. The only time it would be a good idea to use it is if you've got some incredibly slow to calculate equation and want to optimize it. The function will take a long time at first, as it will have to generate second-derivatives and beyond, but afterwards the output equation will just be a simple-to-calculate polynomial (though the approximation gets worse the further you are from the reference point). If you've got an equation that's already fast to calculate, using the taylor series approximation will only be a negative. So take it with a grain of salt. - -That's mostly it. I've fixed some issues/bugs here and there, renamed some small stuff (check the full changelog for more information), removed all the stuff marked obsolete and to be removed in this update, added some more math stuff like prime calculators, and other tiny changes. The next update will be focused on reworking the badly made geometry stuff I did a while back ([Version 2.1](https://github.com/That-One-Nerd/Nerd_STF/releases/tag/v2.1.0)). I know I say this all the time, but version 2.5 should be substantially bigger than this one. I'm going to be reworking the `Polygon` object entirely and will be improving quite a lot of other things in the whole `Nerd_STF.Mathematics.Geometry` namespace. Stay tuned! + DO THIS https://github.com/That-One-Nerd/Nerd_STF False False -- 2.49.0.windows.1 From eeb70604d56b2e0d4e692df5f6497d9c5447ac61 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Mon, 10 Jul 2023 07:36:42 -0400 Subject: [PATCH 2/9] Added setters to the float and int groups. --- Changelog.md | 259 ++++----------------------------- Nerd_STF/Mathematics/Float3.cs | 30 +++- Nerd_STF/Mathematics/Float4.cs | 104 +++++++++++-- Nerd_STF/Mathematics/Int3.cs | 30 +++- Nerd_STF/Mathematics/Int4.cs | 104 +++++++++++-- 5 files changed, 270 insertions(+), 257 deletions(-) diff --git a/Changelog.md b/Changelog.md index 71d4b4b..8a17e79 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,242 +1,39 @@ -# Nerd_STF v2.4.0 (Equations and Numbers) +# Nerd_STF v2.4.1 -I've done a pretty good amount of stuff in this update, and I'm pretty proud of it. Good improvement. - -First of all, I've gone and added all of the applicable `Mathf` functions as an extension to the `Equation` delegate. That way if you want to say, calculate the square root of an entire equation, rather than going: -```csharp -Equation result = x => Mathf.Sqrt(equ(x)); -// Where `equ` is an `Equation` that represents the function we want to take the square root of. -``` -you can shorten it down and remove some of the weirdness. -```csharp -Equation result = equ.Sqrt(); -// Where `equ` is an `Equation` that represents the function we want to take the square root of. -``` - -It works for any common function you'd want to apply to an equation. - ---- - -Speaking of math functions (I guess that's the whole update, given the name), I'm now utilizing an implementation of CORDIC I made to calculate all trigonometric functions, hyperbolic trig functions, exponents, and logs. It's quite a neat process, and I could also have it completely wrong, but whatever I have, CORDIC or something else, works wonders, and is considerably faster than some other methods I tried. Of course, it's still nowhere near as fast as the built-in math functions, but they will always be on a whole other level. Maybe in the optimization update I'll bother to improve them, but they work quite well as-is for most use cases. - -I've also implemented taylor series into the `Calculus` class. It's not particularly useful is most cases, so I wouldn't bother. The only time it would be a good idea to use it is if you've got some incredibly slow to calculate equation and want to optimize it. The function will take a long time at first, as it will have to generate second-derivatives and beyond, but afterwards the output equation will just be a simple-to-calculate polynomial (though the approximation gets worse the further you are from the reference point). If you've got an equation that's already fast to calculate, using the taylor series approximation will only be a negative. So take it with a grain of salt. - -That's mostly it. I've fixed some issues/bugs here and there, renamed some small stuff (check the full changelog for more information), removed all the stuff marked obsolete and to be removed in this update, added some more math stuff like prime calculators, and other tiny changes. The next update will be focused on reworking the badly made geometry stuff I did a while back ([Version 2.1](https://github.com/That-One-Nerd/Nerd_STF/releases/tag/v2.1.0)). I know I say this all the time, but version 2.5 should be substantially bigger than this one. I'm going to be reworking the `Polygon` object entirely and will be improving quite a lot of other things in the whole `Nerd_STF.Mathematics.Geometry` namespace. Stay tuned! +TODO Here's the full changelog: ``` * Nerd_STF - * Exceptions - + BadMethodException - * Extensions - * ConversionExtension - - ToDictionary(IEnumerable>) - * EquationExtension - + ValidNumberTypes - + Absolute(Equation) - + AbsoluteMod(Equation, float) - + ArcCos(Equation) - + ArcCot(Equation) - + ArcCsc(Equation) - + ArcSec(Equation) - + ArcSin(Equation) - + ArcTan(Equation) - + ArcCosh(Equation) - + ArcCoth(Equation) - + ArcCsch(Equation) - + ArcSech(Equation) - + ArcSinh(Equation) - + ArcTanh(Equation) - + Average(Equation, float, float, float) - + Average(Equation, Equation, Equation, float) - + Binomial(Equation, int, float) - + Binomial(Equation, Equation, Equation) - + Cbrt(Equation) - + Ceiling(Equation) - + Clamp(Equation, float, float) - + Clamp(Equation, Equation, Equation) - + Combinations(Equation, int) - + Combinations(Equation, Equation) - + Cos(Equation) - + Cosh(Equation) - + Cot(Equation) - + Coth(Equation) - + Csc(Equation) - + Csch(Equation) - + Divide(Equation, float[]) - + Divide(Equation, Equation[]) - + Factorial(Equation) - + Floor(Equation) - + GetDerivative(Equation, float) - + GetDerivativeAtPoint(Equation, float, float) - + GetIntegral(Equation, float, float, float) - + GetDynamicIntegral(Equation, Equation, Equation, float) - + GetTaylorSeries(Equation, float, int, float) - + GetValues(Equation, float, float, float) - + GradientDescent(Equation, float, float, int, float) - + InverseSqrt(Equation) - + Log(Equation, float) - + Max(Equation, float, float, float) - + Min(Equation, float, float, float) - + Permutations(Equation, int) - + Permutations(Equation, Equation) - + Power(Equation, float) - + Power(Equation, Equation) - + Product(Equation, float[]) - + Product(Equation, Equation[]) - + Root(Equation, float) - + Root(Equation, Equation) - + Round(Equation) - + Sec(Equation) - + Sech(Equation) - + Sin(Equation) - + Sinh(Equation) - + SolveBisection(Equation, float, float, float, float, int) - + SolveEquation(Equation, float, float, float, int) - + SolveNewton(Equation, float, float, float, int) - + Sqrt(Equation) - + Subtract(Equation, float[]) - + Subtract(Equation, Equation[]) - + Sum(Equation, float[]) - + Sum(Equation, Equation[]) - + Tan(Equation) - + Tanh(Equation) - + ZScore(Equation, float[]) - + ZScore(Equation, Equation[]) - + ZScore(Equation, float, float) - + ZScore(Equation, Equation, Equation) - + InvokeMethod(Equation, MethodInfo, object?[]?) - + InvokeMathMethod(Equation, string, object?[]?) - + StringExtension - + Helpers - + CordicHelper - + MathfHelper - + RationalHelper - + UnsafeHelper * Mathematics - * Abstract - = Renamed `IPresets1D` to `IPresets1d` - = Renamed `IPresets2D` to `IPresets2d` - = Renamed `IPresets3D` to `IPresets3d` - = Renamed `IPresets4D` to `IPresets4d` - = Renamed `IShape2D` to `IShape2d` - = Renamed `IShape3D` to `IShape3d` - * NumberSystems - * Complex - - operator >(Complex, Complex) - - operator <(Complex, Complex) - - operator >=(Complex, Complex) - - operator <=(Complex, Complex) - * Quaternion - - Far - - Near - - operator >(Complex, Complex) - - operator <(Complex, Complex) - - operator >=(Complex, Complex) - - operator <=(Complex, Complex) - * Samples - + Fills - * Equations - + FlatLine - + XLine - = Simplified `CosWave` - = Simplified `SinWave` - = Replaced a `readonly` term with a generating field in `CosWave` - = Replaced a `readonly` term with a generating field in `SinWave` - = Replaced a `readonly` term with a generating field in `SawWave` - = Replaced a `readonly` term with a generating field in `SquareWave` - = Replaced a `readonly` term with a generating field in `SgnFill` - = Moved `SgnFill` to `Fills` and renamed it to `SignFill` - * Calculus - + GetTaylorSeries(Equation, float, int, float) - = Fixed a blunder in `GetDerivativeAtPoint(Equation, float, float)` - = Renamed the `stepCount` parameter in `GradientDescent(Equation, float, float, float, float)` to "iterations" and changed its type from `float` to `int` - * Float2 - - Removed the `Obsolete` attribute from `CompareTo(Float2)` - - operator >(Float2, Float2) - - operator <(Float2, Float2) - - operator >=(Float2, Float2) - - operator <=(Float2, Float2) * Float3 - - Removed the `Obsolete` attribute from `CompareTo(Float3)` - - operator >(Float3, Float3) - - operator <(Float3, Float3) - - operator >=(Float3, Float3) - - operator <=(Float3, Float3) + = Added a setter to `XY` + = Added a setter to `XZ` + = Added a setter to `YZ` * Float4 - - Far - - Near - - Removed the `Obsolete` attribute from `CompareTo(Float4)` - - operator >(Float4, Float4) - - operator <(Float4, Float4) - - operator >=(Float4, Float4) - - operator <=(Float4, Float4) - * Int2 - - Removed the `Obsolete` attribute from `CompareTo(Int2)` - - operator >(Int2, Int2) - - operator <(Int2, Int2) - - operator >=(Int2, Int2) - - operator <=(Int2, Int2) + = Added a setter to `XW` + = Added a setter to `XY` + = Added a setter to `XZ` + = Added a setter to `YW` + = Added a setter to `YZ` + = Added a setter to `ZW` + = Added a setter to `XYW` + = Added a setter to `XYZ` + = Added a setter to `XZW` + = Added a setter to `YZW` * Int3 - - Removed the `Obsolete` attribute from `CompareTo(Int3)` - - operator >(Int3, Int3) - - operator <(Int3, Int3) - - operator >=(Int3, Int3) - - operator <=(Int3, Int3) + = Added a setter to `XY` + = Added a setter to `XZ` + = Added a setter to `YZ` * Int4 - - Far - - Deep - - Removed the `Obsolete` attribute from `CompareTo(Int4)` - - operator >(Int4, Int4) - - operator <(Int4, Int4) - - operator >=(Int4, Int4) - - operator <=(Int4, Int4) - * Mathf - + ArcCosh(float) - + ArcCoth(float) - + ArcCsch(float) - + ArcSech(float) - + ArcSinh(float) - + ArcTanh(float) - + ArcTanh2(float, float) - + Cbrt(float) - + Cosh(float) - + Coth(float) - + Csch(float) - + IsPrime(int, PrimeCheckMethod) - + Lerp(float, float, Equation, bool) - + Lerp(Equation, Equation, float, bool) - + Lerp(Equation, Equation, Equation, bool) - + Log(float, float) - + PrimeFactors(int) - + PowerMod(long, long, long) - + Sech(float) - + Sinh(float) - + SharedItems(T[][]) - + SolveBisection(Equation, float, float, float, float, int) - + SolveEquation(Equation, float, float, float, int) - + SolveNewton(Equation, float, float, float, int) - + Tanh(float) - = Improved the `Sqrt(float)` method by using a solution finder - = The `ArcSin(float)` method now uses a solution finder rather than the base math library - = The `Power(float, float)` method now utilizes a custom CORDIC implementation rather than the base math library - + PrimeCheckMethod - + Equation2d - + Rational - + SimplificationMethod - * Miscellaneous - * AssemblyConfig - - using System.Reflection - * GlobalUsings - + global using Nerd_STF.Helpers - + global using System.Reflection - - Foreach(object) - - Foreach(T) - = Moved `IEncapsulator` to `Nerd_STF.Mathematics.Abstract` and renamed it to `IEncapsulate` - = Renamed `Fill2D` to `Fill2d` - = Renamed `IGroup2D` to `IGroup2d` - = Renamed `Modifier2D` to `IModifier2d` - = Renamed `Modifier2D` to `IModifier2d` - = Renamed `Modifier2D` to `IModifier2d` -= Made `Nerd_STF` allow unsafe code blocks + = Added a setter to `XW` + = Added a setter to `XY` + = Added a setter to `XZ` + = Added a setter to `YW` + = Added a setter to `YZ` + = Added a setter to `ZW` + = Added a setter to `XYW` + = Added a setter to `XYZ` + = Added a setter to `XZW` + = Added a setter to `YZW` ``` diff --git a/Nerd_STF/Mathematics/Float3.cs b/Nerd_STF/Mathematics/Float3.cs index c31186c..96c5d40 100644 --- a/Nerd_STF/Mathematics/Float3.cs +++ b/Nerd_STF/Mathematics/Float3.cs @@ -23,9 +23,33 @@ public record struct Float3 : IAbsolute, IAverage, public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z); public Float3 Normalized => this * Mathf.InverseSqrt(x * x + y * y + z * z); - public Float2 XY => new(x, y); - public Float2 XZ => new(x, z); - public Float2 YZ => new(y, z); + public Float2 XY + { + get => (x, y); + set + { + x = value.x; + y = value.y; + } + } + public Float2 XZ + { + get => (x, z); + set + { + x = value.x; + z = value.y; + } + } + public Float2 YZ + { + get => (y, z); + set + { + y = value.x; + z = value.y; + } + } public float x, y, z; diff --git a/Nerd_STF/Mathematics/Float4.cs b/Nerd_STF/Mathematics/Float4.cs index 2c0a0ae..7a67bc5 100644 --- a/Nerd_STF/Mathematics/Float4.cs +++ b/Nerd_STF/Mathematics/Float4.cs @@ -24,17 +24,101 @@ public record struct Float4 : IAbsolute, public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z + w * w); public Float4 Normalized => this * Mathf.InverseSqrt(x * x + y * y + z * z + w * w); - public Float2 XY => new(x, y); - public Float2 XZ => new(x, z); - public Float2 XW => new(x, w); - public Float2 YW => new(y, w); - public Float2 YZ => new(y, z); - public Float2 ZW => new(z, w); + public Float2 XW + { + get => (x, w); + set + { + x = value.x; + w = value.y; + } + } + public Float2 XY + { + get => (x, y); + set + { + x = value.x; + y = value.y; + } + } + public Float2 XZ + { + get => (x, z); + set + { + x = value.x; + z = value.y; + } + } + public Float2 YW + { + get => (y, w); + set + { + y = value.x; + w = value.y; + } + } + public Float2 YZ + { + get => (y, z); + set + { + y = value.x; + z = value.y; + } + } + public Float2 ZW + { + get => (z, w); + set + { + z = value.x; + w = value.y; + } + } - public Float3 XYW => new(x, y, w); - public Float3 XYZ => new(x, y, z); - public Float3 YZW => new(y, z, w); - public Float3 XZW => new(x, z, w); + public Float3 XYW + { + get => (x, y, w); + set + { + x = value.x; + y = value.y; + w = value.z; + } + } + public Float3 XYZ + { + get => (x, y, z); + set + { + x = value.x; + y = value.y; + z = value.z; + } + } + public Float3 XZW + { + get => (x, z, w); + set + { + x = value.x; + z = value.y; + w = value.z; + } + } + public Float3 YZW + { + get => (y, z, w); + set + { + y = value.x; + z = value.y; + w = value.z; + } + } public float x, y, z, w; diff --git a/Nerd_STF/Mathematics/Int3.cs b/Nerd_STF/Mathematics/Int3.cs index 22385a7..72705c1 100644 --- a/Nerd_STF/Mathematics/Int3.cs +++ b/Nerd_STF/Mathematics/Int3.cs @@ -21,9 +21,33 @@ public record struct Int3 : IAbsolute, IAverage, IClamp, IClam public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z); public Int3 Normalized => (Int3)((Float3)this * Mathf.InverseSqrt(x * x + y * y + z * z)); - public Int2 XY => new(x, y); - public Int2 XZ => new(x, z); - public Int2 YZ => new(y, z); + public Int2 XY + { + get => (x, y); + set + { + x = value.x; + y = value.y; + } + } + public Int2 XZ + { + get => (x, z); + set + { + x = value.x; + z = value.y; + } + } + public Int2 YZ + { + get => (y, z); + set + { + y = value.x; + z = value.y; + } + } public int x, y, z; diff --git a/Nerd_STF/Mathematics/Int4.cs b/Nerd_STF/Mathematics/Int4.cs index f125c86..d2fbaab 100644 --- a/Nerd_STF/Mathematics/Int4.cs +++ b/Nerd_STF/Mathematics/Int4.cs @@ -21,17 +21,101 @@ public record struct Int4 : IAbsolute, IAverage, IClamp, IClam public float Magnitude => Mathf.Sqrt(x * x + y * y + z * z + w * w); public Int4 Normalized => (Int4)((Float4)this * Mathf.InverseSqrt(x * x + y * y + z * z + w * w)); - public Int2 XY => new(x, y); - public Int2 XZ => new(x, z); - public Int2 XW => new(x, w); - public Int2 YW => new(y, w); - public Int2 YZ => new(y, z); - public Int2 ZW => new(z, w); + public Int2 XW + { + get => (x, w); + set + { + x = value.x; + w = value.y; + } + } + public Int2 XY + { + get => (x, y); + set + { + x = value.x; + y = value.y; + } + } + public Int2 XZ + { + get => (x, z); + set + { + x = value.x; + z = value.y; + } + } + public Int2 YW + { + get => (y, w); + set + { + y = value.x; + w = value.y; + } + } + public Int2 YZ + { + get => (y, z); + set + { + y = value.x; + z = value.y; + } + } + public Int2 ZW + { + get => (z, w); + set + { + z = value.x; + w = value.y; + } + } - public Int3 XYW => new(x, y, w); - public Int3 XYZ => new(x, y, z); - public Int3 YZW => new(y, z, w); - public Int3 XZW => new(x, z, w); + public Int3 XYW + { + get => (x, y, w); + set + { + x = value.x; + y = value.y; + w = value.z; + } + } + public Int3 XYZ + { + get => (x, y, z); + set + { + x = value.x; + y = value.y; + z = value.z; + } + } + public Int3 XZW + { + get => (x, z, w); + set + { + x = value.x; + z = value.y; + w = value.z; + } + } + public Int3 YZW + { + get => (y, z, w); + set + { + y = value.x; + z = value.y; + w = value.z; + } + } public int x, y, z, w; -- 2.49.0.windows.1 From 2c2e7e3a99c844cb7508274e5f303306ed30ef3b Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Mon, 10 Jul 2023 16:04:04 -0400 Subject: [PATCH 3/9] Added conversion between number systems and their System.Numerics counterparts. (#32) --- Changelog.md | 4 ++++ Nerd_STF/Mathematics/NumberSystems/Complex.cs | 7 ++++++- Nerd_STF/Mathematics/NumberSystems/Quaternion.cs | 7 ++++++- Nerd_STF/Nerd_STF.csproj | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 8a17e79..66fb4ad 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,10 @@ Here's the full changelog: ``` * Nerd_STF * Mathematics + * NumberSystems + * Complex + + operator Complex(SystemComplex) + + operator SystemComplex(Complex) * Float3 = Added a setter to `XY` = Added a setter to `XZ` diff --git a/Nerd_STF/Mathematics/NumberSystems/Complex.cs b/Nerd_STF/Mathematics/NumberSystems/Complex.cs index 6727473..5f1da3e 100644 --- a/Nerd_STF/Mathematics/NumberSystems/Complex.cs +++ b/Nerd_STF/Mathematics/NumberSystems/Complex.cs @@ -1,4 +1,6 @@ -namespace Nerd_STF.Mathematics.NumberSystems; +using SystemComplex = System.Numerics.Complex; + +namespace Nerd_STF.Mathematics.NumberSystems; public record struct Complex(float u, float i) : IAbsolute, IAverage, ICeiling, IClampMagnitude, IComparable, IDivide, IDot, @@ -204,4 +206,7 @@ public record struct Complex(float u, float i) : IAbsolute, IAverage fill) => new(fill); public static implicit operator Complex(Fill fill) => new(fill); public static implicit operator Complex((float u, float i) val) => new(val.u, val.i); + + public static implicit operator Complex(SystemComplex val) => ((float)val.Real, (float)val.Imaginary); + public static implicit operator SystemComplex(Complex val) => new(val.u, val.i); } diff --git a/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs b/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs index 9dd6991..06f5eb7 100644 --- a/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs +++ b/Nerd_STF/Mathematics/NumberSystems/Quaternion.cs @@ -1,4 +1,6 @@ -namespace Nerd_STF.Mathematics.NumberSystems; +using SystemQuaternion = System.Numerics.Quaternion; + +namespace Nerd_STF.Mathematics.NumberSystems; public record struct Quaternion(float u, float i, float j, float k) : IAbsolute, IAverage, ICeiling, IClamp, IClampMagnitude, IComparable, @@ -332,4 +334,7 @@ public record struct Quaternion(float u, float i, float j, float k) : IAbsolute< public static implicit operator Quaternion(Fill fill) => new(fill); public static implicit operator Quaternion((float u, float i, float j, float k) val) => new(val.u, val.i, val.j, val.k); + + public static implicit operator Quaternion(SystemQuaternion val) => (val.X, val.Y, val.Z, val.W); + public static implicit operator SystemQuaternion(Quaternion val) => new(val.u, val.i, val.j, val.k); } diff --git a/Nerd_STF/Nerd_STF.csproj b/Nerd_STF/Nerd_STF.csproj index ed9ea85..7f0aed6 100644 --- a/Nerd_STF/Nerd_STF.csproj +++ b/Nerd_STF/Nerd_STF.csproj @@ -12,7 +12,7 @@ Copyright (c) 2023 That_One_Nerd README.md https://github.com/That-One-Nerd/Nerd_STF - 2.5.0 + 2.4.1 c#;csharp;c sharp;math;mathematics;mathametics;maths;color;rgb;rgba;cmyk;cmyka;hsv;hsva;calculus;linear algebra;linalg;linearalgebra;matrix;matrix2x2;matrix 2x2;matrix3x3;matrix 3x3;matrix4x4;matrix 4x4;matrix multiplication;vector;vector2d;vector3d;vector2;vector3;float2;float3;float4;int2;int3;int4;angle;geometry;vert;line;polygon;triangle;quadrilateral;sphere;circle;number system;numbersystem;complex numbers;complex;2d numbers;2dnumbers;quaternions;4d numbers;4dnumbers 2.4.1 Nerd_STF -- 2.49.0.windows.1 From 97a0b2fee5dd9d9db19e80bf59cd9f13e7a34301 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Mon, 10 Jul 2023 16:34:07 -0400 Subject: [PATCH 4/9] Fixed some blunders and finished #31. --- Changelog.md | 11 +++++++++++ Nerd_STF/Mathematics/Abstract/IMatrix.cs | 1 + Nerd_STF/Mathematics/Algebra/Matrix.cs | 7 ++++++- Nerd_STF/Mathematics/Algebra/Matrix2x2.cs | 4 ++-- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 66fb4ad..4440fd6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,10 +6,21 @@ Here's the full changelog: ``` * Nerd_STF * Mathematics + * Abstract + * IMatrix + + Cofactor() + * Algebra + * Matrix + = Fixed a blunder in `SignGrid(Int2)` with signs being incorrectly placed on matrixes with even column count. + * Matrix2x2 + = Fixed a blunder in `Cofactor()` with the position of elements. * NumberSystems * Complex + operator Complex(SystemComplex) + operator SystemComplex(Complex) + * Quaternion + + operator Quaternion(SystemQuaternion) + + operator SystemQuaternion(Quaternion) * Float3 = Added a setter to `XY` = Added a setter to `XZ` diff --git a/Nerd_STF/Mathematics/Abstract/IMatrix.cs b/Nerd_STF/Mathematics/Abstract/IMatrix.cs index 84429c2..34974f5 100644 --- a/Nerd_STF/Mathematics/Abstract/IMatrix.cs +++ b/Nerd_STF/Mathematics/Abstract/IMatrix.cs @@ -6,6 +6,7 @@ public interface IMatrix : IAbsolute, ICeiling, IClamp, IDivide, where T : IMatrix { public T Adjugate(); + public T Cofactor(); public float Determinant(); public T? Inverse(); public T Transpose(); diff --git a/Nerd_STF/Mathematics/Algebra/Matrix.cs b/Nerd_STF/Mathematics/Algebra/Matrix.cs index 3d13abc..b48d138 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix.cs @@ -20,7 +20,12 @@ public class Matrix : IMatrix return m; } public static Matrix One(Int2 size) => new(size, 1); - public static Matrix SignGrid(Int2 size) => new(size, Fills.SignFill); + public static Matrix SignGrid(Int2 size) => new(size, delegate (int x) + { + float sgnValue = Fills.SignFill(x); + if (size.y % 2 == 0 && x / size.y % 2 == 1) sgnValue *= -1; + return sgnValue; + }); public static Matrix Zero(Int2 size) => new(size); public bool HasMinors => Size.x > 1 && Size.y > 1; diff --git a/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs b/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs index 620b6a2..f842a94 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs @@ -223,8 +223,8 @@ public record class Matrix2x2 : IStaticMatrix { Matrix2x2 swapped = new(new[,] { - { r2c2, r1c2 }, - { r2c1, r1c1 } + { r2c2, r2c1 }, + { r1c2, r1c1 } }); return swapped ^ SignGrid; } -- 2.49.0.windows.1 From 63e70f7124946b30ecc13d4ec74a2775071f135d Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Mon, 10 Jul 2023 17:10:40 -0400 Subject: [PATCH 5/9] Added row operators to matrixes. Row-echelon coming soon. --- Changelog.md | 20 +++++++++++++ Nerd_STF/Mathematics/Abstract/IMatrix.cs | 6 ++++ .../Mathematics/Abstract/IStaticMatrix.cs | 2 +- Nerd_STF/Mathematics/Algebra/Matrix.cs | 29 ++++++++++++++++++ Nerd_STF/Mathematics/Algebra/Matrix2x2.cs | 30 +++++++++++++++++++ Nerd_STF/Mathematics/Algebra/Matrix3x3.cs | 29 ++++++++++++++++++ Nerd_STF/Mathematics/Algebra/Matrix4x4.cs | 29 ++++++++++++++++++ 7 files changed, 144 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 4440fd6..ee2d21a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,18 +2,38 @@ TODO +added row operations, fixed cofactor bugs, added setters + Here's the full changelog: ``` * Nerd_STF * Mathematics * Abstract * IMatrix + + AddRow(int, int, float) + Cofactor() + + ScaleRow(int, float) + + SwapRows(int, int) + + SolveRowEchelon() * Algebra * Matrix + + AddRow(int, int, float) + + ScaleRow(int, float) + + SwapRows(int, int) = Fixed a blunder in `SignGrid(Int2)` with signs being incorrectly placed on matrixes with even column count. * Matrix2x2 + + AddRow(int, int, float) + + ScaleRow(int, float) + + SwapRows(int, int) = Fixed a blunder in `Cofactor()` with the position of elements. + * Matrix3x3 + + AddRow(int, int, float) + + ScaleRow(int, float) + + SwapRows(int, int) + * Matrix4x4 + + AddRow(int, int, float) + + ScaleRow(int, float) + + SwapRows(int, int) * NumberSystems * Complex + operator Complex(SystemComplex) diff --git a/Nerd_STF/Mathematics/Abstract/IMatrix.cs b/Nerd_STF/Mathematics/Abstract/IMatrix.cs index 34974f5..cbcc7bf 100644 --- a/Nerd_STF/Mathematics/Abstract/IMatrix.cs +++ b/Nerd_STF/Mathematics/Abstract/IMatrix.cs @@ -10,6 +10,12 @@ public interface IMatrix : IAbsolute, ICeiling, IClamp, IDivide, public float Determinant(); public T? Inverse(); public T Transpose(); + + public T AddRow(int rowToChange, int referenceRow, float factor = 1); + public T ScaleRow(int rowIndex, float value); + public T SwapRows(int rowA, int rowB); + + //public T SolveRowEchelon(); } public interface IMatrix : IMatrix where This : IMatrix diff --git a/Nerd_STF/Mathematics/Abstract/IStaticMatrix.cs b/Nerd_STF/Mathematics/Abstract/IStaticMatrix.cs index e8287b9..ea3dfd3 100644 --- a/Nerd_STF/Mathematics/Abstract/IStaticMatrix.cs +++ b/Nerd_STF/Mathematics/Abstract/IStaticMatrix.cs @@ -3,5 +3,5 @@ public interface IStaticMatrix : IAverage, IMatrix, IMedian, IMatrixPresets where T : IStaticMatrix { - + } diff --git a/Nerd_STF/Mathematics/Algebra/Matrix.cs b/Nerd_STF/Mathematics/Algebra/Matrix.cs index b48d138..09ea5c5 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix.cs @@ -276,6 +276,35 @@ public class Matrix : IMatrix }); } + public Matrix AddRow(int rowToChange, int referenceRow, float factor = 1) + { + Matrix @this = this; + return new(Size, delegate (int r, int c) + { + if (r == rowToChange) return @this[r, c] += factor * @this[referenceRow, c]; + else return @this[r, c]; + }); + } + public Matrix ScaleRow(int rowIndex, float factor) + { + Matrix @this = this; + return new(Size, delegate (int r, int c) + { + if (r == rowIndex) return @this[r, c] * factor; + else return @this[r, c]; + }); + } + public Matrix SwapRows(int rowA, int rowB) + { + Matrix @this = this; + return new(Size, delegate (int r, int c) + { + if (r == rowA) return @this[rowB, c]; + else if (r == rowB) return @this[rowA, c]; + else return @this[r, c]; + }); + } + public override bool Equals([NotNullWhen(true)] object? obj) { if (obj == null) return base.Equals(obj); diff --git a/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs b/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs index f842a94..0eb26aa 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs @@ -241,6 +241,36 @@ public record class Matrix2x2 : IStaticMatrix { r1c2, r2c2 } }); + public Matrix2x2 AddRow(int rowToChange, int referenceRow, float factor = 1) + { + Matrix2x2 @this = this; + return new(delegate (int r, int c) + { + if (r == rowToChange) return @this[r, c] += factor * @this[referenceRow, c]; + else return @this[r, c]; + }); + } + public Matrix2x2 ScaleRow(int rowIndex, float factor) + { + Matrix2x2 @this = this; + return new(delegate (int r, int c) + { + if (r == rowIndex) return @this[r, c] * factor; + else return @this[r, c]; + }); + } + public Matrix2x2 SwapRows(int rowA, int rowB) + { + Matrix2x2 @this = this; + return new(delegate (int r, int c) + { + if (r == rowA) return @this[rowB, c]; + else if (r == rowB) return @this[rowA, c]; + else return @this[r, c]; + }); + } + + public virtual bool Equals(Matrix2x2? other) { if (other is null) return false; diff --git a/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs b/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs index d028038..8a8d66d 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs @@ -336,6 +336,35 @@ public record class Matrix3x3 : IStaticMatrix { r1c3, r2c3, r3c3 } }); + public Matrix3x3 AddRow(int rowToChange, int referenceRow, float factor = 1) + { + Matrix3x3 @this = this; + return new(delegate (int r, int c) + { + if (r == rowToChange) return @this[r, c] += factor * @this[referenceRow, c]; + else return @this[r, c]; + }); + } + public Matrix3x3 ScaleRow(int rowIndex, float factor) + { + Matrix3x3 @this = this; + return new(delegate (int r, int c) + { + if (r == rowIndex) return @this[r, c] * factor; + else return @this[r, c]; + }); + } + public Matrix3x3 SwapRows(int rowA, int rowB) + { + Matrix3x3 @this = this; + return new(delegate (int r, int c) + { + if (r == rowA) return @this[rowB, c]; + else if (r == rowB) return @this[rowA, c]; + else return @this[r, c]; + }); + } + public virtual bool Equals(Matrix3x3? other) { if (other is null) return false; diff --git a/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs b/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs index 1297034..262da21 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs @@ -451,6 +451,35 @@ public record class Matrix4x4 : IStaticMatrix { r1c4, r2c4, r3c4, r4c4 } }); + public Matrix4x4 AddRow(int rowToChange, int referenceRow, float factor = 1) + { + Matrix4x4 @this = this; + return new(delegate (int r, int c) + { + if (r == rowToChange) return @this[r, c] += factor * @this[referenceRow, c]; + else return @this[r, c]; + }); + } + public Matrix4x4 ScaleRow(int rowIndex, float factor) + { + Matrix4x4 @this = this; + return new(delegate (int r, int c) + { + if (r == rowIndex) return @this[r, c] * factor; + else return @this[r, c]; + }); + } + public Matrix4x4 SwapRows(int rowA, int rowB) + { + Matrix4x4 @this = this; + return new(delegate (int r, int c) + { + if (r == rowA) return @this[rowB, c]; + else if (r == rowB) return @this[rowA, c]; + else return @this[r, c]; + }); + } + public virtual bool Equals(Matrix4x4? other) { if (other is null) return false; -- 2.49.0.windows.1 From 5ff5cc7be8eabb7b36a5eb8b2ccbbc63a9411f24 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Fri, 14 Jul 2023 21:08:50 -0400 Subject: [PATCH 6/9] Some changes to the matrix types have been made. --- Changelog.md | 40 ++++++++++++++++- Nerd_STF/Mathematics/Abstract/IMatrix.cs | 20 +++++++-- Nerd_STF/Mathematics/Algebra/Matrix.cs | 14 ++++++ Nerd_STF/Mathematics/Algebra/Matrix2x2.cs | 37 +++++++++++++++- Nerd_STF/Mathematics/Algebra/Matrix3x3.cs | 42 ++++++++++++++++++ Nerd_STF/Mathematics/Algebra/Matrix4x4.cs | 52 ++++++++++++++++++++++- 6 files changed, 197 insertions(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index ee2d21a..1e72ab1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,7 +2,7 @@ TODO -added row operations, fixed cofactor bugs, added setters +added row operations, fixed cofactor bugs, added setters and more stuff to imatrix Here's the full changelog: ``` @@ -11,29 +11,65 @@ Here's the full changelog: * Abstract * IMatrix + AddRow(int, int, float) + + AddRowMutable(int, int, float) + Cofactor() + + GetColumn(int) + + GetRow(int) + ScaleRow(int, float) + + ScaleRowMutable(int, float) + + SetColumn(int, float[]) + + SetRow(int, float[]) + + Size + SwapRows(int, int) - + SolveRowEchelon() + + SwapRowsMutable(int, int) + + this[int, int] + + this[Index, Index] * Algebra * Matrix + AddRow(int, int, float) + + AddRowMutable(int, int, float) + ScaleRow(int, float) + + ScaleRowMutable(int, float) + SwapRows(int, int) + + SwapRowsMutable(int, int) = Fixed a blunder in `SignGrid(Int2)` with signs being incorrectly placed on matrixes with even column count. * Matrix2x2 + AddRow(int, int, float) + + AddRowMutable(int, int, float) + + GetColumn(int) + + GetRow(int) + ScaleRow(int, float) + + ScaleRowMutable(int, float) + + SetColumn(int, float[]) + + SetRow(int, float[]) + + Size + SwapRows(int, int) + + SwapRowsMutable(int, int) = Fixed a blunder in `Cofactor()` with the position of elements. * Matrix3x3 + AddRow(int, int, float) + + AddRowMutable(int, int, float) + + GetColumn(int) + + GetRow(int) + ScaleRow(int, float) + + ScaleRowMutable(int, float) + + SetColumn(int, float[]) + + SetRow(int, float[]) + + Size + SwapRows(int, int) + + SwapRowsMutable(int, int) * Matrix4x4 + AddRow(int, int, float) + + AddRowMutable(int, int, float) + + GetColumn(int) + + GetRow(int) + ScaleRow(int, float) + + ScaleRowMutable(int, float) + + SetColumn(int, float[]) + + SetRow(int, float[]) + + Size + SwapRows(int, int) + + SwapRowsMutable(int, int) * NumberSystems * Complex + operator Complex(SystemComplex) diff --git a/Nerd_STF/Mathematics/Abstract/IMatrix.cs b/Nerd_STF/Mathematics/Abstract/IMatrix.cs index cbcc7bf..f664310 100644 --- a/Nerd_STF/Mathematics/Abstract/IMatrix.cs +++ b/Nerd_STF/Mathematics/Abstract/IMatrix.cs @@ -5,17 +5,29 @@ public interface IMatrix : IAbsolute, ICeiling, IClamp, IDivide, ISubtract, ISum where T : IMatrix { + public Int2 Size { get; } + + public float this[int r, int c] { get; set; } + public float this[Index r, Index c] { get; set; } + public T Adjugate(); public T Cofactor(); public float Determinant(); public T? Inverse(); public T Transpose(); - public T AddRow(int rowToChange, int referenceRow, float factor = 1); - public T ScaleRow(int rowIndex, float value); - public T SwapRows(int rowA, int rowB); + public float[] GetColumn(int column); + public float[] GetRow(int row); - //public T SolveRowEchelon(); + public void SetColumn(int column, float[] value); + public void SetRow(int row, float[] values); + + public T AddRow(int rowToChange, int referenceRow, float factor = 1); + public void AddRowMutable(int rowToChange, int referenceRow, float factor = 1); + public T ScaleRow(int rowIndex, float value); + public void ScaleRowMutable(int rowIndex, float value); + public T SwapRows(int rowA, int rowB); + public void SwapRowsMutable(int rowA, int rowB); } public interface IMatrix : IMatrix where This : IMatrix diff --git a/Nerd_STF/Mathematics/Algebra/Matrix.cs b/Nerd_STF/Mathematics/Algebra/Matrix.cs index 09ea5c5..8ea5e0f 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix.cs @@ -285,6 +285,10 @@ public class Matrix : IMatrix else return @this[r, c]; }); } + public void AddRowMutable(int rowToChange, int referenceRow, float factor) + { + for (int c = 0; c < Size.y; c++) this[rowToChange, c] += this[referenceRow, c] * factor; + } public Matrix ScaleRow(int rowIndex, float factor) { Matrix @this = this; @@ -294,6 +298,10 @@ public class Matrix : IMatrix else return @this[r, c]; }); } + public void ScaleRowMutable(int rowIndex, float factor) + { + for (int c = 0; c < Size.y; c++) this[rowIndex, c] *= factor; + } public Matrix SwapRows(int rowA, int rowB) { Matrix @this = this; @@ -304,6 +312,12 @@ public class Matrix : IMatrix else return @this[r, c]; }); } + public void SwapRowsMutable(int rowA, int rowB) + { + float[] dataA = GetRow(rowA), dataB = GetRow(rowB); + SetRow(rowA, dataB); + SetRow(rowB, dataA); + } public override bool Equals([NotNullWhen(true)] object? obj) { diff --git a/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs b/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs index 0eb26aa..165ecf3 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix2x2.cs @@ -52,6 +52,8 @@ public record class Matrix2x2 : IStaticMatrix } } + public Int2 Size => (2, 2); + public float r1c1, r2c1, r1c2, r2c2; public Matrix2x2(float all) : this(all, all, all, all) { } @@ -241,6 +243,24 @@ public record class Matrix2x2 : IStaticMatrix { r1c2, r2c2 } }); + public float[] GetColumn(int column) => new[] { this[0, column], this[1, column] }; + public float[] GetRow(int row) => new[] { this[row, 0], this[row, 1] }; + + public void SetColumn(int column, float[] vals) + { + if (vals.Length < 2) + throw new InvalidSizeException("Array must contain enough values to fill the column."); + this[0, column] = vals[0]; + this[1, column] = vals[1]; + } + public void SetRow(int row, float[] vals) + { + if (vals.Length < 2) + throw new InvalidSizeException("Array must contain enough values to fill the row."); + this[row, 0] = vals[0]; + this[row, 1] = vals[1]; + } + public Matrix2x2 AddRow(int rowToChange, int referenceRow, float factor = 1) { Matrix2x2 @this = this; @@ -250,6 +270,11 @@ public record class Matrix2x2 : IStaticMatrix else return @this[r, c]; }); } + public void AddRowMutable(int rowToChange, int referenceRow, float factor) + { + this[rowToChange, 0] += this[referenceRow, 0] * factor; + this[rowToChange, 1] += this[referenceRow, 1] * factor; + } public Matrix2x2 ScaleRow(int rowIndex, float factor) { Matrix2x2 @this = this; @@ -259,6 +284,11 @@ public record class Matrix2x2 : IStaticMatrix else return @this[r, c]; }); } + public void ScaleRowMutable(int rowIndex, float factor) + { + this[rowIndex, 0] *= factor; + this[rowIndex, 1] *= factor; + } public Matrix2x2 SwapRows(int rowA, int rowB) { Matrix2x2 @this = this; @@ -269,7 +299,12 @@ public record class Matrix2x2 : IStaticMatrix else return @this[r, c]; }); } - + public void SwapRowsMutable(int rowA, int rowB) + { + float[] dataA = GetRow(rowA), dataB = GetRow(rowB); + SetRow(rowA, dataB); + SetRow(rowB, dataA); + } public virtual bool Equals(Matrix2x2? other) { diff --git a/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs b/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs index 8a8d66d..79c4ebb 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix3x3.cs @@ -78,6 +78,8 @@ public record class Matrix3x3 : IStaticMatrix } } + public Int2 Size => (3, 3); + public float r1c1, r2c1, r3c1, r1c2, r2c2, r3c2, r1c3, r2c3, r3c3; public Matrix3x3(float all) : this(all, all, all, all, all, all, all, all, all) { } @@ -336,6 +338,28 @@ public record class Matrix3x3 : IStaticMatrix { r1c3, r2c3, r3c3 } }); + public float[] GetColumn(int column) => new[] { this[0, column], this[1, column], this[2, column] }; + public float[] GetRow(int row) => new[] { this[row, 0], this[row, 1], this[row, 2] }; + + public void SetColumn(int column, float[] vals) + { + if (vals.Length < 3) + throw new InvalidSizeException("Array must contain enough values to fill the column."); + + this[0, column] = vals[0]; + this[1, column] = vals[1]; + this[2, column] = vals[2]; + } + public void SetRow(int row, float[] vals) + { + if (vals.Length < 3) + throw new InvalidSizeException("Array must contain enough values to fill the row."); + + this[row, 0] = vals[0]; + this[row, 1] = vals[1]; + this[row, 2] = vals[2]; + } + public Matrix3x3 AddRow(int rowToChange, int referenceRow, float factor = 1) { Matrix3x3 @this = this; @@ -345,6 +369,12 @@ public record class Matrix3x3 : IStaticMatrix else return @this[r, c]; }); } + public void AddRowMutable(int rowToChange, int referenceRow, float factor) + { + this[rowToChange, 0] += this[referenceRow, 0] * factor; + this[rowToChange, 1] += this[referenceRow, 1] * factor; + this[rowToChange, 2] += this[referenceRow, 2] * factor; + } public Matrix3x3 ScaleRow(int rowIndex, float factor) { Matrix3x3 @this = this; @@ -354,6 +384,12 @@ public record class Matrix3x3 : IStaticMatrix else return @this[r, c]; }); } + public void ScaleRowMutable(int rowIndex, float factor) + { + this[rowIndex, 0] *= factor; + this[rowIndex, 1] *= factor; + this[rowIndex, 2] *= factor; + } public Matrix3x3 SwapRows(int rowA, int rowB) { Matrix3x3 @this = this; @@ -364,6 +400,12 @@ public record class Matrix3x3 : IStaticMatrix else return @this[r, c]; }); } + public void SwapRowsMutable(int rowA, int rowB) + { + float[] dataA = GetRow(rowA), dataB = GetRow(rowB); + SetRow(rowA, dataB); + SetRow(rowB, dataA); + } public virtual bool Equals(Matrix3x3? other) { diff --git a/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs b/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs index 262da21..dc35b12 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix4x4.cs @@ -1,4 +1,6 @@ -namespace Nerd_STF.Mathematics.Algebra; +using System.Data.Common; + +namespace Nerd_STF.Mathematics.Algebra; public record class Matrix4x4 : IStaticMatrix { @@ -108,6 +110,8 @@ public record class Matrix4x4 : IStaticMatrix } } + public Int2 Size => (4, 4); + public float r1c1, r2c1, r3c1, r4c1, r1c2, r2c2, r3c2, r4c2, r1c3, r2c3, r3c3, r4c3, r1c4, r2c4, r3c4, r4c4; public Matrix4x4(float all) : this(all, all, all, all, all, @@ -451,6 +455,32 @@ public record class Matrix4x4 : IStaticMatrix { r1c4, r2c4, r3c4, r4c4 } }); + public float[] GetColumn(int column) => + new[] { this[0, column], this[1, column], this[2, column], this[3, column] }; + public float[] GetRow(int row) => + new[] { this[row, 0], this[row, 1], this[row, 2], this[row, 3] }; + + public void SetColumn(int column, float[] vals) + { + if (vals.Length < 4) + throw new InvalidSizeException("Array must contain enough values to fill the column."); + + this[0, column] = vals[0]; + this[1, column] = vals[1]; + this[2, column] = vals[2]; + this[3, column] = vals[3]; + } + public void SetRow(int row, float[] vals) + { + if (vals.Length < 4) + throw new InvalidSizeException("Array must contain enough values to fill the row."); + + this[row, 0] = vals[0]; + this[row, 1] = vals[1]; + this[row, 2] = vals[2]; + this[row, 3] = vals[3]; + } + public Matrix4x4 AddRow(int rowToChange, int referenceRow, float factor = 1) { Matrix4x4 @this = this; @@ -460,6 +490,13 @@ public record class Matrix4x4 : IStaticMatrix else return @this[r, c]; }); } + public void AddRowMutable(int rowToChange, int referenceRow, float factor) + { + this[rowToChange, 0] += this[referenceRow, 0] * factor; + this[rowToChange, 1] += this[referenceRow, 1] * factor; + this[rowToChange, 2] += this[referenceRow, 2] * factor; + this[rowToChange, 3] += this[referenceRow, 3] * factor; + } public Matrix4x4 ScaleRow(int rowIndex, float factor) { Matrix4x4 @this = this; @@ -469,6 +506,13 @@ public record class Matrix4x4 : IStaticMatrix else return @this[r, c]; }); } + public void ScaleRowMutable(int rowIndex, float factor) + { + this[rowIndex, 0] *= factor; + this[rowIndex, 1] *= factor; + this[rowIndex, 2] *= factor; + this[rowIndex, 3] *= factor; + } public Matrix4x4 SwapRows(int rowA, int rowB) { Matrix4x4 @this = this; @@ -479,6 +523,12 @@ public record class Matrix4x4 : IStaticMatrix else return @this[r, c]; }); } + public void SwapRowsMutable(int rowA, int rowB) + { + float[] dataA = GetRow(rowA), dataB = GetRow(rowB); + SetRow(rowA, dataB); + SetRow(rowB, dataA); + } public virtual bool Equals(Matrix4x4? other) { -- 2.49.0.windows.1 From fc223ec70e5cf31426b339183be34eaea9ef27a7 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Fri, 14 Jul 2023 21:34:38 -0400 Subject: [PATCH 7/9] Made a crap row-echelon solver. --- Nerd_STF/Mathematics/Algebra/Matrix.cs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Nerd_STF/Mathematics/Algebra/Matrix.cs b/Nerd_STF/Mathematics/Algebra/Matrix.cs index 8ea5e0f..f97ad07 100644 --- a/Nerd_STF/Mathematics/Algebra/Matrix.cs +++ b/Nerd_STF/Mathematics/Algebra/Matrix.cs @@ -1,6 +1,4 @@ -using System.Buffers; - -namespace Nerd_STF.Mathematics.Algebra; +namespace Nerd_STF.Mathematics.Algebra; public class Matrix : IMatrix { @@ -319,6 +317,27 @@ public class Matrix : IMatrix SetRow(rowB, dataA); } + public Matrix SolveRowEchelon() + { + Matrix result = (Matrix)MemberwiseClone(); + + // Scale the first row so the first element of that row is 1. + result.ScaleRowMutable(0, 1 / result[0, 0]); + + // For each row afterwards, subtract the required amount from all rows before it and normalize. + for (int r1 = 1; r1 < result.Size.x; r1++) + { + int min = Mathf.Min(r1, result.Size.y); + for (int r2 = 0; r2 < min; r2++) + { + result.AddRowMutable(r1, r2, -result[r1, r2]); + } + result.ScaleRowMutable(r1, 1 / result[r1, r1]); + } + + return result; + } + public override bool Equals([NotNullWhen(true)] object? obj) { if (obj == null) return base.Equals(obj); -- 2.49.0.windows.1 From e550688634ed2c98921dee4526738242042e9d2d Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Sun, 16 Jul 2023 19:55:15 -0400 Subject: [PATCH 8/9] Final description update to the changelog. --- Changelog.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 1e72ab1..4394c6d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,8 +1,16 @@ # Nerd_STF v2.4.1 -TODO +Hey everyone! This is one of the larger small updates, and I'm pretty proud of what I got done in a week. -added row operations, fixed cofactor bugs, added setters and more stuff to imatrix +Along with adding setters to parts like `Float3.XY` and fixing a few bugs, almost all improvements in this update are related to matricies. First of all, I've added a bunch of new items to the `IMatrix` interface. Now, any deriving matrix has more requirements that fit the regular `Matrix` type. I don't know why one would use the `IMatrix` interface rather than a specific matrix type, but now the options are more sophisticated. + +I've added some new stuff to all the matrix types, including row operations. You can now scale a row, add a row to another, and swap two rows. If I become aware of any more commonly-used row operations, I'll add then in a `2.4.2` update. But I think I've got all the good ones. There is also a mutable version of each operation which, rather than returning a new matrix with changes made, instead applies the changes to itself. + +Did you know I made two seperate blunders in the `Cofactor()` method? For the `Matrix2x2` version of the `Cofactor()` method, I had the diagonal elements swapped. Whoops. For the `Matrix` version of the `Cofactor()` method, matricies with even column count would break because of the alternating sign pattern I was using. Now, as far as I know, that bug is fixed. + +The last thing I did was add the ability to turn a matrix into its equivalent row-echelon form. This is applicable only to the `Matrix` type (the dynamic one), and works with some levels of success. It's a little weird and tends to give results with lots of negative zeroes, but overall it's fine, I think. As far as I know there aren't any obvious bugs. We'll see though. + +Anyway, that's everything in this update. Again, pretty small, but meaningful nonetheless. Unless I haven't screwed anything up, the next update I work on will be `2.5`, so I'll see you then! Here's the full changelog: ``` -- 2.49.0.windows.1 From 56eaf31c7bc41a6fe941816fdd1363fc50bd7f3c Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Sun, 16 Jul 2023 20:16:07 -0400 Subject: [PATCH 9/9] forgot to add this --- Nerd_STF/Nerd_STF.csproj | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Nerd_STF/Nerd_STF.csproj b/Nerd_STF/Nerd_STF.csproj index 7f0aed6..5bb893b 100644 --- a/Nerd_STF/Nerd_STF.csproj +++ b/Nerd_STF/Nerd_STF.csproj @@ -19,7 +19,17 @@ Nerd_STF MIT Logo Square.png - DO THIS + Hey everyone! This is one of the larger small updates, and I'm pretty proud of what I got done in a week. + +Along with adding setters to parts like `Float3.XY` and fixing a few bugs, almost all improvements in this update are related to matricies. First of all, I've added a bunch of new items to the `IMatrix` interface. Now, any deriving matrix has more requirements that fit the regular `Matrix` type. I don't know why one would use the `IMatrix` interface rather than a specific matrix type, but now the options are more sophisticated. + +I've added some new stuff to all the matrix types, including row operations. You can now scale a row, add a row to another, and swap two rows. If I become aware of any more commonly-used row operations, I'll add then in a `2.4.2` update. But I think I've got all the good ones. There is also a mutable version of each operation which, rather than returning a new matrix with changes made, instead applies the changes to itself. + +Did you know I made two seperate blunders in the `Cofactor()` method? For the `Matrix2x2` version of the `Cofactor()` method, I had the diagonal elements swapped. Whoops. For the `Matrix` version of the `Cofactor()` method, matricies with even column count would break because of the alternating sign pattern I was using. Now, as far as I know, that bug is fixed. + +The last thing I did was add the ability to turn a matrix into its equivalent row-echelon form. This is applicable only to the `Matrix` type (the dynamic one), and works with some levels of success. It's a little weird and tends to give results with lots of negative zeroes, but overall it's fine, I think. As far as I know there aren't any obvious bugs. We'll see though. + +Anyway, that's everything in this update. Again, pretty small, but meaningful nonetheless. Unless I haven't screwed anything up, the next update I work on will be `2.5`, so I'll see you then! https://github.com/That-One-Nerd/Nerd_STF False False -- 2.49.0.windows.1