diff --git a/core-java-modules/core-java-lang-math-2/.gitignore b/core-java-modules/core-java-lang-math-2/.gitignore
new file mode 100644
index 0000000000..30b2b7442c
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/.gitignore
@@ -0,0 +1,4 @@
+/target/
+.settings/
+.classpath
+.project
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/README.md b/core-java-modules/core-java-lang-math-2/README.md
new file mode 100644
index 0000000000..f05c8804ba
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/README.md
@@ -0,0 +1,16 @@
+## Java Math
+
+This module contains articles about math in Java.
+
+### Relevant articles:
+
+- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
+- [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm)
+- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap)
+- [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points)
+- [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines)
+- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred)
+- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
+- [Debugging with Eclipse](https://www.baeldung.com/eclipse-debugging)
+- [Matrix Multiplication in Java](https://www.baeldung.com/java-matrix-multiplication)
+- More articles: [[<-- prev]](/../core-java-lang-math)
diff --git a/core-java-modules/core-java-lang-math-2/pom.xml b/core-java-modules/core-java-lang-math-2/pom.xml
new file mode 100644
index 0000000000..92ebcc6a94
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/pom.xml
@@ -0,0 +1,90 @@
+
+
+ 4.0.0
+ core-java-lang-math-2
+ 0.0.1-SNAPSHOT
+ core-java-lang-math-2
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../../parent-java
+
+
+
+
+ org.apache.commons
+ commons-math3
+ ${commons-math3.version}
+
+
+ org.ejml
+ ejml-all
+ ${ejml.version}
+
+
+ org.nd4j
+ nd4j-native
+ ${nd4j.version}
+
+
+ org.la4j
+ la4j
+ ${la4j.version}
+
+
+ colt
+ colt
+ ${colt.version}
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ org.assertj
+ assertj-core
+ ${org.assertj.core.version}
+ test
+
+
+ com.github.dpaukov
+ combinatoricslib3
+ ${combinatoricslib3.version}
+
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ ${exec-maven-plugin.version}
+
+
+
+
+
+
+ 3.6.1
+ 3.9.0
+ 27.0.1-jre
+ 3.3.0
+ 0.38
+ 1.0.0-beta4
+ 1.2.0
+ 0.6.0
+ 1.19
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java
new file mode 100644
index 0000000000..40142ce940
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/ApacheCommonsCombinationGenerator.java
@@ -0,0 +1,29 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.commons.math3.util.CombinatoricsUtils;
+
+public class ApacheCommonsCombinationGenerator {
+
+ private static final int N = 6;
+ private static final int R = 3;
+
+ /**
+ * Print all combinations of r elements from a set
+ * @param n - number of elements in set
+ * @param r - number of elements in selection
+ */
+ public static void generate(int n, int r) {
+ Iterator iterator = CombinatoricsUtils.combinationsIterator(n, r);
+ while (iterator.hasNext()) {
+ final int[] combination = iterator.next();
+ System.out.println(Arrays.toString(combination));
+ }
+ }
+
+ public static void main(String[] args) {
+ generate(N, R);
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java
new file mode 100644
index 0000000000..0afdeefb8b
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/CombinatoricsLibCombinationGenerator.java
@@ -0,0 +1,13 @@
+package com.baeldung.algorithms.combination;
+
+import org.paukov.combinatorics3.Generator;
+
+public class CombinatoricsLibCombinationGenerator {
+
+ public static void main(String[] args) {
+ Generator.combination(0, 1, 2, 3, 4, 5)
+ .simple(3)
+ .stream()
+ .forEach(System.out::println);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java
new file mode 100644
index 0000000000..d2783881ba
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/GuavaCombinationsGenerator.java
@@ -0,0 +1,17 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+public class GuavaCombinationsGenerator {
+
+ public static void main(String[] args) {
+
+ Set> combinations = Sets.combinations(ImmutableSet.of(0, 1, 2, 3, 4, 5), 3);
+ System.out.println(combinations.size());
+ System.out.println(Arrays.toString(combinations.toArray()));
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java
new file mode 100644
index 0000000000..676d2f41e3
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/IterativeCombinationGenerator.java
@@ -0,0 +1,52 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class IterativeCombinationGenerator {
+
+ private static final int N = 5;
+ private static final int R = 2;
+
+ /**
+ * Generate all combinations of r elements from a set
+ * @param n the number of elements in input set
+ * @param r the number of elements in a combination
+ * @return the list containing all combinations
+ */
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ int[] combination = new int[r];
+
+ // initialize with lowest lexicographic combination
+ for (int i = 0; i < r; i++) {
+ combination[i] = i;
+ }
+
+ while (combination[r - 1] < n) {
+ combinations.add(combination.clone());
+
+ // generate next combination in lexicographic order
+ int t = r - 1;
+ while (t != 0 && combination[t] == n - r + t) {
+ t--;
+ }
+ combination[t]++;
+ for (int i = t + 1; i < r; i++) {
+ combination[i] = combination[i - 1] + 1;
+ }
+ }
+
+ return combinations;
+ }
+
+ public static void main(String[] args) {
+ IterativeCombinationGenerator generator = new IterativeCombinationGenerator();
+ List combinations = generator.generate(N, R);
+ System.out.println(combinations.size());
+ for (int[] combination : combinations) {
+ System.out.println(Arrays.toString(combination));
+ }
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java
new file mode 100644
index 0000000000..52305b8c2f
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/SelectionRecursiveCombinationGenerator.java
@@ -0,0 +1,53 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class SelectionRecursiveCombinationGenerator {
+
+ private static final int N = 6;
+ private static final int R = 3;
+
+ /**
+ * Generate all combinations of r elements from a set
+ * @param n - number of elements in input set
+ * @param r - number of elements to be chosen
+ * @return the list containing all combinations
+ */
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ helper(combinations, new int[r], 0, n - 1, 0);
+ return combinations;
+ }
+
+ /**
+ * Choose elements from set by recursing over elements selected
+ * @param combinations - List to store generated combinations
+ * @param data - current combination
+ * @param start - starting element of remaining set
+ * @param end - last element of remaining set
+ * @param index - number of elements chosen so far.
+ */
+ private void helper(List combinations, int data[], int start, int end, int index) {
+ if (index == data.length) {
+ int[] combination = data.clone();
+ combinations.add(combination);
+ } else {
+ int max = Math.min(end, end + 1 - data.length + index);
+ for (int i = start; i <= max; i++) {
+ data[index] = i;
+ helper(combinations, data, i + 1, end, index + 1);
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ SelectionRecursiveCombinationGenerator generator = new SelectionRecursiveCombinationGenerator();
+ List combinations = generator.generate(N, R);
+ for (int[] combination : combinations) {
+ System.out.println(Arrays.toString(combination));
+ }
+ System.out.printf("generated %d combinations of %d items from %d ", combinations.size(), R, N);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java
new file mode 100644
index 0000000000..a73447b31d
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/combination/SetRecursiveCombinationGenerator.java
@@ -0,0 +1,50 @@
+package com.baeldung.algorithms.combination;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class SetRecursiveCombinationGenerator {
+
+ private static final int N = 5;
+ private static final int R = 2;
+
+ /**
+ * Generate all combinations of r elements from a set
+ * @param n - number of elements in set
+ * @param r - number of elements in selection
+ * @return the list containing all combinations
+ */
+ public List generate(int n, int r) {
+ List combinations = new ArrayList<>();
+ helper(combinations, new int[r], 0, n-1, 0);
+ return combinations;
+ }
+
+ /**
+ * @param combinations - List to contain the generated combinations
+ * @param data - List of elements in the selection
+ * @param start - index of the starting element in the remaining set
+ * @param end - index of the last element in the set
+ * @param index - number of elements selected so far
+ */
+ private void helper(List combinations, int data[], int start, int end, int index) {
+ if (index == data.length) {
+ int[] combination = data.clone();
+ combinations.add(combination);
+ } else if (start <= end) {
+ data[index] = start;
+ helper(combinations, data, start + 1, end, index + 1);
+ helper(combinations, data, start + 1, end, index);
+ }
+ }
+
+ public static void main(String[] args) {
+ SetRecursiveCombinationGenerator generator = new SetRecursiveCombinationGenerator();
+ List combinations = generator.generate(N, R);
+ for (int[] combination : combinations) {
+ System.out.println(Arrays.toString(combination));
+ }
+ System.out.printf("generated %d combinations of %d items from %d ", combinations.size(), R, N);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java
new file mode 100644
index 0000000000..0c8eb86a38
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsService.java
@@ -0,0 +1,38 @@
+package com.baeldung.algorithms.distancebetweenpoints;
+
+import java.awt.geom.Point2D;
+
+public class DistanceBetweenPointsService {
+
+ public double calculateDistanceBetweenPoints(
+ double x1,
+ double y1,
+ double x2,
+ double y2) {
+
+ return Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
+ }
+
+ public double calculateDistanceBetweenPointsWithHypot(
+ double x1,
+ double y1,
+ double x2,
+ double y2) {
+
+ double ac = Math.abs(y2 - y1);
+ double cb = Math.abs(x2 - x1);
+
+ return Math.hypot(ac, cb);
+ }
+
+ public double calculateDistanceBetweenPointsWithPoint2D(
+ double x1,
+ double y1,
+ double x2,
+ double y2) {
+
+ return Point2D.distance(x1, y1, x2, y2);
+
+ }
+
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/factorial/Factorial.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/factorial/Factorial.java
new file mode 100644
index 0000000000..43d2221773
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/factorial/Factorial.java
@@ -0,0 +1,63 @@
+package com.baeldung.algorithms.factorial;
+
+import java.math.BigInteger;
+import java.util.stream.LongStream;
+
+import org.apache.commons.math3.util.CombinatoricsUtils;
+
+import com.google.common.math.BigIntegerMath;
+
+public class Factorial {
+
+ public long factorialUsingForLoop(int n) {
+ long fact = 1;
+ for (int i = 2; i <= n; i++) {
+ fact = fact * i;
+ }
+ return fact;
+ }
+
+ public long factorialUsingStreams(int n) {
+ return LongStream.rangeClosed(1, n)
+ .reduce(1, (long x, long y) -> x * y);
+ }
+
+ public long factorialUsingRecursion(int n) {
+ if (n <= 2) {
+ return n;
+ }
+ return n * factorialUsingRecursion(n - 1);
+ }
+
+ private Long[] factorials = new Long[20];
+
+ public long factorialUsingMemoize(int n) {
+
+ if (factorials[n] != null) {
+ return factorials[n];
+ }
+
+ if (n <= 2) {
+ return n;
+ }
+ long nthValue = n * factorialUsingMemoize(n - 1);
+ factorials[n] = nthValue;
+ return nthValue;
+ }
+
+ public BigInteger factorialHavingLargeResult(int n) {
+ BigInteger result = BigInteger.ONE;
+ for (int i = 2; i <= n; i++)
+ result = result.multiply(BigInteger.valueOf(i));
+ return result;
+ }
+
+ public long factorialUsingApacheCommons(int n) {
+ return CombinatoricsUtils.factorial(n);
+ }
+
+ public BigInteger factorialUsingGuava(int n) {
+ return BigIntegerMath.factorial(n);
+ }
+
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java
new file mode 100644
index 0000000000..35d6c8b424
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/linesintersection/LinesIntersectionService.java
@@ -0,0 +1,21 @@
+package com.baeldung.algorithms.linesintersection;
+
+import java.awt.Point;
+import java.util.Optional;
+
+public class LinesIntersectionService {
+
+ public Optional calculateIntersectionPoint(double m1, double b1, double m2, double b2) {
+
+ if (m1 == m2) {
+ return Optional.empty();
+ }
+
+ double x = (b2 - b1) / (m1 - m2);
+ double y = m1 * x + b1;
+
+ Point point = new Point();
+ point.setLocation(x, y);
+ return Optional.of(point);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/EllipticalMercator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/EllipticalMercator.java
new file mode 100644
index 0000000000..e1c41f9518
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/EllipticalMercator.java
@@ -0,0 +1,22 @@
+package com.baeldung.algorithms.mercator;
+
+class EllipticalMercator extends Mercator {
+
+ @Override
+ double yAxisProjection(double input) {
+
+ input = Math.min(Math.max(input, -89.5), 89.5);
+ double earthDimensionalRateNormalized = 1.0 - Math.pow(RADIUS_MINOR / RADIUS_MAJOR, 2);
+
+ double inputOnEarthProj = Math.sqrt(earthDimensionalRateNormalized) * Math.sin( Math.toRadians(input));
+
+ inputOnEarthProj = Math.pow(((1.0 - inputOnEarthProj)/(1.0+inputOnEarthProj)), 0.5 * Math.sqrt(earthDimensionalRateNormalized));
+ double inputOnEarthProjNormalized = Math.tan(0.5 * ((Math.PI*0.5) - Math.toRadians(input)))/inputOnEarthProj;
+ return (-1) * RADIUS_MAJOR * Math.log(inputOnEarthProjNormalized);
+ }
+
+ @Override
+ double xAxisProjection(double input) {
+ return RADIUS_MAJOR * Math.toRadians(input);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/Mercator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/Mercator.java
new file mode 100644
index 0000000000..b289b1839d
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/Mercator.java
@@ -0,0 +1,10 @@
+package com.baeldung.algorithms.mercator;
+
+abstract class Mercator {
+ final static double RADIUS_MAJOR = 6378137.0;
+ final static double RADIUS_MINOR = 6356752.3142;
+
+ abstract double yAxisProjection(double input);
+
+ abstract double xAxisProjection(double input);
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/SphericalMercator.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/SphericalMercator.java
new file mode 100644
index 0000000000..1be976d82e
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/mercator/SphericalMercator.java
@@ -0,0 +1,14 @@
+package com.baeldung.algorithms.mercator;
+
+public class SphericalMercator extends Mercator {
+
+ @Override
+ double xAxisProjection(double input) {
+ return Math.toRadians(input) * RADIUS_MAJOR;
+ }
+
+ @Override
+ double yAxisProjection(double input) {
+ return Math.log(Math.tan(Math.PI / 4 + Math.toRadians(input) / 2)) * RADIUS_MAJOR;
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Point.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Point.java
new file mode 100644
index 0000000000..68b1e7c594
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Point.java
@@ -0,0 +1,29 @@
+package com.baeldung.algorithms.rectanglesoverlap;
+
+public class Point {
+
+ private int x;
+ private int y;
+
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Rectangle.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Rectangle.java
new file mode 100644
index 0000000000..38f5edec61
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/rectanglesoverlap/Rectangle.java
@@ -0,0 +1,40 @@
+package com.baeldung.algorithms.rectanglesoverlap;
+
+public class Rectangle {
+
+ private Point bottomLeft;
+ private Point topRight;
+
+ public Rectangle(Point bottomLeft, Point topRight) {
+ this.bottomLeft = bottomLeft;
+ this.topRight = topRight;
+ }
+
+ public Point getBottomLeft() {
+ return bottomLeft;
+ }
+
+ public void setBottomLeft(Point bottomLeft) {
+ this.bottomLeft = bottomLeft;
+ }
+
+ public Point getTopRight() {
+ return topRight;
+ }
+
+ public void setTopRight(Point topRight) {
+ this.topRight = topRight;
+ }
+
+ public boolean isOverlapping(Rectangle other) {
+ // one rectangle is to the top of the other
+ if (this.topRight.getY() < other.bottomLeft.getY() || this.bottomLeft.getY() > other.topRight.getY()) {
+ return false;
+ }
+ // one rectangle is to the left of the other
+ if (this.topRight.getX() < other.bottomLeft.getX() || this.bottomLeft.getX() > other.topRight.getX()) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/roundedup/RoundUpToHundred.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/roundedup/RoundUpToHundred.java
new file mode 100644
index 0000000000..333019e294
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/algorithms/roundedup/RoundUpToHundred.java
@@ -0,0 +1,20 @@
+package com.baeldung.algorithms.roundedup;
+
+import java.util.Scanner;
+
+public class RoundUpToHundred {
+
+ public static void main(String[] args) {
+ Scanner scanner = new Scanner(System.in);
+ double input = scanner.nextDouble();
+ scanner.close();
+
+ RoundUpToHundred.round(input);
+ }
+
+ static long round(double input) {
+ long i = (long) Math.ceil(input);
+ return ((i + 99) / 100) * 100;
+ };
+
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/HomemadeMatrix.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/HomemadeMatrix.java
new file mode 100644
index 0000000000..0676250959
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/HomemadeMatrix.java
@@ -0,0 +1,23 @@
+package com.baeldung.matrices;
+
+public class HomemadeMatrix {
+ public static double[][] multiplyMatrices(double[][] firstMatrix, double[][] secondMatrix) {
+ double[][] result = new double[firstMatrix.length][secondMatrix[0].length];
+
+ for (int row = 0; row < result.length; row++) {
+ for (int col = 0; col < result[row].length; col++) {
+ result[row][col] = multiplyMatricesCell(firstMatrix, secondMatrix, row, col);
+ }
+ }
+
+ return result;
+ }
+
+ private static double multiplyMatricesCell(double[][] firstMatrix, double[][] secondMatrix, int row, int col) {
+ double cell = 0;
+ for (int i = 0; i < secondMatrix.length; i++) {
+ cell += firstMatrix[row][i] * secondMatrix[i][col];
+ }
+ return cell;
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/BigMatrixMultiplicationBenchmarking.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/BigMatrixMultiplicationBenchmarking.java
new file mode 100644
index 0000000000..2ed983f733
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/BigMatrixMultiplicationBenchmarking.java
@@ -0,0 +1,121 @@
+package com.baeldung.matrices.benchmark;
+
+import cern.colt.matrix.DoubleFactory2D;
+import cern.colt.matrix.DoubleMatrix2D;
+import cern.colt.matrix.linalg.Algebra;
+import com.baeldung.matrices.HomemadeMatrix;
+import org.apache.commons.math3.linear.Array2DRowRealMatrix;
+import org.apache.commons.math3.linear.RealMatrix;
+import org.ejml.simple.SimpleMatrix;
+import org.la4j.Matrix;
+import org.la4j.matrix.dense.Basic2DMatrix;
+import org.nd4j.linalg.api.ndarray.INDArray;
+import org.nd4j.linalg.factory.Nd4j;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.ChainedOptionsBuilder;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+public class BigMatrixMultiplicationBenchmarking {
+ private static final int DEFAULT_FORKS = 2;
+ private static final int DEFAULT_WARMUP_ITERATIONS = 5;
+ private static final int DEFAULT_MEASUREMENT_ITERATIONS = 10;
+
+ public static void main(String[] args) throws Exception {
+ Map parameters = parseParameters(args);
+
+ ChainedOptionsBuilder builder = new OptionsBuilder()
+ .include(BigMatrixMultiplicationBenchmarking.class.getSimpleName())
+ .mode(Mode.AverageTime)
+ .forks(forks(parameters))
+ .warmupIterations(warmupIterations(parameters))
+ .measurementIterations(measurementIterations(parameters))
+ .timeUnit(TimeUnit.SECONDS);
+
+ parameters.forEach(builder::param);
+
+ new Runner(builder.build()).run();
+ }
+
+ private static Map parseParameters(String[] args) {
+ return Arrays.stream(args)
+ .map(arg -> arg.split("="))
+ .collect(Collectors.toMap(
+ arg -> arg[0],
+ arg -> arg[1]
+ ));
+ }
+
+ private static int forks(Map parameters) {
+ String forks = parameters.remove("forks");
+ return parseOrDefault(forks, DEFAULT_FORKS);
+ }
+
+ private static int warmupIterations(Map parameters) {
+ String warmups = parameters.remove("warmupIterations");
+ return parseOrDefault(warmups, DEFAULT_WARMUP_ITERATIONS);
+ }
+
+ private static int measurementIterations(Map parameters) {
+ String measurements = parameters.remove("measurementIterations");
+ return parseOrDefault(measurements, DEFAULT_MEASUREMENT_ITERATIONS);
+ }
+
+ private static int parseOrDefault(String parameter, int defaultValue) {
+ return parameter != null ? Integer.parseInt(parameter) : defaultValue;
+ }
+
+ @Benchmark
+ public Object homemadeMatrixMultiplication(BigMatrixProvider matrixProvider) {
+ return HomemadeMatrix.multiplyMatrices(matrixProvider.getFirstMatrix(), matrixProvider.getSecondMatrix());
+ }
+
+ @Benchmark
+ public Object ejmlMatrixMultiplication(BigMatrixProvider matrixProvider) {
+ SimpleMatrix firstMatrix = new SimpleMatrix(matrixProvider.getFirstMatrix());
+ SimpleMatrix secondMatrix = new SimpleMatrix(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.mult(secondMatrix);
+ }
+
+ @Benchmark
+ public Object apacheCommonsMatrixMultiplication(BigMatrixProvider matrixProvider) {
+ RealMatrix firstMatrix = new Array2DRowRealMatrix(matrixProvider.getFirstMatrix());
+ RealMatrix secondMatrix = new Array2DRowRealMatrix(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.multiply(secondMatrix);
+ }
+
+ @Benchmark
+ public Object la4jMatrixMultiplication(BigMatrixProvider matrixProvider) {
+ Matrix firstMatrix = new Basic2DMatrix(matrixProvider.getFirstMatrix());
+ Matrix secondMatrix = new Basic2DMatrix(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.multiply(secondMatrix);
+ }
+
+ @Benchmark
+ public Object nd4jMatrixMultiplication(BigMatrixProvider matrixProvider) {
+ INDArray firstMatrix = Nd4j.create(matrixProvider.getFirstMatrix());
+ INDArray secondMatrix = Nd4j.create(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.mmul(secondMatrix);
+ }
+
+ @Benchmark
+ public Object coltMatrixMultiplication(BigMatrixProvider matrixProvider) {
+ DoubleFactory2D doubleFactory2D = DoubleFactory2D.dense;
+
+ DoubleMatrix2D firstMatrix = doubleFactory2D.make(matrixProvider.getFirstMatrix());
+ DoubleMatrix2D secondMatrix = doubleFactory2D.make(matrixProvider.getSecondMatrix());
+
+ Algebra algebra = new Algebra();
+ return algebra.mult(firstMatrix, secondMatrix);
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/BigMatrixProvider.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/BigMatrixProvider.java
new file mode 100644
index 0000000000..d0f8a03fe3
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/BigMatrixProvider.java
@@ -0,0 +1,46 @@
+package com.baeldung.matrices.benchmark;
+
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.infra.BenchmarkParams;
+
+import java.util.Random;
+import java.util.stream.DoubleStream;
+
+@State(Scope.Benchmark)
+public class BigMatrixProvider {
+ @Param({})
+ private int matrixSize;
+ private double[][] firstMatrix;
+ private double[][] secondMatrix;
+
+ public BigMatrixProvider() {}
+
+ @Setup
+ public void setup(BenchmarkParams parameters) {
+ firstMatrix = createMatrix(matrixSize);
+ secondMatrix = createMatrix(matrixSize);
+ }
+
+ private double[][] createMatrix(int matrixSize) {
+ Random random = new Random();
+
+ double[][] result = new double[matrixSize][matrixSize];
+ for (int row = 0; row < result.length; row++) {
+ for (int col = 0; col < result[row].length; col++) {
+ result[row][col] = random.nextDouble();
+ }
+ }
+ return result;
+ }
+
+ public double[][] getFirstMatrix() {
+ return firstMatrix;
+ }
+
+ public double[][] getSecondMatrix() {
+ return secondMatrix;
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/MatrixMultiplicationBenchmarking.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/MatrixMultiplicationBenchmarking.java
new file mode 100644
index 0000000000..fdb423e8da
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/MatrixMultiplicationBenchmarking.java
@@ -0,0 +1,86 @@
+package com.baeldung.matrices.benchmark;
+
+import cern.colt.matrix.DoubleFactory2D;
+import cern.colt.matrix.DoubleMatrix2D;
+import cern.colt.matrix.linalg.Algebra;
+import com.baeldung.matrices.HomemadeMatrix;
+import org.apache.commons.math3.linear.Array2DRowRealMatrix;
+import org.apache.commons.math3.linear.RealMatrix;
+import org.ejml.simple.SimpleMatrix;
+import org.la4j.Matrix;
+import org.la4j.matrix.dense.Basic2DMatrix;
+import org.nd4j.linalg.api.ndarray.INDArray;
+import org.nd4j.linalg.factory.Nd4j;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.concurrent.TimeUnit;
+
+public class MatrixMultiplicationBenchmarking {
+
+ public static void main(String[] args) throws Exception {
+ Options opt = new OptionsBuilder()
+ .include(MatrixMultiplicationBenchmarking.class.getSimpleName())
+ .exclude(BigMatrixMultiplicationBenchmarking.class.getSimpleName())
+ .mode(Mode.AverageTime)
+ .forks(2)
+ .warmupIterations(10)
+ .measurementIterations(10)
+ .timeUnit(TimeUnit.MICROSECONDS)
+ .build();
+
+ new Runner(opt).run();
+ }
+
+ @Benchmark
+ public Object homemadeMatrixMultiplication(MatrixProvider matrixProvider) {
+ return HomemadeMatrix.multiplyMatrices(matrixProvider.getFirstMatrix(), matrixProvider.getSecondMatrix());
+ }
+
+ @Benchmark
+ public Object ejmlMatrixMultiplication(MatrixProvider matrixProvider) {
+ SimpleMatrix firstMatrix = new SimpleMatrix(matrixProvider.getFirstMatrix());
+ SimpleMatrix secondMatrix = new SimpleMatrix(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.mult(secondMatrix);
+ }
+
+ @Benchmark
+ public Object apacheCommonsMatrixMultiplication(MatrixProvider matrixProvider) {
+ RealMatrix firstMatrix = new Array2DRowRealMatrix(matrixProvider.getFirstMatrix());
+ RealMatrix secondMatrix = new Array2DRowRealMatrix(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.multiply(secondMatrix);
+ }
+
+ @Benchmark
+ public Object la4jMatrixMultiplication(MatrixProvider matrixProvider) {
+ Matrix firstMatrix = new Basic2DMatrix(matrixProvider.getFirstMatrix());
+ Matrix secondMatrix = new Basic2DMatrix(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.multiply(secondMatrix);
+ }
+
+ @Benchmark
+ public Object nd4jMatrixMultiplication(MatrixProvider matrixProvider) {
+ INDArray firstMatrix = Nd4j.create(matrixProvider.getFirstMatrix());
+ INDArray secondMatrix = Nd4j.create(matrixProvider.getSecondMatrix());
+
+ return firstMatrix.mmul(secondMatrix);
+ }
+
+ @Benchmark
+ public Object coltMatrixMultiplication(MatrixProvider matrixProvider) {
+ DoubleFactory2D doubleFactory2D = DoubleFactory2D.dense;
+
+ DoubleMatrix2D firstMatrix = doubleFactory2D.make(matrixProvider.getFirstMatrix());
+ DoubleMatrix2D secondMatrix = doubleFactory2D.make(matrixProvider.getSecondMatrix());
+
+ Algebra algebra = new Algebra();
+ return algebra.mult(firstMatrix, secondMatrix);
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/MatrixProvider.java b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/MatrixProvider.java
new file mode 100644
index 0000000000..d401ba2ab6
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/java/com/baeldung/matrices/benchmark/MatrixProvider.java
@@ -0,0 +1,33 @@
+package com.baeldung.matrices.benchmark;
+
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+@State(Scope.Benchmark)
+public class MatrixProvider {
+ private double[][] firstMatrix;
+ private double[][] secondMatrix;
+
+ public MatrixProvider() {
+ firstMatrix =
+ new double[][] {
+ new double[] {1d, 5d},
+ new double[] {2d, 3d},
+ new double[] {1d ,7d}
+ };
+
+ secondMatrix =
+ new double[][] {
+ new double[] {1d, 2d, 3d, 7d},
+ new double[] {5d, 2d, 8d, 1d}
+ };
+ }
+
+ public double[][] getFirstMatrix() {
+ return firstMatrix;
+ }
+
+ public double[][] getSecondMatrix() {
+ return secondMatrix;
+ }
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/main/resources/logback.xml b/core-java-modules/core-java-lang-math-2/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java
new file mode 100644
index 0000000000..987b6ddae6
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/combination/CombinationUnitTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.algorithms.combination;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+
+public class CombinationUnitTest {
+
+ private static final int N = 5;
+ private static final int R = 3;
+ private static final int nCr = 10;
+
+ @Test
+ public void givenSetAndSelectionSize_whenCalculatedUsingSetRecursiveAlgorithm_thenExpectedCount() {
+ SetRecursiveCombinationGenerator generator = new SetRecursiveCombinationGenerator();
+ List selection = generator.generate(N, R);
+ assertEquals(nCr, selection.size());
+ }
+
+ @Test
+ public void givenSetAndSelectionSize_whenCalculatedUsingSelectionRecursiveAlgorithm_thenExpectedCount() {
+ SelectionRecursiveCombinationGenerator generator = new SelectionRecursiveCombinationGenerator();
+ List selection = generator.generate(N, R);
+ assertEquals(nCr, selection.size());
+ }
+
+ @Test
+ public void givenSetAndSelectionSize_whenCalculatedUsingIterativeAlgorithm_thenExpectedCount() {
+ IterativeCombinationGenerator generator = new IterativeCombinationGenerator();
+ List selection = generator.generate(N, R);
+ assertEquals(nCr, selection.size());
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java
new file mode 100644
index 0000000000..784681a807
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/distancebetweenpoints/DistanceBetweenPointsServiceUnitTest.java
@@ -0,0 +1,52 @@
+package com.baeldung.algorithms.distancebetweenpoints;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class DistanceBetweenPointsServiceUnitTest {
+
+ private DistanceBetweenPointsService service = new DistanceBetweenPointsService();
+
+ @Test
+ public void givenTwoPoints_whenCalculateDistanceByFormula_thenCorrect() {
+
+ double x1 = 3;
+ double y1 = 4;
+ double x2 = 7;
+ double y2 = 1;
+
+ double distance = service.calculateDistanceBetweenPoints(x1, y1, x2, y2);
+
+ assertEquals(distance, 5, 0.001);
+
+ }
+
+ @Test
+ public void givenTwoPoints_whenCalculateDistanceWithHypot_thenCorrect() {
+
+ double x1 = 3;
+ double y1 = 4;
+ double x2 = 7;
+ double y2 = 1;
+
+ double distance = service.calculateDistanceBetweenPointsWithHypot(x1, y1, x2, y2);
+
+ assertEquals(distance, 5, 0.001);
+
+ }
+
+ @Test
+ public void givenTwoPoints_whenCalculateDistanceWithPoint2D_thenCorrect() {
+
+ double x1 = 3;
+ double y1 = 4;
+ double x2 = 7;
+ double y2 = 1;
+
+ double distance = service.calculateDistanceBetweenPointsWithPoint2D(x1, y1, x2, y2);
+
+ assertEquals(distance, 5, 0.001);
+
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java
new file mode 100644
index 0000000000..c185dba62b
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/factorial/FactorialUnitTest.java
@@ -0,0 +1,72 @@
+package com.baeldung.algorithms.factorial;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.math.BigInteger;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class FactorialUnitTest {
+
+ Factorial factorial;
+
+ @Before
+ public void setup() {
+ factorial = new Factorial();
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingForLoop_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingForLoop(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingStreams_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingStreams(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingRecursion_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingRecursion(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingMemoize_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingMemoize(n)).isEqualTo(120);
+
+ n = 6;
+
+ assertThat(factorial.factorialUsingMemoize(n)).isEqualTo(720);
+ }
+
+ @Test
+ public void whenCalculatingFactorialHavingLargeResult_thenCorrect() {
+ int n = 22;
+
+ assertThat(factorial.factorialHavingLargeResult(n)).isEqualTo(new BigInteger("1124000727777607680000"));
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingApacheCommons_thenCorrect() {
+ int n = 5;
+
+ assertThat(factorial.factorialUsingApacheCommons(n)).isEqualTo(120);
+ }
+
+ @Test
+ public void whenCalculatingFactorialUsingGuava_thenCorrect() {
+ int n = 22;
+
+ assertThat(factorial.factorialUsingGuava(n)).isEqualTo(new BigInteger("1124000727777607680000"));
+ }
+
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java
new file mode 100644
index 0000000000..22371107f3
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/linesintersection/LinesIntersectionServiceUnitTest.java
@@ -0,0 +1,40 @@
+package com.baeldung.algorithms.linesintersection;
+
+import java.awt.Point;
+import java.util.Optional;
+
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
+
+public class LinesIntersectionServiceUnitTest {
+ private LinesIntersectionService service = new LinesIntersectionService();
+
+ @Test
+ public void givenNotParallelLines_whenCalculatePoint_thenPresent() {
+
+ double m1 = 0;
+ double b1 = 0;
+ double m2 = 1;
+ double b2 = -1;
+
+ Optional point = service.calculateIntersectionPoint(m1, b1, m2, b2);
+
+ assertTrue(point.isPresent());
+ assertEquals(point.get().getX(), 1, 0.001);
+ assertEquals(point.get().getY(), 0, 0.001);
+ }
+
+ @Test
+ public void givenParallelLines_whenCalculatePoint_thenEmpty() {
+ double m1 = 1;
+ double b1 = 0;
+ double m2 = 1;
+ double b2 = -1;
+
+ Optional point = service.calculateIntersectionPoint(m1, b1, m2, b2);
+
+ assertFalse(point.isPresent());
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/mercator/EllipticalMercatorUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/mercator/EllipticalMercatorUnitTest.java
new file mode 100644
index 0000000000..96b644c46c
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/mercator/EllipticalMercatorUnitTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.algorithms.mercator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class EllipticalMercatorUnitTest {
+
+ @Test
+ public void giventThatTheInputIs22_whenXAxisProjectionIsCalled_thenTheResultIsTheCorrectOne() {
+ Mercator mercator = new EllipticalMercator();
+ double result = mercator.xAxisProjection(22);
+ Assert.assertEquals(result, 2449028.7974520186, 0.0);
+ }
+
+ @Test
+ public void giventThatTheInputIs44_whenYAxisProjectionIsCalled_thenTheResultIsTheCorrectOne() {
+ Mercator mercator = new EllipticalMercator();
+ double result = mercator.yAxisProjection(44);
+ Assert.assertEquals(result, 5435749.887511954, 0.0);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/mercator/SphericalMercatorUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/mercator/SphericalMercatorUnitTest.java
new file mode 100644
index 0000000000..348c6ad3e4
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/mercator/SphericalMercatorUnitTest.java
@@ -0,0 +1,21 @@
+package com.baeldung.algorithms.mercator;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SphericalMercatorUnitTest {
+
+ @Test
+ public void giventThatTheInputIs22_whenXAxisProjectionIsCalled_thenTheResultIsTheCorrectOne() {
+ Mercator mercator = new SphericalMercator();
+ double result = mercator.xAxisProjection(22);
+ Assert.assertEquals(result, 2449028.7974520186, 0.0);
+ }
+
+ @Test
+ public void giventThatTheInputIs44_whenYAxisProjectionIsCalled_thenTheResultIsTheCorrectOne() {
+ Mercator mercator = new SphericalMercator();
+ double result = mercator.yAxisProjection(44);
+ Assert.assertEquals(result, 5465442.183322753, 0.0);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java
new file mode 100644
index 0000000000..e4bb614b48
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/rectanglesoverlap/RectangleUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.algorithms.rectanglesoverlap;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import org.junit.Test;
+
+public class RectangleUnitTest {
+
+ @Test
+ public void givenTwoOverlappingRectangles_whenisOverlappingCalled_shouldReturnTrue() {
+ Rectangle rectangle1 = new Rectangle(new Point(2, 1), new Point(4, 3));
+ Rectangle rectangle2 = new Rectangle(new Point(1, 1), new Point(6, 4));
+ assertTrue(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-5, -2), new Point(2, 3));
+ rectangle2 = new Rectangle(new Point(-2, -1), new Point(5, 2));
+ assertTrue(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-5, 1), new Point(2, 4));
+ rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, 5));
+ assertTrue(rectangle1.isOverlapping(rectangle2));
+ }
+
+ @Test
+ public void givenTwoNonOverlappingRectangles_whenisOverlappingCalled_shouldReturnFalse() {
+ Rectangle rectangle1 = new Rectangle(new Point(-5, 1), new Point(-3, 4));
+ Rectangle rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, 5));
+ assertFalse(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-5, 1), new Point(3, 4));
+ rectangle2 = new Rectangle(new Point(-2, -2), new Point(5, -1));
+ assertFalse(rectangle1.isOverlapping(rectangle2));
+
+ rectangle1 = new Rectangle(new Point(-2, 1), new Point(0, 3));
+ rectangle2 = new Rectangle(new Point(3, 1), new Point(5, 4));
+ assertFalse(rectangle1.isOverlapping(rectangle2));
+ }
+
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/roundedup/RoundUpToHundredUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/roundedup/RoundUpToHundredUnitTest.java
new file mode 100644
index 0000000000..5191d65787
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/algorithms/roundedup/RoundUpToHundredUnitTest.java
@@ -0,0 +1,14 @@
+package com.baeldung.algorithms.roundedup;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class RoundUpToHundredUnitTest {
+ @Test
+ public void givenInput_whenRound_thenRoundUpToTheNearestHundred() {
+ assertEquals("Rounded up to hundred", 100, RoundUpToHundred.round(99));
+ assertEquals("Rounded up to three hundred ", 300, RoundUpToHundred.round(200.2));
+ assertEquals("Returns same rounded value", 400, RoundUpToHundred.round(400));
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java
new file mode 100644
index 0000000000..e7d99fbe3e
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.matrices.apache;
+
+import org.apache.commons.math3.linear.Array2DRowRealMatrix;
+import org.apache.commons.math3.linear.RealMatrix;
+import org.junit.jupiter.api.Test;
+import org.openjdk.jmh.annotations.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class RealMatrixUnitTest {
+
+ @Test
+ void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
+ RealMatrix firstMatrix = new Array2DRowRealMatrix(
+ new double[][] {
+ new double[] {1d, 5d},
+ new double[] {2d, 3d},
+ new double[] {1d ,7d}
+ }
+ );
+
+ RealMatrix secondMatrix = new Array2DRowRealMatrix(
+ new double[][] {
+ new double[] {1d, 2d, 3d, 7d},
+ new double[] {5d, 2d, 8d, 1d}
+ }
+ );
+
+ RealMatrix expected = new Array2DRowRealMatrix(
+ new double[][] {
+ new double[] {26d, 12d, 43d, 12d},
+ new double[] {17d, 10d, 30d, 17d},
+ new double[] {36d, 16d, 59d, 14d}
+ }
+ );
+
+ RealMatrix actual = firstMatrix.multiply(secondMatrix);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+}
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java
new file mode 100644
index 0000000000..da66cd7d61
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java
@@ -0,0 +1,46 @@
+package com.baeldung.matrices.colt;
+
+import cern.colt.matrix.DoubleFactory2D;
+import cern.colt.matrix.DoubleMatrix2D;
+import cern.colt.matrix.linalg.Algebra;
+import org.junit.jupiter.api.Test;
+import org.openjdk.jmh.annotations.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class DoubleMatrix2DUnitTest {
+
+ @Test
+ void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
+ DoubleFactory2D doubleFactory2D = DoubleFactory2D.dense;
+
+ DoubleMatrix2D firstMatrix = doubleFactory2D.make(
+ new double[][] {
+ new double[] {1d, 5d},
+ new double[] {2d, 3d},
+ new double[] {1d ,7d}
+ }
+ );
+
+ DoubleMatrix2D secondMatrix = doubleFactory2D.make(
+ new double[][] {
+ new double[] {1d, 2d, 3d, 7d},
+ new double[] {5d, 2d, 8d, 1d}
+ }
+ );
+
+ DoubleMatrix2D expected = doubleFactory2D.make(
+ new double[][] {
+ new double[] {26d, 12d, 43d, 12d},
+ new double[] {17d, 10d, 30d, 17d},
+ new double[] {36d, 16d, 59d, 14d}
+ }
+ );
+
+ Algebra algebra = new Algebra();
+ DoubleMatrix2D actual = algebra.mult(firstMatrix, secondMatrix);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java
new file mode 100644
index 0000000000..60381ece63
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.matrices.ejml;
+
+import org.ejml.simple.SimpleMatrix;
+import org.junit.jupiter.api.Test;
+import org.openjdk.jmh.annotations.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class SimpleMatrixUnitTest {
+
+ @Test
+ void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
+ SimpleMatrix firstMatrix = new SimpleMatrix(
+ new double[][] {
+ new double[] {1d, 5d},
+ new double[] {2d, 3d},
+ new double[] {1d ,7d}
+ }
+ );
+
+ SimpleMatrix secondMatrix = new SimpleMatrix(
+ new double[][] {
+ new double[] {1d, 2d, 3d, 7d},
+ new double[] {5d, 2d, 8d, 1d}
+ }
+ );
+
+ SimpleMatrix expected = new SimpleMatrix(
+ new double[][] {
+ new double[] {26d, 12d, 43d, 12d},
+ new double[] {17d, 10d, 30d, 17d},
+ new double[] {36d, 16d, 59d, 14d}
+ }
+ );
+
+ SimpleMatrix actual = firstMatrix.mult(secondMatrix);
+
+ assertThat(actual).matches(m -> m.isIdentical(expected, 0d));
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java
new file mode 100644
index 0000000000..d1a062ee79
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java
@@ -0,0 +1,54 @@
+package com.baeldung.matrices.homemade;
+
+import org.junit.jupiter.api.Test;
+import org.openjdk.jmh.annotations.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class HomemadeMatrixUnitTest {
+
+ @Test
+ void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
+ double[][] firstMatrix = {
+ new double[]{1d, 5d},
+ new double[]{2d, 3d},
+ new double[]{1d, 7d}
+ };
+
+ double[][] secondMatrix = {
+ new double[]{1d, 2d, 3d, 7d},
+ new double[]{5d, 2d, 8d, 1d}
+ };
+
+ double[][] expected = {
+ new double[]{26d, 12d, 43d, 12d},
+ new double[]{17d, 10d, 30d, 17d},
+ new double[]{36d, 16d, 59d, 14d}
+ };
+
+ double[][] actual = multiplyMatrices(firstMatrix, secondMatrix);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+ private double[][] multiplyMatrices(double[][] firstMatrix, double[][] secondMatrix) {
+ double[][] result = new double[firstMatrix.length][secondMatrix[0].length];
+
+ for (int row = 0; row < result.length; row++) {
+ for (int col = 0; col < result[row].length; col++) {
+ result[row][col] = multiplyMatricesCell(firstMatrix, secondMatrix, row, col);
+ }
+ }
+
+ return result;
+ }
+
+ private double multiplyMatricesCell(double[][] firstMatrix, double[][] secondMatrix, int row, int col) {
+ double cell = 0;
+ for (int i = 0; i < secondMatrix.length; i++) {
+ cell += firstMatrix[row][i] * secondMatrix[i][col];
+ }
+ return cell;
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java
new file mode 100644
index 0000000000..01731a3dd5
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.matrices.la4j;
+
+import org.junit.jupiter.api.Test;
+import org.la4j.Matrix;
+import org.la4j.matrix.dense.Basic2DMatrix;
+import org.openjdk.jmh.annotations.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class Basic2DMatrixUnitTest {
+
+ @Test
+ void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
+ Matrix firstMatrix = new Basic2DMatrix(
+ new double[][]{
+ new double[]{1d, 5d},
+ new double[]{2d, 3d},
+ new double[]{1d, 7d}
+ }
+ );
+
+ Matrix secondMatrix = new Basic2DMatrix(
+ new double[][]{
+ new double[]{1d, 2d, 3d, 7d},
+ new double[]{5d, 2d, 8d, 1d}
+ }
+ );
+
+ Matrix expected = new Basic2DMatrix(
+ new double[][]{
+ new double[]{26d, 12d, 43d, 12d},
+ new double[]{17d, 10d, 30d, 17d},
+ new double[]{36d, 16d, 59d, 14d}
+ }
+ );
+
+ Matrix actual = firstMatrix.multiply(secondMatrix);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java
new file mode 100644
index 0000000000..72ef60a571
--- /dev/null
+++ b/core-java-modules/core-java-lang-math-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.matrices.nd4j;
+
+import org.junit.jupiter.api.Test;
+import org.nd4j.linalg.api.ndarray.INDArray;
+import org.nd4j.linalg.factory.Nd4j;
+import org.openjdk.jmh.annotations.*;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class INDArrayUnitTest {
+
+ @Test
+ void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
+ INDArray firstMatrix = Nd4j.create(
+ new double[][]{
+ new double[]{1d, 5d},
+ new double[]{2d, 3d},
+ new double[]{1d, 7d}
+ }
+ );
+
+ INDArray secondMatrix = Nd4j.create(
+ new double[][] {
+ new double[] {1d, 2d, 3d, 7d},
+ new double[] {5d, 2d, 8d, 1d}
+ }
+ );
+
+ INDArray expected = Nd4j.create(
+ new double[][] {
+ new double[] {26d, 12d, 43d, 12d},
+ new double[] {17d, 10d, 30d, 17d},
+ new double[] {36d, 16d, 59d, 14d}
+ }
+ );
+
+ INDArray actual = firstMatrix.mmul(secondMatrix);
+
+ assertThat(actual).isEqualTo(expected);
+ }
+
+}
\ No newline at end of file