From c7370c39fd3e3d0285f5fa7629f8eaeef51b518f Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Mon, 3 Apr 2023 16:38:58 +0100 Subject: [PATCH] feat: add MathUtility.Sigmoid (#60) --- CHANGELOG.md | 8 +-- X10D.Tests/src/Math/MathUtilityTests.cs | 89 +++++++++++++++++++++++++ X10D/src/Math/MathUtility.cs | 28 ++++++++ 3 files changed, 121 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32229ec..512b4b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,13 +15,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - X10D: Added `IntrinsicExtensions` and `IntrinsicUtility` which offer methods for vectors in `System.Runtime.Instrinsics`. (#70) - X10D: Added `MathUtility.Bias(float, float)` and `MathUtility.Bias(double, double)`. - X10D: Added `MathUtility.ExponentialDecay(float, float, float)` and `MathUtility.ExponentialDecay(double, double, double)`. -- X10D: Added `MathUtility.InverseLerp(float, float, float)` and `MathUtility.InverseLerp(double, double, double)` +- X10D: Added `MathUtility.InverseLerp(float, float, float)` and `MathUtility.InverseLerp(double, double, double)`. - X10D: Added `MathUtility.ScaleRange(float, float, float, float, float)` and `MathUtility.ScaleRange(double, double, double, double, double)` -- X10D: +- X10D: Added `MathUtility.Sigmoid(float)` and `MathUtility.Sigmoid(double)`. - X10D: Added `MathUtility.SmoothStep(float, float, float)` and `MathUtility.SmoothStep(double, double, double)`. - Added `Circle`, `CircleF`, `Cuboid`, `Ellipse`, `EllipseF`, `Line3D`, `Line`, `LineF`, `Polygon`, `PolygonF`, `Polyhedron`, - and `Sphere`, to complement System.Drawing structs such as `Point` and `Rectangle` +- X10D: Added `Circle`, `CircleF`, `Cuboid`, `Ellipse`, `EllipseF`, `Line3D`, `Line`, `LineF`, `Polygon`, `PolygonF`, `Polyhedron`, + and `Sphere`, to complement System.Drawing structs such as `Point` and `Rectangle`. - X10D: Added `Color.Deconstruct()` - with optional alpha parameter. - X10D: Added `Color.GetClosestConsoleColor()`. - X10D: Added `DateTime.GetIso8601WeekOfYear()` and `DateTimeOffset.GetIso8601WeekOfYear()`. diff --git a/X10D.Tests/src/Math/MathUtilityTests.cs b/X10D.Tests/src/Math/MathUtilityTests.cs index 2834643..45c37ab 100644 --- a/X10D.Tests/src/Math/MathUtilityTests.cs +++ b/X10D.Tests/src/Math/MathUtilityTests.cs @@ -177,6 +177,95 @@ public class MathUtilityTests Assert.AreEqual(7.5f, result); } + [TestMethod] + public void Sigmoid_ReturnsExpectedValue_UsingDouble() + { + const double input = 0.5f; + const double expected = 0.622459331f; + + double actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6); + } + + [TestMethod] + public void Sigmoid_ReturnsExpectedValue_UsingSingle() + { + const float input = 0.5f; + const float expected = 0.622459331f; + + float actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6f); + } + + [TestMethod] + public void Sigmoid_ReturnsZeroWhenInputIsNegativeInfinity_UsingDouble() + { + const double input = double.NegativeInfinity; + const double expected = 0f; + + double actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6); + } + + [TestMethod] + public void Sigmoid_ReturnsZeroWhenInputIsNegativeInfinity_UsingSingle() + { + const float input = float.NegativeInfinity; + const float expected = 0f; + + float actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6f); + } + + [TestMethod] + public void Sigmoid_ReturnsOneWhenInputIsPositiveInfinity_UsingDouble() + { + const double input = double.PositiveInfinity; + const double expected = 1f; + + double actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6); + } + + [TestMethod] + public void Sigmoid_ReturnsOneWhenInputIsPositiveInfinity_UsingSingle() + { + const float input = float.PositiveInfinity; + const float expected = 1f; + + float actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6f); + } + + [TestMethod] + public void Sigmoid_ReturnsZeroPointFiveWhenInputIsZero_UsingDouble() + { + const double input = 0f; + const double expected = 0.5f; + + double actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6); + } + + [TestMethod] + public void Sigmoid_ReturnsZeroPointFiveWhenInputIsZero_UsingSingle() + { + const float input = 0f; + const float expected = 0.5f; + + float actual = MathUtility.Sigmoid(input); + + Assert.AreEqual(expected, actual, 1e-6f); + } + + [TestMethod] public void SmoothStep_ShouldReturnHigher_GivenAlpha1() { diff --git a/X10D/src/Math/MathUtility.cs b/X10D/src/Math/MathUtility.cs index a3549a0..dc9b2f7 100644 --- a/X10D/src/Math/MathUtility.cs +++ b/X10D/src/Math/MathUtility.cs @@ -333,6 +333,34 @@ public static class MathUtility return (alpha * newRange) + newMin; } + /// + /// Calculates the sigmoid function for the given input value. + /// + /// The input value for which to calculate the sigmoid function. + /// The result of applying the sigmoid function to the input value. + /// + /// The sigmoid function is a commonly used activation function in artificial neural networks and logistic regression. It + /// maps any real-valued number to a value between 0 and 1. + /// + public static float Sigmoid(float value) + { + return 1.0f / (1.0f + MathF.Exp(-value)); + } + + /// + /// Calculates the sigmoid function for the given input value. + /// + /// The input value for which to calculate the sigmoid function. + /// The result of applying the sigmoid function to the input value. + /// + /// The sigmoid function is a commonly used activation function in artificial neural networks and logistic regression. It + /// maps any real-valued number to a value between 0 and 1. + /// + public static double Sigmoid(double value) + { + return 1.0f / (1.0f + System.Math.Exp(-value)); + } + /// /// Performs smooth Hermite interpolation from one value to a target using a specified alpha. ///