Skip to content

Commit 5c09c0e

Browse files
Add SoftMax Function (#469)
1 parent cb45f4a commit 5c09c0e

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using Algorithms.Numeric;
3+
using NUnit.Framework;
4+
5+
namespace Algorithms.Tests.Numeric;
6+
7+
public static class SoftMaxTests
8+
{
9+
[TestCase(new[] {5.0, 5.0}, new[] {0.5, 0.5})]
10+
[TestCase(new[] {1.0, 2.0, 3.0}, new[] {0.09003057317038046, 0.24472847105479767, 0.6652409557748219})]
11+
[TestCase(new[] {0.0}, new[] {1.0})]
12+
public static void SoftMaxFunction(double[] input, double[] expected)
13+
{
14+
// Act
15+
var result = SoftMax.Compute(input);
16+
17+
// Assert
18+
Assert.That(result, Is.EqualTo(expected).Within(1e-9));
19+
}
20+
21+
[Test]
22+
public static void SoftMaxFunctionThrowsArgumentException()
23+
{
24+
// Arrange
25+
var input = Array.Empty<double>();
26+
27+
// Assert
28+
Assert.Throws<ArgumentException>(() => SoftMax.Compute(input));
29+
}
30+
31+
[TestCase(new[] {1.0, 2.0, 3.0, 4.0, 5.0})]
32+
[TestCase(new[] {0.0, 0.0, 0.0, 0.0, 0.0})]
33+
[TestCase(new[] {5.0})]
34+
public static void SoftMaxFunctionSumsToOne(double[] input)
35+
{
36+
// Act
37+
var result = SoftMax.Compute(input);
38+
39+
var sum = 0.0;
40+
foreach (var value in result)
41+
{
42+
sum += value;
43+
}
44+
45+
// Assert
46+
Assert.That(sum, Is.EqualTo(1.0).Within(1e-9));
47+
}
48+
}

Algorithms/Numeric/SoftMax.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
3+
namespace Algorithms.Numeric;
4+
5+
/// <summary>
6+
/// Implementation of the SoftMax function.
7+
/// Its a function that takes as input a vector of K real numbers, and normalizes
8+
/// it into a probability distribution consisting of K probabilities proportional
9+
/// to the exponentials of the input numbers. After softmax, the elements of the vector always sum up to 1.
10+
/// https://en.wikipedia.org/wiki/Softmax_function.
11+
/// </summary>
12+
public static class SoftMax
13+
{
14+
/// <summary>
15+
/// Compute the SoftMax function.
16+
/// The SoftMax function is defined as:
17+
/// softmax(x_i) = exp(x_i) / sum(exp(x_j)) for j = 1 to n
18+
/// where x_i is the i-th element of the input vector.
19+
/// The elements of the output vector are the probabilities of the input vector, the output sums up to 1.
20+
/// </summary>
21+
/// <param name="input">The input vector of real numbers.</param>
22+
/// <returns>The output vector of real numbers.</returns>
23+
public static double[] Compute(double[] input)
24+
{
25+
if (input.Length == 0)
26+
{
27+
throw new ArgumentException("Array is empty.");
28+
}
29+
30+
var exponentVector = new double[input.Length];
31+
var sum = 0.0;
32+
for (var index = 0; index < input.Length; index++)
33+
{
34+
exponentVector[index] = Math.Exp(input[index]);
35+
sum += exponentVector[index];
36+
}
37+
38+
for (var index = 0; index < input.Length; index++)
39+
{
40+
exponentVector[index] /= sum;
41+
}
42+
43+
return exponentVector;
44+
}
45+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ find more than one implementation for the same objective but using different alg
9595
* [Automorphic Number](./Algorithms/Numeric/AutomorphicNumber.cs)
9696
* [Josephus Problem](./Algorithms/Numeric/JosephusProblem.cs)
9797
* [Newton's Square Root Calculation](./Algorithms/NewtonSquareRoot.cs)
98+
* [SoftMax Function](./Algorithms/Numeric/SoftMax.cs)
9899
* [Searches](./Algorithms/Search)
99100
* [A-Star](./Algorithms/Search/AStar/)
100101
* [Binary Search](./Algorithms/Search/BinarySearcher.cs)

0 commit comments

Comments
 (0)