From 87284704ed908d4dbe286d22be75a702847d3bd9 Mon Sep 17 00:00:00 2001 From: crapxxi Date: Thu, 17 Sep 2026 13:36:36 +0500 Subject: [PATCH 1/7] Sigmoid Activation function implementation with simplified batch calculation --- .../maths/SigmoidActivation.java | 59 ++++++++++++++++++ .../maths/SigmoidActivationTest.java | 61 +++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/main/java/com/thealgorithms/maths/SigmoidActivation.java create mode 100644 src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java diff --git a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java new file mode 100644 index 000000000000..992a473b5384 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java @@ -0,0 +1,59 @@ +package com.thealgorithms.maths; + +/** + * Implementation of the Sigmoid Activation function. + * Sigmoid function is used as an activation function in machine learning and neural networks + * for modeling binary classification problems, smoothing outputs, and introducing non-linearity + * into models. + * + * @author Alikhan Turugeldiyev + */ + +public class SigmoidActivation { + /** + * @summary Maps any real-valued number into a value between 0 and 1 + * @param x In machine learning, x could be a weighted sum of inputs in a neural network neuron or a raw score in logistic regression. + * @return The output (range) of the sigmoid function is always strictly between 0 and 1. + */ + public static double activate(double x) { + // If the number x is NaN then, returning NaN to saving from unexpected output. + if(Double.isNaN(x)) return Double.NaN; + // Saving from unnecessary and heavy calculations. + // lim x->-inf sigmoid(x) will return number very close to 0 + if(x < -745) return 0.0; + // lim x->inf sigmoid(x) will return number very close to 1 + if(x > 745) return 1.0; + // sigmoid function's formula + return 1.0 / ( 1 + Math.exp((-1) * x)); + } + + public static double[][] activate(double[][] x) { + // apply calculation to every value in batch. + double[][] activatedNumbers = new double[x.length][x[0].length]; + for(int i = 0; i < x.length; i++) { + for (int j = 0; j < x[0].length; j++) activatedNumbers[i][j] = activate(x[i][j]); + } + return activatedNumbers; + } + + /** + * @summary Calculates gradients for mapped values. By the chain rule, you can calculate error. + * @param y Activated by sigmoid function value. + * @return The output is a gradient of the activated value. + */ + public static double grad(double y) { + // sigmoid function derivative is reducing to this value. + // sigmoid'(x) = sigmoid(x) * (1-sigmoid(x)) + return y * (1 - y); + } + + public static double[][] grad(double[][] y) { + // apply calculation to every value in batch. + double[][] grads = new double[y.length][y[0].length]; + for(int i = 0; i < y.length; i++) { + for (int j = 0; j < y[0].length; j++) grads[i][j] = grad(y[i][j]); + } + return grads; + } + +} diff --git a/src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java b/src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java new file mode 100644 index 000000000000..61a8119188ab --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java @@ -0,0 +1,61 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class SigmoidActivationTest { + + @Test + public void calculationTest() { + assertEquals(0.5,SigmoidActivation.activate(0), 0.01,"1 case correct" ); + assertEquals(0.73,SigmoidActivation.activate(1),0.01,"2 case correct"); + assertEquals(0.26,SigmoidActivation.activate(-1),0.01, "3 case correct"); + assertEquals(0.88,SigmoidActivation.activate(2),0.01,"4 case correct"); + assertEquals(0.11,SigmoidActivation.activate(-2),0.01,"5 case correct"); + + double[][] xBatch = new double[4][3]; + double[][] expectedX = new double[4][3]; + + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 3; j++) xBatch[i][j] = 0; + } + + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 3; j++) expectedX[i][j] = 0.5; + } + + assertTrue(Arrays.deepEquals(expectedX, SigmoidActivation.activate(xBatch)), "batch case correct"); + + assertEquals(0.25, SigmoidActivation.grad(0.5), 0.01, "grad calculation correct"); + + double[][] yBatch = new double[4][3]; + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 3; j++) yBatch[i][j] = 0.5; + } + + double[][] expectedY = new double[4][3]; + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 3; j++) expectedY[i][j] = 0.25; + } + assertTrue(Arrays.deepEquals(expectedY, SigmoidActivation.grad(yBatch)), "grad batch case correct"); + } + + @Test + public void willReturnNaN() { + double x = Double.NaN; + + assertTrue(Double.isNaN(SigmoidActivation.activate(x)), "returned NaN"); + } + + @Test + public void extremumNumbersOnActivate() { + double x = 777; + + assertEquals(1.0, SigmoidActivation.activate(x), 0.01, "big number case correct"); + assertEquals(0.0, SigmoidActivation.activate((-1) * x), 0.01, "small number case correct"); + } +} From 1cc18103a18b9a2eef0928e23bc6faac81034be4 Mon Sep 17 00:00:00 2001 From: crapxxi Date: Fri, 18 Sep 2026 23:08:51 +0500 Subject: [PATCH 2/7] clang formatted --- .../maths/SigmoidActivation.java | 23 +++++++---- .../maths/SigmoidActivationTest.java | 41 +++++++++++-------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java index 992a473b5384..10cdc0d8f489 100644 --- a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java +++ b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java @@ -17,21 +17,25 @@ public class SigmoidActivation { */ public static double activate(double x) { // If the number x is NaN then, returning NaN to saving from unexpected output. - if(Double.isNaN(x)) return Double.NaN; + if (Double.isNaN(x)) { + return Double.NaN; + } // Saving from unnecessary and heavy calculations. // lim x->-inf sigmoid(x) will return number very close to 0 - if(x < -745) return 0.0; + if (x < -745) return 0.0; // lim x->inf sigmoid(x) will return number very close to 1 - if(x > 745) return 1.0; + if (x > 745) return 1.0; // sigmoid function's formula - return 1.0 / ( 1 + Math.exp((-1) * x)); + return 1.0 / (1 + Math.exp((-1) * x)); } public static double[][] activate(double[][] x) { // apply calculation to every value in batch. double[][] activatedNumbers = new double[x.length][x[0].length]; - for(int i = 0; i < x.length; i++) { - for (int j = 0; j < x[0].length; j++) activatedNumbers[i][j] = activate(x[i][j]); + for (int i = 0; i < x.length; i++) { + for (int j = 0; j < x[0].length; j++) { + activatedNumbers[i][j] = activate(x[i][j]); + } } return activatedNumbers; } @@ -50,10 +54,11 @@ public static double grad(double y) { public static double[][] grad(double[][] y) { // apply calculation to every value in batch. double[][] grads = new double[y.length][y[0].length]; - for(int i = 0; i < y.length; i++) { - for (int j = 0; j < y[0].length; j++) grads[i][j] = grad(y[i][j]); + for (int i = 0; i < y.length; i++) { + for (int j = 0; j < y[0].length; j++) { + grads[i][j] = grad(y[i][j]); + } } return grads; } - } diff --git a/src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java b/src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java index 61a8119188ab..aadf2c7ddc12 100644 --- a/src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java +++ b/src/test/java/com/thealgorithms/maths/SigmoidActivationTest.java @@ -1,31 +1,34 @@ package com.thealgorithms.maths; -import org.junit.jupiter.api.Test; - -import java.util.Arrays; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + public class SigmoidActivationTest { @Test public void calculationTest() { - assertEquals(0.5,SigmoidActivation.activate(0), 0.01,"1 case correct" ); - assertEquals(0.73,SigmoidActivation.activate(1),0.01,"2 case correct"); - assertEquals(0.26,SigmoidActivation.activate(-1),0.01, "3 case correct"); - assertEquals(0.88,SigmoidActivation.activate(2),0.01,"4 case correct"); - assertEquals(0.11,SigmoidActivation.activate(-2),0.01,"5 case correct"); + assertEquals(0.5, SigmoidActivation.activate(0), 0.01, "1 case correct"); + assertEquals(0.73, SigmoidActivation.activate(1), 0.01, "2 case correct"); + assertEquals(0.26, SigmoidActivation.activate(-1), 0.01, "3 case correct"); + assertEquals(0.88, SigmoidActivation.activate(2), 0.01, "4 case correct"); + assertEquals(0.11, SigmoidActivation.activate(-2), 0.01, "5 case correct"); double[][] xBatch = new double[4][3]; double[][] expectedX = new double[4][3]; - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 3; j++) xBatch[i][j] = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + xBatch[i][j] = 0; + } } - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 3; j++) expectedX[i][j] = 0.5; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + expectedX[i][j] = 0.5; + } } assertTrue(Arrays.deepEquals(expectedX, SigmoidActivation.activate(xBatch)), "batch case correct"); @@ -33,13 +36,17 @@ public void calculationTest() { assertEquals(0.25, SigmoidActivation.grad(0.5), 0.01, "grad calculation correct"); double[][] yBatch = new double[4][3]; - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 3; j++) yBatch[i][j] = 0.5; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + yBatch[i][j] = 0.5; + } } double[][] expectedY = new double[4][3]; - for(int i = 0; i < 4; i++) { - for(int j = 0; j < 3; j++) expectedY[i][j] = 0.25; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + expectedY[i][j] = 0.25; + } } assertTrue(Arrays.deepEquals(expectedY, SigmoidActivation.grad(yBatch)), "grad batch case correct"); } From 064582a33144eb73fc19e14fc181f9692d6f1d25 Mon Sep 17 00:00:00 2001 From: crapxxi Date: Fri, 18 Sep 2026 23:49:59 +0500 Subject: [PATCH 3/7] braces --- .../java/com/thealgorithms/maths/SigmoidActivation.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java index 10cdc0d8f489..dcb570e96f55 100644 --- a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java +++ b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java @@ -22,9 +22,13 @@ public static double activate(double x) { } // Saving from unnecessary and heavy calculations. // lim x->-inf sigmoid(x) will return number very close to 0 - if (x < -745) return 0.0; + if (x < -745) { + return 0.0; + } // lim x->inf sigmoid(x) will return number very close to 1 - if (x > 745) return 1.0; + if (x > 745) { + return 1.0; + } // sigmoid function's formula return 1.0 / (1 + Math.exp((-1) * x)); } From 297edee782e6367f7713fe31ca60bec0e018f0b9 Mon Sep 17 00:00:00 2001 From: crapxxi Date: Sat, 19 Sep 2026 10:56:52 +0500 Subject: [PATCH 4/7] private constructor added --- src/main/java/com/thealgorithms/maths/SigmoidActivation.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java index dcb570e96f55..ff2212b25308 100644 --- a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java +++ b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java @@ -10,6 +10,9 @@ */ public class SigmoidActivation { + + private SigmoidActivation() { } + /** * @summary Maps any real-valued number into a value between 0 and 1 * @param x In machine learning, x could be a weighted sum of inputs in a neural network neuron or a raw score in logistic regression. From 543032ab631fd1d3cf848fe1503868b3cd9b22fa Mon Sep 17 00:00:00 2001 From: crapxxi Date: Sat, 19 Sep 2026 11:04:54 +0500 Subject: [PATCH 5/7] final + clang-format --- src/main/java/com/thealgorithms/maths/SigmoidActivation.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java index ff2212b25308..202190619155 100644 --- a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java +++ b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java @@ -9,9 +9,10 @@ * @author Alikhan Turugeldiyev */ -public class SigmoidActivation { +public final class SigmoidActivation { - private SigmoidActivation() { } + private SigmoidActivation() { + } /** * @summary Maps any real-valued number into a value between 0 and 1 From d923ba64a3fe4d0665bbe936ef9fd4dfc985b2b5 Mon Sep 17 00:00:00 2001 From: Alikhan Turugeldiyev Date: Sat, 19 Sep 2026 15:21:47 +0500 Subject: [PATCH 6/7] Update src/main/java/com/thealgorithms/maths/SigmoidActivation.java Co-authored-by: Oleksandr Klymenko --- src/main/java/com/thealgorithms/maths/SigmoidActivation.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java index 202190619155..772a2e947477 100644 --- a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java +++ b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java @@ -39,9 +39,10 @@ public static double activate(double x) { public static double[][] activate(double[][] x) { // apply calculation to every value in batch. - double[][] activatedNumbers = new double[x.length][x[0].length]; + double[][] activatedNumbers = new double[x.length][]; for (int i = 0; i < x.length; i++) { - for (int j = 0; j < x[0].length; j++) { + activatedNumbers[i] = new double[x[i].length]; + for (int j = 0; j < x[i].length; j++) { activatedNumbers[i][j] = activate(x[i][j]); } } From 835933adce063267c420bac979e7d622bd32e86c Mon Sep 17 00:00:00 2001 From: Alikhan Turugeldiyev Date: Sat, 19 Sep 2026 15:21:55 +0500 Subject: [PATCH 7/7] Update src/main/java/com/thealgorithms/maths/SigmoidActivation.java Co-authored-by: Oleksandr Klymenko --- src/main/java/com/thealgorithms/maths/SigmoidActivation.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java index 772a2e947477..aa12886e171b 100644 --- a/src/main/java/com/thealgorithms/maths/SigmoidActivation.java +++ b/src/main/java/com/thealgorithms/maths/SigmoidActivation.java @@ -62,9 +62,10 @@ public static double grad(double y) { public static double[][] grad(double[][] y) { // apply calculation to every value in batch. - double[][] grads = new double[y.length][y[0].length]; + double[][] grads = new double[y.length][]; for (int i = 0; i < y.length; i++) { - for (int j = 0; j < y[0].length; j++) { + grads[i] = new double[y[i].length]; + for (int j = 0; j < y[i].length; j++) { grads[i][j] = grad(y[i][j]); } }