From 155ae5610515d9a7934d40fbe6fa1ad9181be40c Mon Sep 17 00:00:00 2001 From: KeyKyrios Date: Mon, 27 Oct 2025 03:30:55 +0530 Subject: [PATCH 01/25] feat: Add Chebyshev Iteration algorithm --- .../maths/ChebyshevIteration.java | 198 ++++++++++++++++++ .../maths/ChebyshevIterationTest.java | 168 +++++++++++++++ 2 files changed, 366 insertions(+) create mode 100644 src/main/java/com/thealgorithms/maths/ChebyshevIteration.java create mode 100644 src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java new file mode 100644 index 000000000000..053029e140c0 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -0,0 +1,198 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; + +/** + * Implements the Chebyshev Iteration method for solving a system of linear + * equations (Ax = b). + * + * @author Mitrajit ghorui (github: keyKyrios) + * @see Wikipedia + * Page + * + * This is an iterative method that requires the matrix A to be + * symmetric positive definite (SPD). + * It also requires knowledge of the minimum (lambdaMin) and maximum + * (lambdaMax) + * eigenvalues of the matrix A. + * + * The algorithm converges faster than simpler methods like Jacobi or + * Gauss-Seidel + * by using Chebyshev polynomials to optimize the update steps. + */ +public final class ChebyshevIteration { + + /** + * Private constructor to prevent instantiation of this utility class. + */ + private ChebyshevIteration() { + } + + /** + * Solves the linear system Ax = b using Chebyshev Iteration. + * + * @param A A symmetric positive definite matrix. + * @param b The vector 'b' in the equation Ax = b. + * @param x0 An initial guess vector for 'x'. + * @param lambdaMin The smallest eigenvalue of matrix A. + * @param lambdaMax The largest eigenvalue of matrix A. + * @param maxIterations The maximum number of iterations to perform. + * @param tolerance The desired tolerance for convergence (e.g., 1e-10). + * @return The solution vector 'x'. + * @throws IllegalArgumentException if matrix/vector dimensions don't + * match, + * or if max/min eigenvalues are invalid. + */ + public static double[] solve( + double[][] A, + double[] b, + double[] x0, + double lambdaMin, + double lambdaMax, + int maxIterations, + double tolerance + ) { + validateInputs(A, b, x0, lambdaMin, lambdaMax); + + int n = b.length; + double[] x = Arrays.copyOf(x0, n); + double[] r = vectorSubtract(b, matrixVectorMultiply(A, x)); + double[] p = new double[n]; + double alpha = 0.0; + double beta = 0.0; + double c = (lambdaMax - lambdaMin) / 2.0; + double d = (lambdaMax + lambdaMin) / 2.0; + + double initialResidualNorm = vectorNorm(r); + if (initialResidualNorm < tolerance) { + return x; // Already converged + } + + for (int k = 1; k <= maxIterations; k++) { + if (k == 1) { + alpha = 1.0 / d; + p = Arrays.copyOf(r, n); + } else { + + // 1. Save the previous alpha + double alphaPrev = alpha; + + // 2. Calculate new beta and alpha using alphaPrev + beta = (c * alphaPrev / 2.0) * (c * alphaPrev / 2.0); + alpha = 1.0 / (d - beta / alphaPrev); + + // 3. Use alphaPrev in the p update + double betaOverAlphaPrev = beta / alphaPrev; + double[] rScaled = vectorScale(p, betaOverAlphaPrev); + p = vectorAdd(r, rScaled); + + } + + double[] pScaled = vectorScale(p, alpha); + x = vectorAdd(x, pScaled); + + // Re-calculate residual to avoid accumulating floating-point errors + // Note: Some variants calculate r = r - alpha * A * p for + // efficiency, + // but this direct calculation is more stable against drift. + r = vectorSubtract(b, matrixVectorMultiply(A, x)); + + if (vectorNorm(r) < tolerance) { + break; // Converged + } + } + return x; + } + + // --- Helper Methods for Linear Algebra --- + private static void validateInputs( + double[][] A, + double[] b, + double[] x0, + double lambdaMin, + double lambdaMax + ) { + int n = b.length; + if (n == 0) { + throw new IllegalArgumentException("Vectors cannot be empty."); + } + if (A.length != n || A[0].length != n) { + throw new IllegalArgumentException( + "Matrix A must be square with dimensions n x n." + ); + } + if (x0.length != n) { + throw new IllegalArgumentException( + "Initial guess vector x0 must have length n." + ); + } + if (lambdaMin >= lambdaMax || lambdaMin <= 0) { + throw new IllegalArgumentException( + "Eigenvalues must satisfy 0 < lambdaMin < lambdaMax." + ); + } + } + + /** + * Computes y = Ax + */ + private static double[] matrixVectorMultiply(double[][] A, double[] x) { + int n = A.length; + double[] y = new double[n]; + for (int i = 0; i < n; i++) { + double sum = 0.0; + for (int j = 0; j < n; j++) { + sum += A[i][j] * x[j]; + } + y[i] = sum; + } + return y; + } + + /** + * Computes c = a + b + */ + private static double[] vectorAdd(double[] a, double[] b) { + int n = a.length; + double[] c = new double[n]; + for (int i = 0; i < n; i++) { + c[i] = a[i] + b[i]; + } + return c; + } + + /** + * Computes c = a - b + */ + private static double[] vectorSubtract(double[] a, double[] b) { + int n = a.length; + double[] c = new double[n]; + for (int i = 0; i < n; i++) { + c[i] = a[i] - b[i]; + } + return c; + } + + /** + * Computes c = a * scalar + */ + private static double[] vectorScale(double[] a, double scalar) { + int n = a.length; + double[] c = new double[n]; + for (int i = 0; i < n; i++) { + c[i] = a[i] * scalar; + } + return c; + } + + /** + * Computes the L2 norm (Euclidean norm) of a vector + */ + private static double vectorNorm(double[] a) { + double sumOfSquares = 0.0; + for (double val : a) { + sumOfSquares += val * val; + } + return Math.sqrt(sumOfSquares); + } +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java new file mode 100644 index 000000000000..32aa02de07fc --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -0,0 +1,168 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class ChebyshevIterationTest { + + // --- Constants for testSolveSimple2x2System --- + private static final double M1_A11 = 4.0; + private static final double M1_A12 = 1.0; + private static final double M1_A21 = 1.0; + private static final double M1_A22 = 3.0; + private static final double[][] M1_A = { { M1_A11, M1_A12 }, { M1_A21, M1_A22 } }; + + private static final double M1_B1 = 1.0; + private static final double M1_B2 = 2.0; + private static final double[] M1_B = { M1_B1, M1_B2 }; + private static final double[] M1_X0 = { 0.0, 0.0 }; + + // Eigenvalues are (7 +/- sqrt(5)) / 2 + private static final double M1_LAMBDA_MIN = (7.0 - Math.sqrt(5.0)) / 2.0; + private static final double M1_LAMBDA_MAX = (7.0 + Math.sqrt(5.0)) / 2.0; + private static final double M1_EXPECTED_X1 = 1.0 / 11.0; + private static final double M1_EXPECTED_X2 = 7.0 / 11.0; + private static final double[] M1_EXPECTED = { M1_EXPECTED_X1, M1_EXPECTED_X2 }; + + // --- Constants for testSolve3x3System --- + private static final double[][] M2_A = { { 5.0, 0.0, 0.0 }, { 0.0, 2.0, 0.0 }, { 0.0, 0.0, 8.0 } }; + private static final double[] M2_B = { 10.0, -4.0, 24.0 }; + private static final double[] M2_X0 = { 0.0, 0.0, 0.0 }; + private static final double[] M2_EXPECTED = { 2.0, -2.0, 3.0 }; + private static final double M2_LAMBDA_MIN = 2.0; + private static final double M2_LAMBDA_MAX = 8.0; + + // --- Constants for testAlreadyConverged --- + private static final double M3_LAMBDA_MIN = 2.38; + private static final double M3_LAMBDA_MAX = 4.62; + + // --- General Constants --- + private static final int MAX_ITERATIONS = 100; + private static final double TOLERANCE = 1e-10; + private static final double ASSERT_TOLERANCE = 1e-9; + private static final int TEST_ITERATIONS = 10; + private static final double TEST_TOLERANCE = 1e-5; + + @Test + void testSolveSimple2x2System() { + double[] solution = ChebyshevIteration.solve( + M1_A, + M1_B, + M1_X0, + M1_LAMBDA_MIN, + M1_LAMBDA_MAX, + MAX_ITERATIONS, + TOLERANCE + ); + assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); + } + + @Test + void testSolve3x3System() { + double[] solution = ChebyshevIteration.solve( + M2_A, + M2_B, + M2_X0, + M2_LAMBDA_MIN, + M2_LAMBDA_MAX, + MAX_ITERATIONS, + TOLERANCE + ); + assertArrayEquals(M2_EXPECTED, solution, ASSERT_TOLERANCE); + } + + @Test + void testAlreadyConverged() { + // Test case where the initial guess is already the solution + double[] solution = ChebyshevIteration.solve( + M1_A, + M1_B, + M1_EXPECTED, // Use expected solution as initial guess + M3_LAMBDA_MIN, // Use approximate eigenvalues + M3_LAMBDA_MAX, + MAX_ITERATIONS, + TOLERANCE + ); + assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); + } + + @Test + void testInvalidEigenvalues() { + double[][] A = { { 1.0, 0.0 }, { 0.0, 1.0 } }; + double[] b = { 1.0, 1.0 }; + double[] x0 = { 0.0, 0.0 }; + + // lambdaMin >= lambdaMax + assertThrows( + IllegalArgumentException.class, + () -> + ChebyshevIteration.solve( + A, + b, + x0, + 2.0, + 1.0, + TEST_ITERATIONS, + TEST_TOLERANCE + ) + ); + // lambdaMin <= 0 + assertThrows( + IllegalArgumentException.class, + () -> + ChebyshevIteration.solve( + A, + b, + x0, + 0.0, + 2.0, + TEST_ITERATIONS, + TEST_TOLERANCE + ) + ); + } + + @Test + void testMismatchedDimensions() { + double[][] A = { { 1.0, 0.0 }, { 0.0, 1.0 } }; + double[] b = { 1.0, 1.0, 1.0 }; // b.length = 3 + double[] x0 = { 0.0, 0.0 }; // x0.length = 2 + + assertThrows( + IllegalArgumentException.class, + () -> + ChebyshevIteration.solve( + A, + b, + x0, + 0.5, + 1.5, + TEST_ITERATIONS, + TEST_TOLERANCE + ) + ); + } + + @Test + void testNonSquareMatrix() { + double[][] A = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 } }; // 2x3 matrix + double[] b = { 1.0, 1.0 }; + double[] x0 = { 0.0, 0.0 }; + + assertThrows( + IllegalArgumentException.class, + () -> + ChebyshevIteration.solve( + A, + b, + x0, + 0.5, + 1.5, + TEST_ITERATIONS, + TEST_TOLERANCE + ) + ); + } +} \ No newline at end of file From d66c700a91dc087b6894992c1dfde67ab9ed9cea Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:00:32 +0530 Subject: [PATCH 02/25] Update ChebyshevIteration.java --- .../com/thealgorithms/maths/ChebyshevIteration.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 053029e140c0..b43b3cf237d6 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -73,28 +73,21 @@ public static double[] solve( alpha = 1.0 / d; p = Arrays.copyOf(r, n); } else { - - // 1. Save the previous alpha + // Fix for algorithmic bug (use alphaPrev) double alphaPrev = alpha; - // 2. Calculate new beta and alpha using alphaPrev beta = (c * alphaPrev / 2.0) * (c * alphaPrev / 2.0); alpha = 1.0 / (d - beta / alphaPrev); - // 3. Use alphaPrev in the p update double betaOverAlphaPrev = beta / alphaPrev; double[] rScaled = vectorScale(p, betaOverAlphaPrev); p = vectorAdd(r, rScaled); - } double[] pScaled = vectorScale(p, alpha); x = vectorAdd(x, pScaled); // Re-calculate residual to avoid accumulating floating-point errors - // Note: Some variants calculate r = r - alpha * A * p for - // efficiency, - // but this direct calculation is more stable against drift. r = vectorSubtract(b, matrixVectorMultiply(A, x)); if (vectorNorm(r) < tolerance) { @@ -195,4 +188,4 @@ private static double vectorNorm(double[] a) { } return Math.sqrt(sumOfSquares); } -} \ No newline at end of file +} From babefd6bbbf16ff9e4fea6cca016160e53386d16 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:01:44 +0530 Subject: [PATCH 03/25] Update ChebyshevIterationTest.java --- .../maths/ChebyshevIterationTest.java | 110 +++++++++++------- 1 file changed, 66 insertions(+), 44 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index 32aa02de07fc..7f9cbac7e494 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -27,10 +27,23 @@ class ChebyshevIterationTest { private static final double[] M1_EXPECTED = { M1_EXPECTED_X1, M1_EXPECTED_X2 }; // --- Constants for testSolve3x3System --- - private static final double[][] M2_A = { { 5.0, 0.0, 0.0 }, { 0.0, 2.0, 0.0 }, { 0.0, 0.0, 8.0 } }; - private static final double[] M2_B = { 10.0, -4.0, 24.0 }; + private static final double M2_A11 = 5.0; + private static final double M2_A22 = 2.0; + private static final double M2_A33 = 8.0; + private static final double[][] M2_A = { + { M2_A11, 0.0, 0.0 }, + { 0.0, M2_A22, 0.0 }, + { 0.0, 0.0, M2_A33 }, + }; + private static final double M2_B1 = 10.0; + private static final double M2_B2 = -4.0; + private static final double M2_B3 = 24.0; + private static final double[] M2_B = { M2_B1, M2_B2, M2_B3 }; private static final double[] M2_X0 = { 0.0, 0.0, 0.0 }; - private static final double[] M2_EXPECTED = { 2.0, -2.0, 3.0 }; + private static final double M2_E1 = 2.0; + private static final double M2_E2 = -2.0; + private static final double M2_E3 = 3.0; + private static final double[] M2_EXPECTED = { M2_E1, M2_E2, M2_E3 }; private static final double M2_LAMBDA_MIN = 2.0; private static final double M2_LAMBDA_MAX = 8.0; @@ -38,6 +51,23 @@ class ChebyshevIterationTest { private static final double M3_LAMBDA_MIN = 2.38; private static final double M3_LAMBDA_MAX = 4.62; + // --- Constants for Invalid/Dimension Tests --- + private static final double VAL_0_0 = 0.0; + private static final double VAL_0_5 = 0.5; + private static final double VAL_1_0 = 1.0; + private static final double VAL_1_5 = 1.5; + private static final double VAL_2_0 = 2.0; + private static final double[][] M4_A = { { VAL_1_0, VAL_0_0 }, { VAL_0_0, VAL_1_0 } }; + private static final double[] M4_B = { VAL_1_0, VAL_1_0 }; + private static final double[] M4_X0 = { VAL_0_0, VAL_0_0 }; + private static final double[] M5_B = { VAL_1_0, VAL_1_0, VAL_1_0 }; + private static final double[][] M6_A = { + { VAL_1_0, VAL_0_0, VAL_0_0 }, + { VAL_0_0, VAL_1_0, VAL_0_0 }, + }; + private static final double[] M6_B = { VAL_1_0, VAL_1_0 }; + private static final double[] M6_X0 = { VAL_0_0, VAL_0_0 }; + // --- General Constants --- private static final int MAX_ITERATIONS = 100; private static final double TOLERANCE = 1e-10; @@ -90,79 +120,71 @@ void testAlreadyConverged() { @Test void testInvalidEigenvalues() { - double[][] A = { { 1.0, 0.0 }, { 0.0, 1.0 } }; - double[] b = { 1.0, 1.0 }; - double[] x0 = { 0.0, 0.0 }; - // lambdaMin >= lambdaMax assertThrows( IllegalArgumentException.class, - () -> + () -> { ChebyshevIteration.solve( - A, - b, - x0, - 2.0, - 1.0, + M4_A, + M4_B, + M4_X0, + VAL_2_0, + VAL_1_0, TEST_ITERATIONS, TEST_TOLERANCE - ) + ); + } ); // lambdaMin <= 0 assertThrows( IllegalArgumentException.class, - () -> + () -> { ChebyshevIteration.solve( - A, - b, - x0, - 0.0, - 2.0, + M4_A, + M4_B, + M4_X0, + VAL_0_0, + VAL_2_0, TEST_ITERATIONS, TEST_TOLERANCE - ) + ); + } ); } @Test void testMismatchedDimensions() { - double[][] A = { { 1.0, 0.0 }, { 0.0, 1.0 } }; - double[] b = { 1.0, 1.0, 1.0 }; // b.length = 3 - double[] x0 = { 0.0, 0.0 }; // x0.length = 2 - assertThrows( IllegalArgumentException.class, - () -> + () -> { ChebyshevIteration.solve( - A, - b, - x0, - 0.5, - 1.5, + M4_A, + M5_B, + M4_X0, + VAL_0_5, + VAL_1_5, TEST_ITERATIONS, TEST_TOLERANCE - ) + ); + } ); } @Test void testNonSquareMatrix() { - double[][] A = { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 } }; // 2x3 matrix - double[] b = { 1.0, 1.0 }; - double[] x0 = { 0.0, 0.0 }; - assertThrows( IllegalArgumentException.class, - () -> + () -> { ChebyshevIteration.solve( - A, - b, - x0, - 0.5, - 1.5, + M6_A, + M6_B, + M6_X0, + VAL_0_5, + VAL_1_5, TEST_ITERATIONS, TEST_TOLERANCE - ) + ); + } ); } -} \ No newline at end of file +} From b283f9b48413b005126362244b7d3a6c57c78e1d Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:09:05 +0530 Subject: [PATCH 04/25] Update ChebyshevIteration.java --- src/main/java/com/thealgorithms/maths/ChebyshevIteration.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index b43b3cf237d6..cf99ad4f8c45 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -110,16 +110,19 @@ private static void validateInputs( throw new IllegalArgumentException("Vectors cannot be empty."); } if (A.length != n || A[0].length != n) { + // clang-format-lint-action wants this on one line throw new IllegalArgumentException( "Matrix A must be square with dimensions n x n." ); } if (x0.length != n) { + // clang-format-lint-action wants this on one line throw new IllegalArgumentException( "Initial guess vector x0 must have length n." ); } if (lambdaMin >= lambdaMax || lambdaMin <= 0) { + // clang-format-lint-action wants this on one line throw new IllegalArgumentException( "Eigenvalues must satisfy 0 < lambdaMin < lambdaMax." ); From 016ffbba69f7fc43653342fc6d3218a6198ef31d Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:09:06 +0530 Subject: [PATCH 05/25] Update ChebyshevIterationTest.java From 14d893622816299661d22df0be4ec6f19cb5c324 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:14:10 +0530 Subject: [PATCH 06/25] Update ChebyshevIteration.java --- .../thealgorithms/maths/ChebyshevIteration.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index cf99ad4f8c45..861c139a2ba5 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -110,22 +110,13 @@ private static void validateInputs( throw new IllegalArgumentException("Vectors cannot be empty."); } if (A.length != n || A[0].length != n) { - // clang-format-lint-action wants this on one line - throw new IllegalArgumentException( - "Matrix A must be square with dimensions n x n." - ); + throw new IllegalArgumentException("Matrix A must be square with dimensions n x n."); } if (x0.length != n) { - // clang-format-lint-action wants this on one line - throw new IllegalArgumentException( - "Initial guess vector x0 must have length n." - ); + throw new IllegalArgumentException("Initial guess vector x0 must have length n."); } if (lambdaMin >= lambdaMax || lambdaMin <= 0) { - // clang-format-lint-action wants this on one line - throw new IllegalArgumentException( - "Eigenvalues must satisfy 0 < lambdaMin < lambdaMax." - ); + throw new IllegalArgumentException("Eigenvalues must satisfy 0 < lambdaMin < lambdaMax."); } } From af646073825d423676c902e7887f03ee2280988c Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:18:13 +0530 Subject: [PATCH 07/25] Update ChebyshevIteration.java --- .../maths/ChebyshevIteration.java | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 861c139a2ba5..53a0f506c5b7 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -43,15 +43,8 @@ private ChebyshevIteration() { * match, * or if max/min eigenvalues are invalid. */ - public static double[] solve( - double[][] A, - double[] b, - double[] x0, - double lambdaMin, - double lambdaMax, - int maxIterations, - double tolerance - ) { + // FIX: Method signature flattened to one line + public static double[] solve(double[][] A, double[] b, double[] x0, double lambdaMin, double lambdaMax, int maxIterations, double tolerance) { validateInputs(A, b, x0, lambdaMin, lambdaMax); int n = b.length; @@ -98,13 +91,7 @@ public static double[] solve( } // --- Helper Methods for Linear Algebra --- - private static void validateInputs( - double[][] A, - double[] b, - double[] x0, - double lambdaMin, - double lambdaMax - ) { + private static void validateInputs(double[][] A, double[] b, double[] x0, double lambdaMin, double lambdaMax) { int n = b.length; if (n == 0) { throw new IllegalArgumentException("Vectors cannot be empty."); From 693e02f28db4b9c17184acc2f06313b05ec24327 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:22:54 +0530 Subject: [PATCH 08/25] Update ChebyshevIterationTest.java --- .../maths/ChebyshevIterationTest.java | 133 ++++-------------- 1 file changed, 25 insertions(+), 108 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index 7f9cbac7e494..f37c12806e70 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -12,38 +12,34 @@ class ChebyshevIterationTest { private static final double M1_A12 = 1.0; private static final double M1_A21 = 1.0; private static final double M1_A22 = 3.0; - private static final double[][] M1_A = { { M1_A11, M1_A12 }, { M1_A21, M1_A22 } }; + private static final double[][] M1_A = {{M1_A11, M1_A12}, {M1_A21, M1_A22}}; private static final double M1_B1 = 1.0; private static final double M1_B2 = 2.0; - private static final double[] M1_B = { M1_B1, M1_B2 }; - private static final double[] M1_X0 = { 0.0, 0.0 }; + private static final double[] M1_B = {M1_B1, M1_B2}; + private static final double[] M1_X0 = {0.0, 0.0}; // Eigenvalues are (7 +/- sqrt(5)) / 2 private static final double M1_LAMBDA_MIN = (7.0 - Math.sqrt(5.0)) / 2.0; private static final double M1_LAMBDA_MAX = (7.0 + Math.sqrt(5.0)) / 2.0; private static final double M1_EXPECTED_X1 = 1.0 / 11.0; private static final double M1_EXPECTED_X2 = 7.0 / 11.0; - private static final double[] M1_EXPECTED = { M1_EXPECTED_X1, M1_EXPECTED_X2 }; + private static final double[] M1_EXPECTED = {M1_EXPECTED_X1, M1_EXPECTED_X2}; // --- Constants for testSolve3x3System --- private static final double M2_A11 = 5.0; private static final double M2_A22 = 2.0; private static final double M2_A33 = 8.0; - private static final double[][] M2_A = { - { M2_A11, 0.0, 0.0 }, - { 0.0, M2_A22, 0.0 }, - { 0.0, 0.0, M2_A33 }, - }; + private static final double[][] M2_A = {{M2_A11, 0.0, 0.0}, {0.0, M2_A22, 0.0}, {0.0, 0.0, M2_A33}}; private static final double M2_B1 = 10.0; private static final double M2_B2 = -4.0; private static final double M2_B3 = 24.0; - private static final double[] M2_B = { M2_B1, M2_B2, M2_B3 }; - private static final double[] M2_X0 = { 0.0, 0.0, 0.0 }; + private static final double[] M2_B = {M2_B1, M2_B2, M2_B3}; + private static final double[] M2_X0 = {0.0, 0.0, 0.0}; private static final double M2_E1 = 2.0; private static final double M2_E2 = -2.0; private static final double M2_E3 = 3.0; - private static final double[] M2_EXPECTED = { M2_E1, M2_E2, M2_E3 }; + private static final double[] M2_EXPECTED = {M2_E1, M2_E2, M2_E3}; private static final double M2_LAMBDA_MIN = 2.0; private static final double M2_LAMBDA_MAX = 8.0; @@ -57,16 +53,13 @@ class ChebyshevIterationTest { private static final double VAL_1_0 = 1.0; private static final double VAL_1_5 = 1.5; private static final double VAL_2_0 = 2.0; - private static final double[][] M4_A = { { VAL_1_0, VAL_0_0 }, { VAL_0_0, VAL_1_0 } }; - private static final double[] M4_B = { VAL_1_0, VAL_1_0 }; - private static final double[] M4_X0 = { VAL_0_0, VAL_0_0 }; - private static final double[] M5_B = { VAL_1_0, VAL_1_0, VAL_1_0 }; - private static final double[][] M6_A = { - { VAL_1_0, VAL_0_0, VAL_0_0 }, - { VAL_0_0, VAL_1_0, VAL_0_0 }, - }; - private static final double[] M6_B = { VAL_1_0, VAL_1_0 }; - private static final double[] M6_X0 = { VAL_0_0, VAL_0_0 }; + private static final double[][] M4_A = {{VAL_1_0, VAL_0_0}, {VAL_0_0, VAL_1_0}}; + private static final double[] M4_B = {VAL_1_0, VAL_1_0}; + private static final double[] M4_X0 = {VAL_0_0, VAL_0_0}; + private static final double[] M5_B = {VAL_1_0, VAL_1_0, VAL_1_0}; + private static final double[][] M6_A = {{VAL_1_0, VAL_0_0, VAL_0_0}, {VAL_0_0, VAL_1_0, VAL_0_0}}; + private static final double[] M6_B = {VAL_1_0, VAL_1_0}; + private static final double[] M6_X0 = {VAL_0_0, VAL_0_0}; // --- General Constants --- private static final int MAX_ITERATIONS = 100; @@ -77,114 +70,38 @@ class ChebyshevIterationTest { @Test void testSolveSimple2x2System() { - double[] solution = ChebyshevIteration.solve( - M1_A, - M1_B, - M1_X0, - M1_LAMBDA_MIN, - M1_LAMBDA_MAX, - MAX_ITERATIONS, - TOLERANCE - ); + double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_X0, M1_LAMBDA_MIN, M1_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testSolve3x3System() { - double[] solution = ChebyshevIteration.solve( - M2_A, - M2_B, - M2_X0, - M2_LAMBDA_MIN, - M2_LAMBDA_MAX, - MAX_ITERATIONS, - TOLERANCE - ); + double[] solution = ChebyshevIteration.solve(M2_A, M2_B, M2_X0, M2_LAMBDA_MIN, M2_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); assertArrayEquals(M2_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testAlreadyConverged() { - // Test case where the initial guess is already the solution - double[] solution = ChebyshevIteration.solve( - M1_A, - M1_B, - M1_EXPECTED, // Use expected solution as initial guess - M3_LAMBDA_MIN, // Use approximate eigenvalues - M3_LAMBDA_MAX, - MAX_ITERATIONS, - TOLERANCE - ); + + double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_EXPECTED, M3_LAMBDA_MIN, M3_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testInvalidEigenvalues() { - // lambdaMin >= lambdaMax - assertThrows( - IllegalArgumentException.class, - () -> { - ChebyshevIteration.solve( - M4_A, - M4_B, - M4_X0, - VAL_2_0, - VAL_1_0, - TEST_ITERATIONS, - TEST_TOLERANCE - ); - } - ); - // lambdaMin <= 0 - assertThrows( - IllegalArgumentException.class, - () -> { - ChebyshevIteration.solve( - M4_A, - M4_B, - M4_X0, - VAL_0_0, - VAL_2_0, - TEST_ITERATIONS, - TEST_TOLERANCE - ); - } - ); + + assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M4_B, M4_X0, VAL_2_0, VAL_1_0, TEST_ITERATIONS, TEST_TOLERANCE); }); + + assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M4_B, M4_X0, VAL_0_0, VAL_2_0, TEST_ITERATIONS, TEST_TOLERANCE); }); } @Test void testMismatchedDimensions() { - assertThrows( - IllegalArgumentException.class, - () -> { - ChebyshevIteration.solve( - M4_A, - M5_B, - M4_X0, - VAL_0_5, - VAL_1_5, - TEST_ITERATIONS, - TEST_TOLERANCE - ); - } - ); + assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M5_B, M4_X0, VAL_0_5, VAL_1_5, TEST_ITERATIONS, TEST_TOLERANCE); }); } @Test void testNonSquareMatrix() { - assertThrows( - IllegalArgumentException.class, - () -> { - ChebyshevIteration.solve( - M6_A, - M6_B, - M6_X0, - VAL_0_5, - VAL_1_5, - TEST_ITERATIONS, - TEST_TOLERANCE - ); - } - ); + assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M6_A, M6_B, M6_X0, VAL_0_5, VAL_1_5, TEST_ITERATIONS, TEST_TOLERANCE); }); } } From 24e219e7859b99c9ce785e82ec25ef0cefde1680 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:27:37 +0530 Subject: [PATCH 09/25] Update ChebyshevIteration.java --- .../maths/ChebyshevIteration.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 53a0f506c5b7..77d1cacf08de 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -31,7 +31,7 @@ private ChebyshevIteration() { /** * Solves the linear system Ax = b using Chebyshev Iteration. * - * @param A A symmetric positive definite matrix. + * @param a A symmetric positive definite matrix. * @param b The vector 'b' in the equation Ax = b. * @param x0 An initial guess vector for 'x'. * @param lambdaMin The smallest eigenvalue of matrix A. @@ -43,13 +43,12 @@ private ChebyshevIteration() { * match, * or if max/min eigenvalues are invalid. */ - // FIX: Method signature flattened to one line - public static double[] solve(double[][] A, double[] b, double[] x0, double lambdaMin, double lambdaMax, int maxIterations, double tolerance) { - validateInputs(A, b, x0, lambdaMin, lambdaMax); + public static double[] solve(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax, int maxIterations, double tolerance) { + validateInputs(a, b, x0, lambdaMin, lambdaMax); int n = b.length; double[] x = Arrays.copyOf(x0, n); - double[] r = vectorSubtract(b, matrixVectorMultiply(A, x)); + double[] r = vectorSubtract(b, matrixVectorMultiply(a, x)); // Use `a` double[] p = new double[n]; double alpha = 0.0; double beta = 0.0; @@ -66,7 +65,6 @@ public static double[] solve(double[][] A, double[] b, double[] x0, double lambd alpha = 1.0 / d; p = Arrays.copyOf(r, n); } else { - // Fix for algorithmic bug (use alphaPrev) double alphaPrev = alpha; beta = (c * alphaPrev / 2.0) * (c * alphaPrev / 2.0); @@ -81,7 +79,7 @@ public static double[] solve(double[][] A, double[] b, double[] x0, double lambd x = vectorAdd(x, pScaled); // Re-calculate residual to avoid accumulating floating-point errors - r = vectorSubtract(b, matrixVectorMultiply(A, x)); + r = vectorSubtract(b, matrixVectorMultiply(a, x)); // Use `a` if (vectorNorm(r) < tolerance) { break; // Converged @@ -91,12 +89,12 @@ public static double[] solve(double[][] A, double[] b, double[] x0, double lambd } // --- Helper Methods for Linear Algebra --- - private static void validateInputs(double[][] A, double[] b, double[] x0, double lambdaMin, double lambdaMax) { + private static void validateInputs(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax) { int n = b.length; if (n == 0) { throw new IllegalArgumentException("Vectors cannot be empty."); } - if (A.length != n || A[0].length != n) { + if (a.length != n || a[0].length != n) { // Use `a` throw new IllegalArgumentException("Matrix A must be square with dimensions n x n."); } if (x0.length != n) { @@ -110,13 +108,13 @@ private static void validateInputs(double[][] A, double[] b, double[] x0, double /** * Computes y = Ax */ - private static double[] matrixVectorMultiply(double[][] A, double[] x) { - int n = A.length; + private static double[] matrixVectorMultiply(double[][] a, double[] x) { + int n = a.length; // Use `a` double[] y = new double[n]; for (int i = 0; i < n; i++) { double sum = 0.0; for (int j = 0; j < n; j++) { - sum += A[i][j] * x[j]; + sum += a[i][j] * x[j]; // Use `a` } y[i] = sum; } From de0b3af902845c323a297b01bec477a130b7ea7a Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:28:31 +0530 Subject: [PATCH 10/25] Update ChebyshevIterationTest.java --- .../com/thealgorithms/maths/ChebyshevIterationTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index f37c12806e70..a7e9bb4c4f99 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -34,7 +34,7 @@ class ChebyshevIterationTest { private static final double M2_B1 = 10.0; private static final double M2_B2 = -4.0; private static final double M2_B3 = 24.0; - private static final double[] M2_B = {M2_B1, M2_B2, M2_B3}; + private static final double[] M2_B = {M1_B1, M2_B2, M2_B3}; private static final double[] M2_X0 = {0.0, 0.0, 0.0}; private static final double M2_E1 = 2.0; private static final double M2_E2 = -2.0; @@ -82,16 +82,16 @@ void testSolve3x3System() { @Test void testAlreadyConverged() { - + // Test case where the initial guess is already the solution double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_EXPECTED, M3_LAMBDA_MIN, M3_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testInvalidEigenvalues() { - + // lambdaMin >= lambdaMax assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M4_B, M4_X0, VAL_2_0, VAL_1_0, TEST_ITERATIONS, TEST_TOLERANCE); }); - + // lambdaMin <= 0 assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M4_B, M4_X0, VAL_0_0, VAL_2_0, TEST_ITERATIONS, TEST_TOLERANCE); }); } From 47968679f220854fb2814b1bfeefc08d4f07647a Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:47:55 +0530 Subject: [PATCH 11/25] Update ChebyshevIterationTest.java --- .../maths/ChebyshevIterationTest.java | 86 ++++--------------- 1 file changed, 16 insertions(+), 70 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index a7e9bb4c4f99..2589d0527f0f 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -7,101 +7,47 @@ class ChebyshevIterationTest { - // --- Constants for testSolveSimple2x2System --- - private static final double M1_A11 = 4.0; - private static final double M1_A12 = 1.0; - private static final double M1_A21 = 1.0; - private static final double M1_A22 = 3.0; - private static final double[][] M1_A = {{M1_A11, M1_A12}, {M1_A21, M1_A22}}; - - private static final double M1_B1 = 1.0; - private static final double M1_B2 = 2.0; - private static final double[] M1_B = {M1_B1, M1_B2}; - private static final double[] M1_X0 = {0.0, 0.0}; - - // Eigenvalues are (7 +/- sqrt(5)) / 2 + private static final double[][] M1_A = { { 4.0, 1.0 }, { 1.0, 3.0 } }; + private static final double[] M1_B = { 1.0, 2.0 }; + private static final double[] M1_X0 = { 0.0, 0.0 }; private static final double M1_LAMBDA_MIN = (7.0 - Math.sqrt(5.0)) / 2.0; private static final double M1_LAMBDA_MAX = (7.0 + Math.sqrt(5.0)) / 2.0; - private static final double M1_EXPECTED_X1 = 1.0 / 11.0; - private static final double M1_EXPECTED_X2 = 7.0 / 11.0; - private static final double[] M1_EXPECTED = {M1_EXPECTED_X1, M1_EXPECTED_X2}; + private static final double[] M1_EXPECTED = { 1.0 / 11.0, 7.0 / 11.0 }; - // --- Constants for testSolve3x3System --- - private static final double M2_A11 = 5.0; - private static final double M2_A22 = 2.0; - private static final double M2_A33 = 8.0; - private static final double[][] M2_A = {{M2_A11, 0.0, 0.0}, {0.0, M2_A22, 0.0}, {0.0, 0.0, M2_A33}}; - private static final double M2_B1 = 10.0; - private static final double M2_B2 = -4.0; - private static final double M2_B3 = 24.0; - private static final double[] M2_B = {M1_B1, M2_B2, M2_B3}; - private static final double[] M2_X0 = {0.0, 0.0, 0.0}; - private static final double M2_E1 = 2.0; - private static final double M2_E2 = -2.0; - private static final double M2_E3 = 3.0; - private static final double[] M2_EXPECTED = {M2_E1, M2_E2, M2_E3}; + private static final double[][] M2_A = { { 5.0, 0.0, 0.0 }, { 0.0, 2.0, 0.0 }, { 0.0, 0.0, 8.0 } }; + private static final double[] M2_B = { 10.0, -4.0, 24.0 }; + private static final double[] M2_X0 = { 0.0, 0.0, 0.0 }; + private static final double[] M2_EXPECTED = { 2.0, -2.0, 3.0 }; private static final double M2_LAMBDA_MIN = 2.0; private static final double M2_LAMBDA_MAX = 8.0; - // --- Constants for testAlreadyConverged --- - private static final double M3_LAMBDA_MIN = 2.38; - private static final double M3_LAMBDA_MAX = 4.62; - - // --- Constants for Invalid/Dimension Tests --- - private static final double VAL_0_0 = 0.0; - private static final double VAL_0_5 = 0.5; - private static final double VAL_1_0 = 1.0; - private static final double VAL_1_5 = 1.5; - private static final double VAL_2_0 = 2.0; - private static final double[][] M4_A = {{VAL_1_0, VAL_0_0}, {VAL_0_0, VAL_1_0}}; - private static final double[] M4_B = {VAL_1_0, VAL_1_0}; - private static final double[] M4_X0 = {VAL_0_0, VAL_0_0}; - private static final double[] M5_B = {VAL_1_0, VAL_1_0, VAL_1_0}; - private static final double[][] M6_A = {{VAL_1_0, VAL_0_0, VAL_0_0}, {VAL_0_0, VAL_1_0, VAL_0_0}}; - private static final double[] M6_B = {VAL_1_0, VAL_1_0}; - private static final double[] M6_X0 = {VAL_0_0, VAL_0_0}; - - // --- General Constants --- - private static final int MAX_ITERATIONS = 100; + private static final double MAX_ITERATIONS = 100; private static final double TOLERANCE = 1e-10; private static final double ASSERT_TOLERANCE = 1e-9; - private static final int TEST_ITERATIONS = 10; - private static final double TEST_TOLERANCE = 1e-5; @Test void testSolveSimple2x2System() { - double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_X0, M1_LAMBDA_MIN, M1_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); + double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_X0, M1_LAMBDA_MIN, M1_LAMBDA_MAX, 100, TOLERANCE); assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testSolve3x3System() { - double[] solution = ChebyshevIteration.solve(M2_A, M2_B, M2_X0, M2_LAMBDA_MIN, M2_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); + double[] solution = ChebyshevIteration.solve(M2_A, M2_B, M2_X0, M2_LAMBDA_MIN, M2_LAMBDA_MAX, 100, TOLERANCE); assertArrayEquals(M2_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testAlreadyConverged() { - // Test case where the initial guess is already the solution - double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_EXPECTED, M3_LAMBDA_MIN, M3_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); + double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_EXPECTED, M1_LAMBDA_MIN, M1_LAMBDA_MAX, 100, TOLERANCE); assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testInvalidEigenvalues() { - // lambdaMin >= lambdaMax - assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M4_B, M4_X0, VAL_2_0, VAL_1_0, TEST_ITERATIONS, TEST_TOLERANCE); }); - // lambdaMin <= 0 - assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M4_B, M4_X0, VAL_0_0, VAL_2_0, TEST_ITERATIONS, TEST_TOLERANCE); }); - } - - @Test - void testMismatchedDimensions() { - assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M4_A, M5_B, M4_X0, VAL_0_5, VAL_1_5, TEST_ITERATIONS, TEST_TOLERANCE); }); - } - - @Test - void testNonSquareMatrix() { - assertThrows(IllegalArgumentException.class, () -> { ChebyshevIteration.solve(M6_A, M6_B, M6_X0, VAL_0_5, VAL_1_5, TEST_ITERATIONS, TEST_TOLERANCE); }); + assertThrows(IllegalArgumentException.class, + () -> ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 2.0, 1.0, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, + () -> ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 0.0, 2.0, 10, 1e-5)); } } From 61a5fbf60a6f43a6564620a5e418a2caf1c5b365 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:48:20 +0530 Subject: [PATCH 12/25] Update ChebyshevIteration.java --- .../maths/ChebyshevIteration.java | 126 ++++++------------ 1 file changed, 41 insertions(+), 85 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 77d1cacf08de..071ba4878ece 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -6,49 +6,39 @@ * Implements the Chebyshev Iteration method for solving a system of linear * equations (Ax = b). * - * @author Mitrajit ghorui (github: keyKyrios) - * @see Wikipedia - * Page + * This iterative method requires: + * - Matrix A to be symmetric positive definite (SPD) + * - Knowledge of minimum (lambdaMin) and maximum (lambdaMax) eigenvalues * - * This is an iterative method that requires the matrix A to be - * symmetric positive definite (SPD). - * It also requires knowledge of the minimum (lambdaMin) and maximum - * (lambdaMax) - * eigenvalues of the matrix A. + * Reference: https://en.wikipedia.org/wiki/Chebyshev_iteration * - * The algorithm converges faster than simpler methods like Jacobi or - * Gauss-Seidel - * by using Chebyshev polynomials to optimize the update steps. + * Author: Mitrajit Ghorui (github: keyKyrios) */ public final class ChebyshevIteration { - /** - * Private constructor to prevent instantiation of this utility class. - */ private ChebyshevIteration() { } /** - * Solves the linear system Ax = b using Chebyshev Iteration. + * Solves Ax = b using Chebyshev Iteration. * - * @param a A symmetric positive definite matrix. - * @param b The vector 'b' in the equation Ax = b. - * @param x0 An initial guess vector for 'x'. - * @param lambdaMin The smallest eigenvalue of matrix A. - * @param lambdaMax The largest eigenvalue of matrix A. - * @param maxIterations The maximum number of iterations to perform. - * @param tolerance The desired tolerance for convergence (e.g., 1e-10). - * @return The solution vector 'x'. - * @throws IllegalArgumentException if matrix/vector dimensions don't - * match, - * or if max/min eigenvalues are invalid. + * @param A SPD matrix + * @param b vector b + * @param x0 initial guess + * @param lambdaMin minimum eigenvalue + * @param lambdaMax maximum eigenvalue + * @param maxIterations maximum iterations + * @param tolerance convergence tolerance + * @return solution vector x */ - public static double[] solve(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax, int maxIterations, double tolerance) { - validateInputs(a, b, x0, lambdaMin, lambdaMax); + public static double[] solve(double[][] A, double[] b, double[] x0, + double lambdaMin, double lambdaMax, + int maxIterations, double tolerance) { + validateInputs(A, b, x0, lambdaMin, lambdaMax); int n = b.length; double[] x = Arrays.copyOf(x0, n); - double[] r = vectorSubtract(b, matrixVectorMultiply(a, x)); // Use `a` + double[] r = vectorSubtract(b, matrixVectorMultiply(A, x)); double[] p = new double[n]; double alpha = 0.0; double beta = 0.0; @@ -66,105 +56,71 @@ public static double[] solve(double[][] a, double[] b, double[] x0, double lambd p = Arrays.copyOf(r, n); } else { double alphaPrev = alpha; - - beta = (c * alphaPrev / 2.0) * (c * alphaPrev / 2.0); + beta = Math.pow(c * alphaPrev / 2.0, 2); alpha = 1.0 / (d - beta / alphaPrev); - - double betaOverAlphaPrev = beta / alphaPrev; - double[] rScaled = vectorScale(p, betaOverAlphaPrev); - p = vectorAdd(r, rScaled); + p = vectorAdd(r, vectorScale(p, beta / alphaPrev)); } - double[] pScaled = vectorScale(p, alpha); - x = vectorAdd(x, pScaled); - - // Re-calculate residual to avoid accumulating floating-point errors - r = vectorSubtract(b, matrixVectorMultiply(a, x)); // Use `a` + x = vectorAdd(x, vectorScale(p, alpha)); + r = vectorSubtract(b, matrixVectorMultiply(A, x)); if (vectorNorm(r) < tolerance) { - break; // Converged + break; } } + return x; } - // --- Helper Methods for Linear Algebra --- - private static void validateInputs(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax) { + private static void validateInputs(double[][] A, double[] b, double[] x0, + double lambdaMin, double lambdaMax) { int n = b.length; - if (n == 0) { - throw new IllegalArgumentException("Vectors cannot be empty."); - } - if (a.length != n || a[0].length != n) { // Use `a` - throw new IllegalArgumentException("Matrix A must be square with dimensions n x n."); - } - if (x0.length != n) { + if (n == 0) throw new IllegalArgumentException("Vectors cannot be empty."); + if (A.length != n || A[0].length != n) + throw new IllegalArgumentException("Matrix A must be square (n x n)."); + if (x0.length != n) throw new IllegalArgumentException("Initial guess vector x0 must have length n."); - } - if (lambdaMin >= lambdaMax || lambdaMin <= 0) { + if (lambdaMin >= lambdaMax || lambdaMin <= 0) throw new IllegalArgumentException("Eigenvalues must satisfy 0 < lambdaMin < lambdaMax."); - } } - /** - * Computes y = Ax - */ - private static double[] matrixVectorMultiply(double[][] a, double[] x) { - int n = a.length; // Use `a` + private static double[] matrixVectorMultiply(double[][] A, double[] x) { + int n = A.length; double[] y = new double[n]; for (int i = 0; i < n; i++) { double sum = 0.0; for (int j = 0; j < n; j++) { - sum += a[i][j] * x[j]; // Use `a` + sum += A[i][j] * x[j]; } y[i] = sum; } return y; } - /** - * Computes c = a + b - */ private static double[] vectorAdd(double[] a, double[] b) { int n = a.length; double[] c = new double[n]; - for (int i = 0; i < n; i++) { - c[i] = a[i] + b[i]; - } + for (int i = 0; i < n; i++) c[i] = a[i] + b[i]; return c; } - /** - * Computes c = a - b - */ private static double[] vectorSubtract(double[] a, double[] b) { int n = a.length; double[] c = new double[n]; - for (int i = 0; i < n; i++) { - c[i] = a[i] - b[i]; - } + for (int i = 0; i < n; i++) c[i] = a[i] - b[i]; return c; } - /** - * Computes c = a * scalar - */ private static double[] vectorScale(double[] a, double scalar) { int n = a.length; double[] c = new double[n]; - for (int i = 0; i < n; i++) { - c[i] = a[i] * scalar; - } + for (int i = 0; i < n; i++) c[i] = a[i] * scalar; return c; } - /** - * Computes the L2 norm (Euclidean norm) of a vector - */ private static double vectorNorm(double[] a) { - double sumOfSquares = 0.0; - for (double val : a) { - sumOfSquares += val * val; - } - return Math.sqrt(sumOfSquares); + double sum = 0.0; + for (double val : a) sum += val * val; + return Math.sqrt(sum); } } From b4e47fc201e6c0c25600543e83d01bff396be2d0 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:52:21 +0530 Subject: [PATCH 13/25] Update ChebyshevIteration.java --- .../maths/ChebyshevIteration.java | 55 +++++++++++-------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 071ba4878ece..4756f1f2d934 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -7,7 +7,7 @@ * equations (Ax = b). * * This iterative method requires: - * - Matrix A to be symmetric positive definite (SPD) + * - Matrix a to be symmetric positive definite (SPD) * - Knowledge of minimum (lambdaMin) and maximum (lambdaMax) eigenvalues * * Reference: https://en.wikipedia.org/wiki/Chebyshev_iteration @@ -20,9 +20,9 @@ private ChebyshevIteration() { } /** - * Solves Ax = b using Chebyshev Iteration. + * Solves ax = b using Chebyshev Iteration. * - * @param A SPD matrix + * @param a SPD matrix * @param b vector b * @param x0 initial guess * @param lambdaMin minimum eigenvalue @@ -31,14 +31,13 @@ private ChebyshevIteration() { * @param tolerance convergence tolerance * @return solution vector x */ - public static double[] solve(double[][] A, double[] b, double[] x0, - double lambdaMin, double lambdaMax, + public static double[] solve(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax, int maxIterations, double tolerance) { - validateInputs(A, b, x0, lambdaMin, lambdaMax); + validateInputs(a, b, x0, lambdaMin, lambdaMax); int n = b.length; double[] x = Arrays.copyOf(x0, n); - double[] r = vectorSubtract(b, matrixVectorMultiply(A, x)); + double[] r = vectorSubtract(b, matrixVectorMultiply(a, x)); double[] p = new double[n]; double alpha = 0.0; double beta = 0.0; @@ -62,7 +61,7 @@ public static double[] solve(double[][] A, double[] b, double[] x0, } x = vectorAdd(x, vectorScale(p, alpha)); - r = vectorSubtract(b, matrixVectorMultiply(A, x)); + r = vectorSubtract(b, matrixVectorMultiply(a, x)); if (vectorNorm(r) < tolerance) { break; @@ -72,25 +71,29 @@ public static double[] solve(double[][] A, double[] b, double[] x0, return x; } - private static void validateInputs(double[][] A, double[] b, double[] x0, - double lambdaMin, double lambdaMax) { + private static void validateInputs(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax) { int n = b.length; - if (n == 0) throw new IllegalArgumentException("Vectors cannot be empty."); - if (A.length != n || A[0].length != n) - throw new IllegalArgumentException("Matrix A must be square (n x n)."); - if (x0.length != n) + if (n == 0) { + throw new IllegalArgumentException("Vectors cannot be empty."); + } + if (a.length != n || a[0].length != n) { + throw new IllegalArgumentException("Matrix a must be square (n x n)."); + } + if (x0.length != n) { throw new IllegalArgumentException("Initial guess vector x0 must have length n."); - if (lambdaMin >= lambdaMax || lambdaMin <= 0) + } + if (lambdaMin >= lambdaMax || lambdaMin <= 0) { throw new IllegalArgumentException("Eigenvalues must satisfy 0 < lambdaMin < lambdaMax."); + } } - private static double[] matrixVectorMultiply(double[][] A, double[] x) { - int n = A.length; + private static double[] matrixVectorMultiply(double[][] a, double[] x) { + int n = a.length; double[] y = new double[n]; for (int i = 0; i < n; i++) { double sum = 0.0; for (int j = 0; j < n; j++) { - sum += A[i][j] * x[j]; + sum += a[i][j] * x[j]; } y[i] = sum; } @@ -100,27 +103,35 @@ private static double[] matrixVectorMultiply(double[][] A, double[] x) { private static double[] vectorAdd(double[] a, double[] b) { int n = a.length; double[] c = new double[n]; - for (int i = 0; i < n; i++) c[i] = a[i] + b[i]; + for (int i = 0; i < n; i++) { + c[i] = a[i] + b[i]; + } return c; } private static double[] vectorSubtract(double[] a, double[] b) { int n = a.length; double[] c = new double[n]; - for (int i = 0; i < n; i++) c[i] = a[i] - b[i]; + for (int i = 0; i < n; i++) { + c[i] = a[i] - b[i]; + } return c; } private static double[] vectorScale(double[] a, double scalar) { int n = a.length; double[] c = new double[n]; - for (int i = 0; i < n; i++) c[i] = a[i] * scalar; + for (int i = 0; i < n; i++) { + c[i] = a[i] * scalar; + } return c; } private static double vectorNorm(double[] a) { double sum = 0.0; - for (double val : a) sum += val * val; + for (double val : a) { + sum += val * val; + } return Math.sqrt(sum); } } From e00efa5056698026d6543a08e53c78caf5efe736 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Mon, 27 Oct 2025 04:53:24 +0530 Subject: [PATCH 14/25] Update ChebyshevIterationTest.java --- .../maths/ChebyshevIterationTest.java | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index 2589d0527f0f..47fe833528ff 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -5,49 +5,55 @@ import org.junit.jupiter.api.Test; +/** + * Unit tests for ChebyshevIteration class + */ class ChebyshevIterationTest { - private static final double[][] M1_A = { { 4.0, 1.0 }, { 1.0, 3.0 } }; - private static final double[] M1_B = { 1.0, 2.0 }; - private static final double[] M1_X0 = { 0.0, 0.0 }; + private static final double[][] M1_A = {{4.0, 1.0}, {1.0, 3.0}}; + private static final double[] M1_B = {1.0, 2.0}; + private static final double[] M1_X0 = {0.0, 0.0}; private static final double M1_LAMBDA_MIN = (7.0 - Math.sqrt(5.0)) / 2.0; private static final double M1_LAMBDA_MAX = (7.0 + Math.sqrt(5.0)) / 2.0; - private static final double[] M1_EXPECTED = { 1.0 / 11.0, 7.0 / 11.0 }; + private static final double[] M1_EXPECTED = {1.0 / 11.0, 7.0 / 11.0}; - private static final double[][] M2_A = { { 5.0, 0.0, 0.0 }, { 0.0, 2.0, 0.0 }, { 0.0, 0.0, 8.0 } }; - private static final double[] M2_B = { 10.0, -4.0, 24.0 }; - private static final double[] M2_X0 = { 0.0, 0.0, 0.0 }; - private static final double[] M2_EXPECTED = { 2.0, -2.0, 3.0 }; + private static final double[][] M2_A = {{5.0, 0.0, 0.0}, {0.0, 2.0, 0.0}, {0.0, 0.0, 8.0}}; + private static final double[] M2_B = {10.0, -4.0, 24.0}; + private static final double[] M2_X0 = {0.0, 0.0, 0.0}; + private static final double[] M2_EXPECTED = {2.0, -2.0, 3.0}; private static final double M2_LAMBDA_MIN = 2.0; private static final double M2_LAMBDA_MAX = 8.0; - private static final double MAX_ITERATIONS = 100; + private static final int MAX_ITERATIONS = 1000; private static final double TOLERANCE = 1e-10; private static final double ASSERT_TOLERANCE = 1e-9; @Test - void testSolveSimple2x2System() { - double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_X0, M1_LAMBDA_MIN, M1_LAMBDA_MAX, 100, TOLERANCE); + void testSolve2x2System() { + double[] solution = ChebyshevIteration.solve( + M1_A, M1_B, M1_X0, M1_LAMBDA_MIN, M1_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testSolve3x3System() { - double[] solution = ChebyshevIteration.solve(M2_A, M2_B, M2_X0, M2_LAMBDA_MIN, M2_LAMBDA_MAX, 100, TOLERANCE); + double[] solution = ChebyshevIteration.solve( + M2_A, M2_B, M2_X0, M2_LAMBDA_MIN, M2_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); assertArrayEquals(M2_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testAlreadyConverged() { - double[] solution = ChebyshevIteration.solve(M1_A, M1_B, M1_EXPECTED, M1_LAMBDA_MIN, M1_LAMBDA_MAX, 100, TOLERANCE); + double[] solution = ChebyshevIteration.solve( + M1_A, M1_B, M1_EXPECTED, M1_LAMBDA_MIN, M1_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); } @Test void testInvalidEigenvalues() { - assertThrows(IllegalArgumentException.class, - () -> ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 2.0, 1.0, 10, 1e-5)); - assertThrows(IllegalArgumentException.class, - () -> ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 0.0, 2.0, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> + ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 2.0, 1.0, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> + ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 0.0, 2.0, 10, 1e-5)); } } From b31588235ba2849c8e519112a7d893ed846a774f Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 19:46:47 +0530 Subject: [PATCH 15/25] Update ChebyshevIteration.java --- .../maths/ChebyshevIteration.java | 216 +++++++++++------- 1 file changed, 138 insertions(+), 78 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 4756f1f2d934..4ab57e809503 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -1,137 +1,197 @@ package com.thealgorithms.maths; -import java.util.Arrays; - /** - * Implements the Chebyshev Iteration method for solving a system of linear - * equations (Ax = b). + * In numerical analysis, Chebyshev iteration is an iterative method for solving + * systems of linear equations Ax = b. It is designed for systems where the + * matrix A is symmetric positive-definite (SPD). + * + *

+ * This method is a "polynomial acceleration" method, meaning it finds the + * optimal polynomial to apply to the residual to accelerate convergence. * - * This iterative method requires: - * - Matrix a to be symmetric positive definite (SPD) - * - Knowledge of minimum (lambdaMin) and maximum (lambdaMax) eigenvalues + *

+ * It requires knowledge of the bounds of the eigenvalues of the matrix A: + * m(A) (smallest eigenvalue) and M(A) (largest eigenvalue). * - * Reference: https://en.wikipedia.org/wiki/Chebyshev_iteration + *

+ * Wikipedia: https://en.wikipedia.org/wiki/Chebyshev_iteration * - * Author: Mitrajit Ghorui (github: keyKyrios) + * @author Mitrajit Ghorui(KeyKyrios) */ -public final class ChebyshevIteration { +public final class Chebyshev { - private ChebyshevIteration() { + private Chebyshev() { } /** - * Solves ax = b using Chebyshev Iteration. + * Solves the linear system Ax = b using the Chebyshev iteration method. * - * @param a SPD matrix - * @param b vector b - * @param x0 initial guess - * @param lambdaMin minimum eigenvalue - * @param lambdaMax maximum eigenvalue - * @param maxIterations maximum iterations - * @param tolerance convergence tolerance - * @return solution vector x + *

+ * NOTE: The matrix A *must* be symmetric positive-definite (SPD) for this + * algorithm to converge. + * + * @param a The matrix A (must be square, SPD). + * @param b The vector b. + * @param x0 The initial guess vector. + * @param minEigenvalue The smallest eigenvalue of A (m(A)). + * @param maxEigenvalue The largest eigenvalue of A (M(A)). + * @param maxIterations The maximum number of iterations to perform. + * @param tolerance The desired tolerance for the residual norm. + * @return The solution vector x. + * @throws IllegalArgumentException if matrix/vector dimensions are + * incompatible, + * if maxIterations <= 0, or if eigenvalues are invalid (e.g., minEigenvalue + * <= 0, maxEigenvalue <= minEigenvalue). */ - public static double[] solve(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax, - int maxIterations, double tolerance) { - validateInputs(a, b, x0, lambdaMin, lambdaMax); + public static double[] solve( + double[][] a, + double[] b, + double[] x0, + double minEigenvalue, + double maxEigenvalue, + int maxIterations, + double tolerance + ) { + validateInputs(a, b, x0, minEigenvalue, maxEigenvalue, maxIterations, tolerance); int n = b.length; - double[] x = Arrays.copyOf(x0, n); + double[] x = x0.clone(); double[] r = vectorSubtract(b, matrixVectorMultiply(a, x)); double[] p = new double[n]; + + double d = (maxEigenvalue + minEigenvalue) / 2.0; + double c = (maxEigenvalue - minEigenvalue) / 2.0; + double alpha = 0.0; - double beta = 0.0; - double c = (lambdaMax - lambdaMin) / 2.0; - double d = (lambdaMax + lambdaMin) / 2.0; + double alphaPrev = 0.0; - double initialResidualNorm = vectorNorm(r); - if (initialResidualNorm < tolerance) { - return x; // Already converged - } + for (int k = 0; k < maxIterations; k++) { + double residualNorm = vectorNorm(r); + if (residualNorm < tolerance) { + return x; // Solution converged + } - for (int k = 1; k <= maxIterations; k++) { - if (k == 1) { + if (k == 0) { alpha = 1.0 / d; - p = Arrays.copyOf(r, n); + System.arraycopy(r, 0, p, 0, n); // p = r } else { - double alphaPrev = alpha; - beta = Math.pow(c * alphaPrev / 2.0, 2); + double beta = (c * alphaPrev / 2.0) * (c * alphaPrev / 2.0); alpha = 1.0 / (d - beta / alphaPrev); - p = vectorAdd(r, vectorScale(p, beta / alphaPrev)); + double[] pUpdate = scalarMultiply(beta / alphaPrev, p); + p = vectorAdd(r, pUpdate); // p = r + (beta / alphaPrev) * p } - x = vectorAdd(x, vectorScale(p, alpha)); - r = vectorSubtract(b, matrixVectorMultiply(a, x)); + double[] xUpdate = scalarMultiply(alpha, p); + x = vectorAdd(x, xUpdate); // x = x + alpha * p - if (vectorNorm(r) < tolerance) { - break; - } + // Recompute residual for accuracy, though it can be updated iteratively + r = vectorSubtract(b, matrixVectorMultiply(a, x)); + alphaPrev = alpha; } - return x; + return x; // Return best guess after maxIterations } - private static void validateInputs(double[][] a, double[] b, double[] x0, double lambdaMin, double lambdaMax) { - int n = b.length; + /** + * Validates the inputs for the Chebyshev solver. + */ + private static void validateInputs( + double[][] a, + double[] b, + double[] x0, + double minEigenvalue, + double maxEigenvalue, + int maxIterations, + double tolerance + ) { + int n = a.length; if (n == 0) { - throw new IllegalArgumentException("Vectors cannot be empty."); + throw new IllegalArgumentException("Matrix A cannot be empty."); + } + if (n != a[0].length) { + throw new IllegalArgumentException("Matrix A must be square."); + } + if (n != b.length) { + throw new IllegalArgumentException("Matrix A and vector b dimensions do not match."); } - if (a.length != n || a[0].length != n) { - throw new IllegalArgumentException("Matrix a must be square (n x n)."); + if (n != x0.length) { + throw new IllegalArgumentException("Matrix A and vector x0 dimensions do not match."); } - if (x0.length != n) { - throw new IllegalArgumentException("Initial guess vector x0 must have length n."); + if (minEigenvalue <= 0) { + throw new IllegalArgumentException("Smallest eigenvalue must be positive (matrix must be positive-definite)."); } - if (lambdaMin >= lambdaMax || lambdaMin <= 0) { - throw new IllegalArgumentException("Eigenvalues must satisfy 0 < lambdaMin < lambdaMax."); + if (maxEigenvalue <= minEigenvalue) { + throw new IllegalArgumentException("Max eigenvalue must be strictly greater than min eigenvalue."); + } + if (maxIterations <= 0) { + throw new IllegalArgumentException("Max iterations must be positive."); + } + if (tolerance <= 0) { + throw new IllegalArgumentException("Tolerance must be positive."); } } - private static double[] matrixVectorMultiply(double[][] a, double[] x) { + // --- Vector/Matrix Helper Methods --- + /** + * Computes the product of a matrix A and a vector v (Av). + */ + private static double[] matrixVectorMultiply(double[][] a, double[] v) { int n = a.length; - double[] y = new double[n]; + double[] result = new double[n]; for (int i = 0; i < n; i++) { - double sum = 0.0; + double sum = 0; for (int j = 0; j < n; j++) { - sum += a[i][j] * x[j]; + sum += a[i][j] * v[j]; } - y[i] = sum; + result[i] = sum; } - return y; + return result; } - private static double[] vectorAdd(double[] a, double[] b) { - int n = a.length; - double[] c = new double[n]; + /** + * Computes the subtraction of two vectors (v1 - v2). + */ + private static double[] vectorSubtract(double[] v1, double[] v2) { + int n = v1.length; + double[] result = new double[n]; for (int i = 0; i < n; i++) { - c[i] = a[i] + b[i]; + result[i] = v1[i] - v2[i]; } - return c; + return result; } - private static double[] vectorSubtract(double[] a, double[] b) { - int n = a.length; - double[] c = new double[n]; + /** + * Computes the addition of two vectors (v1 + v2). + */ + private static double[] vectorAdd(double[] v1, double[] v2) { + int n = v1.length; + double[] result = new double[n]; for (int i = 0; i < n; i++) { - c[i] = a[i] - b[i]; + result[i] = v1[i] + v2[i]; } - return c; + return result; } - private static double[] vectorScale(double[] a, double scalar) { - int n = a.length; - double[] c = new double[n]; + /** + * Computes the product of a scalar and a vector (s * v). + */ + private static double[] scalarMultiply(double scalar, double[] v) { + int n = v.length; + double[] result = new double[n]; for (int i = 0; i < n; i++) { - c[i] = a[i] * scalar; + result[i] = scalar * v[i]; } - return c; + return result; } - private static double vectorNorm(double[] a) { - double sum = 0.0; - for (double val : a) { - sum += val * val; + /** + * Computes the L2 norm (Euclidean norm) of a vector. + */ + private static double vectorNorm(double[] v) { + double sumOfSquares = 0; + for (double val : v) { + sumOfSquares += val * val; } - return Math.sqrt(sum); + return Math.sqrt(sumOfSquares); } } From 3968a1ec39711e279748ee370162e95e42e82469 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 19:46:56 +0530 Subject: [PATCH 16/25] Update ChebyshevIterationTest.java --- .../maths/ChebyshevIterationTest.java | 132 +++++++++++++----- 1 file changed, 96 insertions(+), 36 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index 47fe833528ff..5c34ed32f8da 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -5,55 +5,115 @@ import org.junit.jupiter.api.Test; -/** - * Unit tests for ChebyshevIteration class - */ -class ChebyshevIterationTest { +public class ChebyshevTest { - private static final double[][] M1_A = {{4.0, 1.0}, {1.0, 3.0}}; - private static final double[] M1_B = {1.0, 2.0}; - private static final double[] M1_X0 = {0.0, 0.0}; - private static final double M1_LAMBDA_MIN = (7.0 - Math.sqrt(5.0)) / 2.0; - private static final double M1_LAMBDA_MAX = (7.0 + Math.sqrt(5.0)) / 2.0; - private static final double[] M1_EXPECTED = {1.0 / 11.0, 7.0 / 11.0}; + @Test + public void testSolveSimple2x2Diagonal() { + // A = [[2, 0], [0, 1]] (SPD) + // Eigenvalues: m=1, M=2 + // b = [2, 2] + // Exact solution: x = [1, 2] + double[][] a = { { 2, 0 }, { 0, 1 } }; + double[] b = { 2, 2 }; + double[] x0 = { 0, 0 }; + double minEig = 1.0; + double maxEig = 2.0; + int maxIter = 50; + double tol = 1e-9; + double[] expected = { 1.0, 2.0 }; + + double[] result = Chebyshev.solve(a, b, x0, minEig, maxEig, maxIter, tol); + assertArrayEquals(expected, result, 1e-9); + } + + @Test + public void testSolve2x2Symmetric() { + // A = [[4, 1], [1, 3]] (SPD) + // Eigenvalues = (7 +/- sqrt(5)) / 2 + // m ≈ 2.3819, M ≈ 4.6180 + // b = [1, 2] + // Exact solution: x = [1/11, 7/11] + double[][] a = { { 4, 1 }, { 1, 3 } }; + double[] b = { 1, 2 }; + double[] x0 = { 0, 0 }; + double minEig = (7.0 - Math.sqrt(5.0)) / 2.0; + double maxEig = (7.0 + Math.sqrt(5.0)) / 2.0; + int maxIter = 100; + double tol = 1e-10; + double[] expected = { 1.0 / 11.0, 7.0 / 11.0 }; + + double[] result = Chebyshev.solve(a, b, x0, minEig, maxEig, maxIter, tol); + assertArrayEquals(expected, result, 1e-9); + } - private static final double[][] M2_A = {{5.0, 0.0, 0.0}, {0.0, 2.0, 0.0}, {0.0, 0.0, 8.0}}; - private static final double[] M2_B = {10.0, -4.0, 24.0}; - private static final double[] M2_X0 = {0.0, 0.0, 0.0}; - private static final double[] M2_EXPECTED = {2.0, -2.0, 3.0}; - private static final double M2_LAMBDA_MIN = 2.0; - private static final double M2_LAMBDA_MAX = 8.0; + @Test + public void testAlreadyAtSolution() { + // Test if the initial guess is already the solution + double[][] a = { { 2, 0 }, { 0, 1 } }; + double[] b = { 2, 2 }; + double[] x0 = { 1, 2 }; // Initial guess is the solution + double minEig = 1.0; + double maxEig = 2.0; + int maxIter = 10; + double tol = 1e-5; + double[] expected = { 1.0, 2.0 }; - private static final int MAX_ITERATIONS = 1000; - private static final double TOLERANCE = 1e-10; - private static final double ASSERT_TOLERANCE = 1e-9; + double[] result = Chebyshev.solve(a, b, x0, minEig, maxEig, maxIter, tol); + assertArrayEquals(expected, result, 0.0); // Should be exact + } + + @Test + public void testMismatchedDimensionsAB() { + double[][] a = { { 1, 0 }, { 0, 1 } }; + double[] b = { 1 }; // Should be length 2 + double[] x0 = { 0, 0 }; + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 10, 1e-5)); + } + + @Test + public void testMismatchedDimensionsAX() { + double[][] a = { { 1, 0 }, { 0, 1 } }; + double[] b = { 1, 1 }; + double[] x0 = { 0 }; // Should be length 2 + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 10, 1e-5)); + } @Test - void testSolve2x2System() { - double[] solution = ChebyshevIteration.solve( - M1_A, M1_B, M1_X0, M1_LAMBDA_MIN, M1_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); - assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); + public void testNonSquareMatrix() { + double[][] a = { { 1, 0, 0 }, { 0, 1, 0 } }; // 2x3 + double[] b = { 1, 1 }; + double[] x0 = { 0, 0 }; // This check will fail first + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 10, 1e-5)); } @Test - void testSolve3x3System() { - double[] solution = ChebyshevIteration.solve( - M2_A, M2_B, M2_X0, M2_LAMBDA_MIN, M2_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); - assertArrayEquals(M2_EXPECTED, solution, ASSERT_TOLERANCE); + public void testInvalidEigenvalues() { + double[][] a = { { 1, 0 }, { 0, 1 } }; + double[] b = { 1, 1 }; + double[] x0 = { 0, 0 }; + // min > max + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 2, 1, 10, 1e-5)); + // min == max + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 1, 10, 1e-5)); } @Test - void testAlreadyConverged() { - double[] solution = ChebyshevIteration.solve( - M1_A, M1_B, M1_EXPECTED, M1_LAMBDA_MIN, M1_LAMBDA_MAX, MAX_ITERATIONS, TOLERANCE); - assertArrayEquals(M1_EXPECTED, solution, ASSERT_TOLERANCE); + public void testNonPositiveDefinite() { + double[][] a = { { 1, 0 }, { 0, 1 } }; + double[] b = { 1, 1 }; + double[] x0 = { 0, 0 }; + // min = 0 + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 0, 1, 10, 1e-5)); + // min < 0 + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, -1, 1, 10, 1e-5)); } @Test - void testInvalidEigenvalues() { - assertThrows(IllegalArgumentException.class, () -> - ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 2.0, 1.0, 10, 1e-5)); - assertThrows(IllegalArgumentException.class, () -> - ChebyshevIteration.solve(M1_A, M1_B, M1_X0, 0.0, 2.0, 10, 1e-5)); + public void testInvalidIterationCount() { + double[][] a = { { 1, 0 }, { 0, 1 } }; + double[] b = { 1, 1 }; + double[] x0 = { 0, 0 }; + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 0, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, -1, 1e-5)); } } From 3cd55db000cbbb722ecc9fe5b6fe7fbcf10ddaad Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 19:54:37 +0530 Subject: [PATCH 17/25] Update ChebyshevIteration.java --- .../maths/ChebyshevIteration.java | 49 ++----------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 4ab57e809503..75228a188dec 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -18,9 +18,9 @@ * * @author Mitrajit Ghorui(KeyKyrios) */ -public final class Chebyshev { +public final class ChebyshevIteration { - private Chebyshev() { + private ChebyshevIteration() { } /** @@ -84,7 +84,7 @@ public static double[] solve( double[] xUpdate = scalarMultiply(alpha, p); x = vectorAdd(x, xUpdate); // x = x + alpha * p - // Recompute residual for accuracy, though it can be updated iteratively + // Recompute residual for accuracy r = vectorSubtract(b, matrixVectorMultiply(a, x)); alphaPrev = alpha; } @@ -132,9 +132,6 @@ private static void validateInputs( } // --- Vector/Matrix Helper Methods --- - /** - * Computes the product of a matrix A and a vector v (Av). - */ private static double[] matrixVectorMultiply(double[][] a, double[] v) { int n = a.length; double[] result = new double[n]; @@ -148,9 +145,6 @@ private static double[] matrixVectorMultiply(double[][] a, double[] v) { return result; } - /** - * Computes the subtraction of two vectors (v1 - v2). - */ private static double[] vectorSubtract(double[] v1, double[] v2) { int n = v1.length; double[] result = new double[n]; @@ -158,40 +152,3 @@ private static double[] vectorSubtract(double[] v1, double[] v2) { result[i] = v1[i] - v2[i]; } return result; - } - - /** - * Computes the addition of two vectors (v1 + v2). - */ - private static double[] vectorAdd(double[] v1, double[] v2) { - int n = v1.length; - double[] result = new double[n]; - for (int i = 0; i < n; i++) { - result[i] = v1[i] + v2[i]; - } - return result; - } - - /** - * Computes the product of a scalar and a vector (s * v). - */ - private static double[] scalarMultiply(double scalar, double[] v) { - int n = v.length; - double[] result = new double[n]; - for (int i = 0; i < n; i++) { - result[i] = scalar * v[i]; - } - return result; - } - - /** - * Computes the L2 norm (Euclidean norm) of a vector. - */ - private static double vectorNorm(double[] v) { - double sumOfSquares = 0; - for (double val : v) { - sumOfSquares += val * val; - } - return Math.sqrt(sumOfSquares); - } -} From 5226d9b8de9c21a84f7d8b49234891060262f738 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 19:55:30 +0530 Subject: [PATCH 18/25] Update ChebyshevIterationTest.java --- .../maths/ChebyshevIterationTest.java | 52 +++++++------------ 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index 5c34ed32f8da..477262967bee 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -5,14 +5,10 @@ import org.junit.jupiter.api.Test; -public class ChebyshevTest { +public class ChebyshevIterationTest { @Test public void testSolveSimple2x2Diagonal() { - // A = [[2, 0], [0, 1]] (SPD) - // Eigenvalues: m=1, M=2 - // b = [2, 2] - // Exact solution: x = [1, 2] double[][] a = { { 2, 0 }, { 0, 1 } }; double[] b = { 2, 2 }; double[] x0 = { 0, 0 }; @@ -22,17 +18,12 @@ public void testSolveSimple2x2Diagonal() { double tol = 1e-9; double[] expected = { 1.0, 2.0 }; - double[] result = Chebyshev.solve(a, b, x0, minEig, maxEig, maxIter, tol); + double[] result = ChebyshevIteration.solve(a, b, x0, minEig, maxEig, maxIter, tol); assertArrayEquals(expected, result, 1e-9); } @Test public void testSolve2x2Symmetric() { - // A = [[4, 1], [1, 3]] (SPD) - // Eigenvalues = (7 +/- sqrt(5)) / 2 - // m ≈ 2.3819, M ≈ 4.6180 - // b = [1, 2] - // Exact solution: x = [1/11, 7/11] double[][] a = { { 4, 1 }, { 1, 3 } }; double[] b = { 1, 2 }; double[] x0 = { 0, 0 }; @@ -42,48 +33,47 @@ public void testSolve2x2Symmetric() { double tol = 1e-10; double[] expected = { 1.0 / 11.0, 7.0 / 11.0 }; - double[] result = Chebyshev.solve(a, b, x0, minEig, maxEig, maxIter, tol); + double[] result = ChebyshevIteration.solve(a, b, x0, minEig, maxEig, maxIter, tol); assertArrayEquals(expected, result, 1e-9); } @Test public void testAlreadyAtSolution() { - // Test if the initial guess is already the solution double[][] a = { { 2, 0 }, { 0, 1 } }; double[] b = { 2, 2 }; - double[] x0 = { 1, 2 }; // Initial guess is the solution + double[] x0 = { 1, 2 }; double minEig = 1.0; double maxEig = 2.0; int maxIter = 10; double tol = 1e-5; double[] expected = { 1.0, 2.0 }; - double[] result = Chebyshev.solve(a, b, x0, minEig, maxEig, maxIter, tol); - assertArrayEquals(expected, result, 0.0); // Should be exact + double[] result = ChebyshevIteration.solve(a, b, x0, minEig, maxEig, maxIter, tol); + assertArrayEquals(expected, result, 0.0); } @Test public void testMismatchedDimensionsAB() { double[][] a = { { 1, 0 }, { 0, 1 } }; - double[] b = { 1 }; // Should be length 2 + double[] b = { 1 }; double[] x0 = { 0, 0 }; - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 10, 1e-5)); } @Test public void testMismatchedDimensionsAX() { double[][] a = { { 1, 0 }, { 0, 1 } }; double[] b = { 1, 1 }; - double[] x0 = { 0 }; // Should be length 2 - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 10, 1e-5)); + double[] x0 = { 0 }; + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 10, 1e-5)); } @Test public void testNonSquareMatrix() { - double[][] a = { { 1, 0, 0 }, { 0, 1, 0 } }; // 2x3 + double[][] a = { { 1, 0, 0 }, { 0, 1, 0 } }; double[] b = { 1, 1 }; - double[] x0 = { 0, 0 }; // This check will fail first - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 10, 1e-5)); + double[] x0 = { 0, 0 }; + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 10, 1e-5)); } @Test @@ -91,10 +81,8 @@ public void testInvalidEigenvalues() { double[][] a = { { 1, 0 }, { 0, 1 } }; double[] b = { 1, 1 }; double[] x0 = { 0, 0 }; - // min > max - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 2, 1, 10, 1e-5)); - // min == max - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 1, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 2, 1, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 1, 10, 1e-5)); } @Test @@ -102,10 +90,8 @@ public void testNonPositiveDefinite() { double[][] a = { { 1, 0 }, { 0, 1 } }; double[] b = { 1, 1 }; double[] x0 = { 0, 0 }; - // min = 0 - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 0, 1, 10, 1e-5)); - // min < 0 - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, -1, 1, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 0, 1, 10, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, -1, 1, 10, 1e-5)); } @Test @@ -113,7 +99,7 @@ public void testInvalidIterationCount() { double[][] a = { { 1, 0 }, { 0, 1 } }; double[] b = { 1, 1 }; double[] x0 = { 0, 0 }; - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, 0, 1e-5)); - assertThrows(IllegalArgumentException.class, () -> Chebyshev.solve(a, b, x0, 1, 2, -1, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 0, 1e-5)); + assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, -1, 1e-5)); } } From 4874dc35ccd7fc0b673669f25d6cb43e78ab1a59 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 14:43:30 +0000 Subject: [PATCH 19/25] update --- .../maths/ChebyshevIteration.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 75228a188dec..9fb6c6ea0351 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -132,6 +132,9 @@ private static void validateInputs( } // --- Vector/Matrix Helper Methods --- + /** + * Computes the product of a matrix A and a vector v (Av). + */ private static double[] matrixVectorMultiply(double[][] a, double[] v) { int n = a.length; double[] result = new double[n]; @@ -145,6 +148,9 @@ private static double[] matrixVectorMultiply(double[][] a, double[] v) { return result; } + /** + * Computes the subtraction of two vectors (v1 - v2). + */ private static double[] vectorSubtract(double[] v1, double[] v2) { int n = v1.length; double[] result = new double[n]; @@ -152,3 +158,40 @@ private static double[] vectorSubtract(double[] v1, double[] v2) { result[i] = v1[i] - v2[i]; } return result; + } + + /** + * Computes the addition of two vectors (v1 + v2). + */ + private static double[] vectorAdd(double[] v1, double[] v2) { + int n = v1.length; + double[] result = new double[n]; + for (int i = 0; i < n; i++) { + result[i] = v1[i] + v2[i]; + } + return result; + } + + /** + * Computes the product of a scalar and a vector (s * v). + */ + private static double[] scalarMultiply(double scalar, double[] v) { + int n = v.length; + double[] result = new double[n]; + for (int i = 0; i < n; i++) { + result[i] = scalar * v[i]; + } + return result; + } + + /** + * Computes the L2 norm (Euclidean norm) of a vector. + */ + private static double vectorNorm(double[] v) { + double sumOfSquares = 0; + for (double val : v) { + sumOfSquares += val * val; + } + return Math.sqrt(sumOfSquares); + } +} \ No newline at end of file From 2bf25806d908141d0d27ddd915b0bc00f19a85da Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 20:24:07 +0530 Subject: [PATCH 20/25] Update ChebyshevIteration.java --- .../maths/ChebyshevIteration.java | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 9fb6c6ea0351..19b5ed5e03d4 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -43,15 +43,7 @@ private ChebyshevIteration() { * if maxIterations <= 0, or if eigenvalues are invalid (e.g., minEigenvalue * <= 0, maxEigenvalue <= minEigenvalue). */ - public static double[] solve( - double[][] a, - double[] b, - double[] x0, - double minEigenvalue, - double maxEigenvalue, - int maxIterations, - double tolerance - ) { + public static double[] solve(double[][] a, double[] b, double[] x0, double minEigenvalue, double maxEigenvalue, int maxIterations, double tolerance) { validateInputs(a, b, x0, minEigenvalue, maxEigenvalue, maxIterations, tolerance); int n = b.length; @@ -95,15 +87,7 @@ public static double[] solve( /** * Validates the inputs for the Chebyshev solver. */ - private static void validateInputs( - double[][] a, - double[] b, - double[] x0, - double minEigenvalue, - double maxEigenvalue, - int maxIterations, - double tolerance - ) { + private static void validateInputs(double[][] a, double[] b, double[] x0, double minEigenvalue, double maxEigenvalue, int maxIterations, double tolerance) { int n = a.length; if (n == 0) { throw new IllegalArgumentException("Matrix A cannot be empty."); @@ -194,4 +178,4 @@ private static double vectorNorm(double[] v) { } return Math.sqrt(sumOfSquares); } -} \ No newline at end of file +} From 358ae02850be029b8c637e115f46cbc35f45a659 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 20:24:17 +0530 Subject: [PATCH 21/25] Update ChebyshevIterationTest.java --- .../maths/ChebyshevIterationTest.java | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java index 477262967bee..d5cf83818fa4 100644 --- a/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java +++ b/src/test/java/com/thealgorithms/maths/ChebyshevIterationTest.java @@ -5,18 +5,18 @@ import org.junit.jupiter.api.Test; -public class ChebyshevIterationTest { +public class ChebyshevIterationTest { @Test public void testSolveSimple2x2Diagonal() { - double[][] a = { { 2, 0 }, { 0, 1 } }; - double[] b = { 2, 2 }; - double[] x0 = { 0, 0 }; + double[][] a = {{2, 0}, {0, 1}}; + double[] b = {2, 2}; + double[] x0 = {0, 0}; double minEig = 1.0; double maxEig = 2.0; int maxIter = 50; double tol = 1e-9; - double[] expected = { 1.0, 2.0 }; + double[] expected = {1.0, 2.0}; double[] result = ChebyshevIteration.solve(a, b, x0, minEig, maxEig, maxIter, tol); assertArrayEquals(expected, result, 1e-9); @@ -24,14 +24,14 @@ public void testSolveSimple2x2Diagonal() { @Test public void testSolve2x2Symmetric() { - double[][] a = { { 4, 1 }, { 1, 3 } }; - double[] b = { 1, 2 }; - double[] x0 = { 0, 0 }; + double[][] a = {{4, 1}, {1, 3}}; + double[] b = {1, 2}; + double[] x0 = {0, 0}; double minEig = (7.0 - Math.sqrt(5.0)) / 2.0; double maxEig = (7.0 + Math.sqrt(5.0)) / 2.0; int maxIter = 100; double tol = 1e-10; - double[] expected = { 1.0 / 11.0, 7.0 / 11.0 }; + double[] expected = {1.0 / 11.0, 7.0 / 11.0}; double[] result = ChebyshevIteration.solve(a, b, x0, minEig, maxEig, maxIter, tol); assertArrayEquals(expected, result, 1e-9); @@ -39,14 +39,14 @@ public void testSolve2x2Symmetric() { @Test public void testAlreadyAtSolution() { - double[][] a = { { 2, 0 }, { 0, 1 } }; - double[] b = { 2, 2 }; - double[] x0 = { 1, 2 }; + double[][] a = {{2, 0}, {0, 1}}; + double[] b = {2, 2}; + double[] x0 = {1, 2}; double minEig = 1.0; double maxEig = 2.0; int maxIter = 10; double tol = 1e-5; - double[] expected = { 1.0, 2.0 }; + double[] expected = {1.0, 2.0}; double[] result = ChebyshevIteration.solve(a, b, x0, minEig, maxEig, maxIter, tol); assertArrayEquals(expected, result, 0.0); @@ -54,51 +54,51 @@ public void testAlreadyAtSolution() { @Test public void testMismatchedDimensionsAB() { - double[][] a = { { 1, 0 }, { 0, 1 } }; - double[] b = { 1 }; - double[] x0 = { 0, 0 }; + double[][] a = {{1, 0}, {0, 1}}; + double[] b = {1}; + double[] x0 = {0, 0}; assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 10, 1e-5)); } @Test public void testMismatchedDimensionsAX() { - double[][] a = { { 1, 0 }, { 0, 1 } }; - double[] b = { 1, 1 }; - double[] x0 = { 0 }; + double[][] a = {{1, 0}, {0, 1}}; + double[] b = {1, 1}; + double[] x0 = {0}; assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 10, 1e-5)); } @Test public void testNonSquareMatrix() { - double[][] a = { { 1, 0, 0 }, { 0, 1, 0 } }; - double[] b = { 1, 1 }; - double[] x0 = { 0, 0 }; + double[][] a = {{1, 0, 0}, {0, 1, 0}}; + double[] b = {1, 1}; + double[] x0 = {0, 0}; assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 10, 1e-5)); } @Test public void testInvalidEigenvalues() { - double[][] a = { { 1, 0 }, { 0, 1 } }; - double[] b = { 1, 1 }; - double[] x0 = { 0, 0 }; + double[][] a = {{1, 0}, {0, 1}}; + double[] b = {1, 1}; + double[] x0 = {0, 0}; assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 2, 1, 10, 1e-5)); assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 1, 10, 1e-5)); } @Test public void testNonPositiveDefinite() { - double[][] a = { { 1, 0 }, { 0, 1 } }; - double[] b = { 1, 1 }; - double[] x0 = { 0, 0 }; + double[][] a = {{1, 0}, {0, 1}}; + double[] b = {1, 1}; + double[] x0 = {0, 0}; assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 0, 1, 10, 1e-5)); assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, -1, 1, 10, 1e-5)); } @Test public void testInvalidIterationCount() { - double[][] a = { { 1, 0 }, { 0, 1 } }; - double[] b = { 1, 1 }; - double[] x0 = { 0, 0 }; + double[][] a = {{1, 0}, {0, 1}}; + double[] b = {1, 1}; + double[] x0 = {0, 0}; assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, 0, 1e-5)); assertThrows(IllegalArgumentException.class, () -> ChebyshevIteration.solve(a, b, x0, 1, 2, -1, 1e-5)); } From 030f5c86dd64b8e4587277d39eb888eb2977ce04 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 20:30:32 +0530 Subject: [PATCH 22/25] Update ChebyshevIteration.java --- src/main/java/com/thealgorithms/maths/ChebyshevIteration.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 19b5ed5e03d4..761348b0938d 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -67,7 +67,7 @@ public static double[] solve(double[][] a, double[] b, double[] x0, double minEi alpha = 1.0 / d; System.arraycopy(r, 0, p, 0, n); // p = r } else { - double beta = (c * alphaPrev / 2.0) * (c * alphaPrev / 2.0); + double beta = c * alphaPrev / 2.0 * (c * alphaPrev / 2.0); alpha = 1.0 / (d - beta / alphaPrev); double[] pUpdate = scalarMultiply(beta / alphaPrev, p); p = vectorAdd(r, pUpdate); // p = r + (beta / alphaPrev) * p @@ -138,7 +138,7 @@ private static double[] matrixVectorMultiply(double[][] a, double[] v) { private static double[] vectorSubtract(double[] v1, double[] v2) { int n = v1.length; double[] result = new double[n]; - for (int i = 0; i < n; i++) { + for (int i = or (int i = 0; i < n; i++) { result[i] = v1[i] - v2[i]; } return result; From a3915e12dae53cc8416f9721a40a38d5a0cbcf07 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 20:30:44 +0530 Subject: [PATCH 23/25] Update ChebyshevIterationTest.java From 6defac80d4021ac4654f8979a0aff6768089ebd0 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 20:53:33 +0530 Subject: [PATCH 24/25] Update ChebyshevIteration.java --- src/main/java/com/thealgorithms/maths/ChebyshevIteration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java index 761348b0938d..bc30f1ba6e7e 100644 --- a/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java +++ b/src/main/java/com/thealgorithms/maths/ChebyshevIteration.java @@ -138,7 +138,7 @@ private static double[] matrixVectorMultiply(double[][] a, double[] v) { private static double[] vectorSubtract(double[] v1, double[] v2) { int n = v1.length; double[] result = new double[n]; - for (int i = or (int i = 0; i < n; i++) { + for (int i = 0; i < n; i++) { result[i] = v1[i] - v2[i]; } return result; From 08482b5023526a922d52bbea0a0ce860b2c26b42 Mon Sep 17 00:00:00 2001 From: Keykyrios Date: Tue, 28 Oct 2025 20:53:43 +0530 Subject: [PATCH 25/25] Update ChebyshevIterationTest.java