From 8c76f533b97162904338b2861276157f29846ac8 Mon Sep 17 00:00:00 2001 From: That-One-Nerd Date: Sun, 9 Jul 2023 23:38:31 -0400 Subject: [PATCH] Added taylor series generation. --- Changelog.md | 8 ++++++ Nerd_STF/Extensions/EquationExtension.cs | 17 +++++++++++++ Nerd_STF/Mathematics/Calculus.cs | 32 ++++++++++++++++++++---- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/Changelog.md b/Changelog.md index 5501c60..fdc6fbd 100644 --- a/Changelog.md +++ b/Changelog.md @@ -43,7 +43,13 @@ + 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) @@ -118,7 +124,9 @@ = 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) diff --git a/Nerd_STF/Extensions/EquationExtension.cs b/Nerd_STF/Extensions/EquationExtension.cs index f62b08d..e533133 100644 --- a/Nerd_STF/Extensions/EquationExtension.cs +++ b/Nerd_STF/Extensions/EquationExtension.cs @@ -78,9 +78,26 @@ public static class EquationExtension public static Equation Floor(this Equation equ) => x => Mathf.Floor(equ(x)); + public static Equation GetDerivative(this Equation equ, float step = Calculus.DefaultStep) => + Calculus.GetDerivative(equ, step); + public static float GetDerivativeAtPoint(this Equation equ, float x, float step = Calculus.DefaultStep) => + Calculus.GetDerivativeAtPoint(equ, x, step); + + public static float GetIntegral(this Equation equ, float lowerBound, float upperBound, + float step = Calculus.DefaultStep) => Calculus.GetIntegral(equ, lowerBound, upperBound, step); + + public static Equation GetDynamicIntegral(this Equation equ, Equation lowerBound, + Equation upperBound, float step = Calculus.DefaultStep) => Calculus.GetDynamicIntegral(equ, lowerBound, upperBound, step); + + public static Equation GetTaylorSeries(this Equation equ, float referenceX, int iterations = 4, float step = 0.01f) => + Calculus.GetTaylorSeries(equ, referenceX, iterations, step); + public static Dictionary GetValues(this Equation equ, float min, float max, float step = Calculus.DefaultStep) => Mathf.GetValues(equ, min, max, step); + public static float GradientDescent(this Equation equ, float initial, float rate, int iterations = 1000, + float step = Calculus.DefaultStep) => Calculus.GradientDescent(equ, initial, rate, iterations, step); + public static Equation InverseSqrt(this Equation equ) => x => Mathf.InverseSqrt(equ(x)); public static Equation Log(this Equation equ, float @base) => x => Mathf.Log(@base, equ(x)); diff --git a/Nerd_STF/Mathematics/Calculus.cs b/Nerd_STF/Mathematics/Calculus.cs index 95539cc..c61d5ab 100644 --- a/Nerd_STF/Mathematics/Calculus.cs +++ b/Nerd_STF/Mathematics/Calculus.cs @@ -1,6 +1,4 @@ -using System.Linq.Expressions; - -namespace Nerd_STF.Mathematics; +namespace Nerd_STF.Mathematics; public static class Calculus { @@ -21,14 +19,38 @@ public static class Calculus public static Equation GetDynamicIntegral(Equation equ, Equation lowerBound, Equation upperBound, float step = DefaultStep) => x => GetIntegral(equ, lowerBound(x), upperBound(x), step); + public static Equation GetTaylorSeries(Equation equ, float referenceX, int iterations = 4, float step = 0.01f) + { + Equation activeDerivative = equ; + float[] coefficients = new float[iterations]; + int fact = 1; + for (int i = 0; i < iterations; i++) + { + coefficients[i] = activeDerivative(referenceX) / fact; + activeDerivative = GetDerivative(activeDerivative, step); + fact *= i + 1; + } + + return delegate (float x) + { + float xVal = 1, result = 0; + for (int i = 0; i < coefficients.Length; i++) + { + result += coefficients[i] * xVal; + xVal *= x; + } + return result; + }; + } + // Unfortunately, I cannot test this function, as I have literally no idea how it works and // I can't find any tools online (and couldn't make my own) to compare my results. // Something to know, though I didn't feel like it deserved its own [Obsolete] attribute. - public static float GradientDescent(Equation equ, float initial, float rate, float stepCount = 1000, + public static float GradientDescent(Equation equ, float initial, float rate, int iterations = 1000, float step = DefaultStep) { float val = initial; - for (int i = 0; i < stepCount; i++) val -= GetDerivativeAtPoint(equ, val, step) * rate; + for (int i = 0; i < iterations; i++) val -= GetDerivativeAtPoint(equ, val, step) * rate; return val; } }