Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the SoftMax Function #469

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Algorithms.Tests/Numeric/SoftMaxTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using Algorithms.Numeric;
using NUnit.Framework;

namespace Algorithms.Tests.Numeric;

public static class SoftMaxTests
{
[TestCase(new[] {5.0, 5.0}, new[] {0.5, 0.5})]
[TestCase(new[] {1.0, 2.0, 3.0}, new[] {0.09003057317038046, 0.24472847105479767, 0.6652409557748219})]
[TestCase(new[] {0.0}, new[] {1.0})]
public static void SoftMaxFunction(double[] input, double[] expected)
{
// Act
var result = SoftMax.Compute(input);

// Assert
Assert.That(result, Is.EqualTo(expected).Within(1e-9));
}

[Test]
public static void SoftMaxFunctionThrowsArgumentException()
{
// Arrange
var input = Array.Empty<double>();

// Assert
Assert.Throws<ArgumentException>(() => SoftMax.Compute(input));
}

[TestCase(new[] {1.0, 2.0, 3.0, 4.0, 5.0})]
[TestCase(new[] {0.0, 0.0, 0.0, 0.0, 0.0})]
[TestCase(new[] {5.0})]
public static void SoftMaxFunctionSumsToOne(double[] input)
{
// Act
var result = SoftMax.Compute(input);

var sum = 0.0;
foreach (var value in result)
{
sum += value;
}

// Assert
Assert.That(sum, Is.EqualTo(1.0).Within(1e-9));
}
}
45 changes: 45 additions & 0 deletions Algorithms/Numeric/SoftMax.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;

namespace Algorithms.Numeric;

/// <summary>
/// Implementation of the SoftMax function.
/// Its a function that takes as input a vector of K real numbers, and normalizes
/// it into a probability distribution consisting of K probabilities proportional
/// to the exponentials of the input numbers. After softmax, the elements of the vector always sum up to 1.
/// https://en.wikipedia.org/wiki/Softmax_function.
/// </summary>
public static class SoftMax
{
/// <summary>
/// Compute the SoftMax function.
/// The SoftMax function is defined as:
/// softmax(x_i) = exp(x_i) / sum(exp(x_j)) for j = 1 to n
/// where x_i is the i-th element of the input vector.
/// The elements of the output vector are the probabilities of the input vector, the output sums up to 1.
/// </summary>
/// <param name="input">The input vector of real numbers.</param>
/// <returns>The output vector of real numbers.</returns>
public static double[] Compute(double[] input)
{
if (input.Length == 0)
{
throw new ArgumentException("Array is empty.");
}

var exponentVector = new double[input.Length];
var sum = 0.0;
for (var index = 0; index < input.Length; index++)
{
exponentVector[index] = Math.Exp(input[index]);
sum += exponentVector[index];
}

for (var index = 0; index < input.Length; index++)
{
exponentVector[index] /= sum;
}

return exponentVector;
}
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ find more than one implementation for the same objective but using different alg
* [Automorphic Number](./Algorithms/Numeric/AutomorphicNumber.cs)
* [Josephus Problem](./Algorithms/Numeric/JosephusProblem.cs)
* [Newton's Square Root Calculation](./Algorithms/NewtonSquareRoot.cs)
* [SoftMax Function](./Algorithms/Numeric/SoftMax.cs)
* [Searches](./Algorithms/Search)
* [A-Star](./Algorithms/Search/AStar/)
* [Binary Search](./Algorithms/Search/BinarySearcher.cs)
Expand Down
Loading