SymmLQ extends PreconditionedIterativeLinearSolver { @Override public RealVector solve(final RealLinearOperator a, final RealLinearOperator m, final RealVector b) throws NullArgumentException, NonSquareOperatorException, DimensionMismatchException, MaxCountExceededException, NonSelfAdjointOperatorException, NonPositiveDefiniteOperatorException, IllConditionedOperatorException { MathUtils.checkNotNull(a); final RealVector x = new ArrayRealVector(a.getColumnDimension()); return solveInPlace(a, m, b, x, false, 0.); } SymmLQ(final int maxIterations, final double delta,
                  final boolean check);  SymmLQ(final IterationManager manager, final double delta,
                  final boolean check); final boolean getCheck(); @Override RealVector solve(final RealLinearOperator a,
        final RealLinearOperator m, final RealVector b); RealVector solve(final RealLinearOperator a,
        final RealLinearOperator m, final RealVector b, final boolean goodb,
        final double shift); @Override RealVector solve(final RealLinearOperator a,
        final RealLinearOperator m, final RealVector b, final RealVector x); @Override RealVector solve(final RealLinearOperator a, final RealVector b); RealVector solve(final RealLinearOperator a, final RealVector b,
        final boolean goodb, final double shift); @Override RealVector solve(final RealLinearOperator a, final RealVector b,
        final RealVector x); @Override RealVector solveInPlace(final RealLinearOperator a,
        final RealLinearOperator m, final RealVector b, final RealVector x); RealVector solveInPlace(final RealLinearOperator a,
        final RealLinearOperator m, final RealVector b,
        final RealVector x, final boolean goodb, final double shift); @Override RealVector solveInPlace(final RealLinearOperator a,
        final RealVector b, final RealVector x);  }
@Test(expected = NonSquareOperatorException.class) public void testNonSquareOperator() { final Array2DRowRealMatrix a = new Array2DRowRealMatrix(2, 3); final IterativeLinearSolver solver; solver = new SymmLQ(10, 0., false); final ArrayRealVector b = new ArrayRealVector(a.getRowDimension()); final ArrayRealVector x = new ArrayRealVector(a.getColumnDimension()); solver.solve(a, b, x); }
@Test(expected = DimensionMismatchException.class) public void testDimensionMismatchRightHandSide() { final Array2DRowRealMatrix a = new Array2DRowRealMatrix(3, 3); final IterativeLinearSolver solver; solver = new SymmLQ(10, 0., false); final ArrayRealVector b = new ArrayRealVector(2); solver.solve(a, b); }
@Test(expected = DimensionMismatchException.class) public void testDimensionMismatchSolution() { final Array2DRowRealMatrix a = new Array2DRowRealMatrix(3, 3); final IterativeLinearSolver solver; solver = new SymmLQ(10, 0., false); final ArrayRealVector b = new ArrayRealVector(3); final ArrayRealVector x = new ArrayRealVector(2); solver.solve(a, b, x); }
@Test public void testUnpreconditionedSolution() { final int n = 5; final int maxIterations = 100; final RealLinearOperator a = new HilbertMatrix(n); final InverseHilbertMatrix ainv = new InverseHilbertMatrix(n); final IterativeLinearSolver solver; solver = new SymmLQ(maxIterations, 1E-10, true); final RealVector b = new ArrayRealVector(n); for (int j = 0; j < n; j++) { b.set(0.); b.setEntry(j, 1.); final RealVector x = solver.solve(a, b); for (int i = 0; i < n; i++) { final double actual = x.getEntry(i); final double expected = ainv.getEntry(i, j); final double delta = 1E-6 * FastMath.abs(expected); final String msg = String.format("entry[%d][%d]", i, j); Assert.assertEquals(msg, expected, actual, delta); } } }
@Test public void testUnpreconditionedSolutionWithInitialGuess() { final int n = 5; final int maxIterations = 100; final RealLinearOperator a = new HilbertMatrix(n); final InverseHilbertMatrix ainv = new InverseHilbertMatrix(n); final IterativeLinearSolver solver; solver = new SymmLQ(maxIterations, 1E-10, true); final RealVector b = new ArrayRealVector(n); for (int j = 0; j < n; j++) { b.set(0.); b.setEntry(j, 1.); final RealVector x0 = new ArrayRealVector(n); x0.set(1.); final RealVector x = solver.solve(a, b, x0); Assert.assertNotSame("x should not be a reference to x0", x0, x); for (int i = 0; i < n; i++) { final double actual = x.getEntry(i); final double expected = ainv.getEntry(i, j); final double delta = 1E-6 * FastMath.abs(expected); final String msg = String.format("entry[%d][%d]", i, j); Assert.assertEquals(msg, expected, actual, delta); Assert.assertEquals(msg, x0.getEntry(i), 1., Math.ulp(1.)); } } }
@Test(expected = NonSquareOperatorException.class) public void testNonSquarePreconditioner() { final Array2DRowRealMatrix a = new Array2DRowRealMatrix(2, 2); final RealLinearOperator m = new RealLinearOperator() { @Override public RealVector operate(final RealVector x) { throw new UnsupportedOperationException(); } @Override public int getRowDimension() { return 2; } @Override public int getColumnDimension() { return 3; } }; final PreconditionedIterativeLinearSolver solver; solver = new SymmLQ(10, 0., false); final ArrayRealVector b = new ArrayRealVector(a.getRowDimension()); solver.solve(a, m, b); }
@Test(expected = DimensionMismatchException.class) public void testMismatchedOperatorDimensions() { final Array2DRowRealMatrix a = new Array2DRowRealMatrix(2, 2); final RealLinearOperator m = new RealLinearOperator() { @Override public RealVector operate(final RealVector x) { throw new UnsupportedOperationException(); } @Override public int getRowDimension() { return 3; } @Override public int getColumnDimension() { return 3; } }; final PreconditionedIterativeLinearSolver solver; solver = new SymmLQ(10, 0d, false); final ArrayRealVector b = new ArrayRealVector(a.getRowDimension()); solver.solve(a, m, b); }
@Test(expected = NonPositiveDefiniteOperatorException.class) public void testNonPositiveDefinitePreconditioner() { final Array2DRowRealMatrix a = new Array2DRowRealMatrix(2, 2); a.setEntry(0, 0, 1d); a.setEntry(0, 1, 2d); a.setEntry(1, 0, 3d); a.setEntry(1, 1, 4d); final RealLinearOperator m = new RealLinearOperator() { @Override public RealVector operate(final RealVector x) { final ArrayRealVector y = new ArrayRealVector(2); y.setEntry(0, -x.getEntry(0)); y.setEntry(1, -x.getEntry(1)); return y; } @Override public int getRowDimension() { return 2; } @Override public int getColumnDimension() { return 2; } }; final PreconditionedIterativeLinearSolver solver; solver = new SymmLQ(10, 0d, true); final ArrayRealVector b = new ArrayRealVector(2); b.setEntry(0, -1d); b.setEntry(1, -1d); solver.solve(a, m, b); }
@Test public void testPreconditionedSolution() { final int n = 8; final int maxIterations = 100; final RealLinearOperator a = new HilbertMatrix(n); final InverseHilbertMatrix ainv = new InverseHilbertMatrix(n); final RealLinearOperator m = JacobiPreconditioner.create(a); final PreconditionedIterativeLinearSolver solver; solver = new SymmLQ(maxIterations, 1E-15, true); final RealVector b = new ArrayRealVector(n); for (int j = 0; j < n; j++) { b.set(0.); b.setEntry(j, 1.); final RealVector x = solver.solve(a, m, b); for (int i = 0; i < n; i++) { final double actual = x.getEntry(i); final double expected = ainv.getEntry(i, j); final double delta = 1E-6 * FastMath.abs(expected); final String msg = String.format("coefficient (%d, %d)", i, j); Assert.assertEquals(msg, expected, actual, delta); } } }
@Test public void testPreconditionedSolution2() { final int n = 100; final int maxIterations = 100000; final Array2DRowRealMatrix a = new Array2DRowRealMatrix(n, n); double daux = 1.; for (int i = 0; i < n; i++) { a.setEntry(i, i, daux); daux *= 1.2; for (int j = i + 1; j < n; j++) { if (i == j) { } else { final double value = 1.0; a.setEntry(i, j, value); a.setEntry(j, i, value); } } } final RealLinearOperator m = JacobiPreconditioner.create(a); final PreconditionedIterativeLinearSolver prec; final IterativeLinearSolver unprec; prec = new SymmLQ(maxIterations, 1E-15, true); unprec = new SymmLQ(maxIterations, 1E-15, true); final RealVector b = new ArrayRealVector(n); final String pattern = "preconditioned SymmLQ (%d iterations) should" + " have been faster than unpreconditioned (%d iterations)"; String msg; for (int j = 0; j < 1; j++) { b.set(0.); b.setEntry(j, 1.); final RealVector px = prec.solve(a, m, b); final RealVector x = unprec.solve(a, b); final int np = prec.getIterationManager().getIterations(); final int nup = unprec.getIterationManager().getIterations(); msg = String.format(pattern, np, nup); for (int i = 0; i < n; i++) { msg = String.format("row %d, column %d", i, j); final double expected = x.getEntry(i); final double actual = px.getEntry(i); final double delta = 5E-5 * FastMath.abs(expected); Assert.assertEquals(msg, expected, actual, delta); } } }
@Test public void testEventManagement() { final int n = 5; final int maxIterations = 100; final RealLinearOperator a = new HilbertMatrix(n); final IterativeLinearSolver solver; final int[] count = new int[] {0, 0, 0, 0}; final RealVector xFromListener = new ArrayRealVector(n); final IterationListener listener = new IterationListener() { public void initializationPerformed(final IterationEvent e) { ++count[0]; } public void iterationPerformed(final IterationEvent e) { ++count[2]; Assert.assertEquals("iteration performed", count[2], e.getIterations() - 1); } public void iterationStarted(final IterationEvent e) { ++count[1]; Assert.assertEquals("iteration started", count[1], e.getIterations() - 1); } public void terminationPerformed(final IterationEvent e) { ++count[3]; final IterativeLinearSolverEvent ilse; ilse = (IterativeLinearSolverEvent) e; xFromListener.setSubVector(0, ilse.getSolution()); } }; solver = new SymmLQ(maxIterations, 1E-10, true); solver.getIterationManager().addIterationListener(listener); final RealVector b = new ArrayRealVector(n); for (int j = 0; j < n; j++) { Arrays.fill(count, 0); b.set(0.); b.setEntry(j, 1.); final RealVector xFromSolver = solver.solve(a, b); String msg = String.format("column %d (initialization)", j); Assert.assertEquals(msg, 1, count[0]); msg = String.format("column %d (finalization)", j); Assert.assertEquals(msg, 1, count[3]); for (int i = 0; i < n; i++){ msg = String.format("row %d, column %d", i, j); final double expected = xFromSolver.getEntry(i); final double actual = xFromListener.getEntry(i); Assert.assertEquals(msg, expected, actual, 0.0); } } }
@Test(expected = NonSelfAdjointOperatorException.class) public void testNonSelfAdjointOperator() { final RealLinearOperator a; a = new Array2DRowRealMatrix(new double[][] { {1., 2., 3.}, {2., 4., 5.}, {2.999, 5., 6.} }); final RealVector b; b = new ArrayRealVector(new double[] {1., 1., 1.}); new SymmLQ(100, 1., true).solve(a, b); }
@Test(expected = NonSelfAdjointOperatorException.class) public void testNonSelfAdjointPreconditioner() { final RealLinearOperator a = new Array2DRowRealMatrix(new double[][] { {1., 2., 3.}, {2., 4., 5.}, {3., 5., 6.} }); final Array2DRowRealMatrix mMat; mMat = new Array2DRowRealMatrix(new double[][] { {1., 0., 1.}, {0., 1., 0.}, {0., 0., 1.} }); final DecompositionSolver mSolver; mSolver = new LUDecomposition(mMat).getSolver(); final RealLinearOperator minv = new RealLinearOperator() { @Override public RealVector operate(final RealVector x) { return mSolver.solve(x); } @Override public int getRowDimension() { return mMat.getRowDimension(); } @Override public int getColumnDimension() { return mMat.getColumnDimension(); } }; final RealVector b = new ArrayRealVector(new double[] { 1., 1., 1. }); new SymmLQ(100, 1., true).solve(a, minv, b); }
@Test public void testUnpreconditionedNormOfResidual() { final int n = 5; final int maxIterations = 100; final RealLinearOperator a = new HilbertMatrix(n); final IterativeLinearSolver solver; final IterationListener listener = new IterationListener() { private void doTestNormOfResidual(final IterationEvent e) { final IterativeLinearSolverEvent evt; evt = (IterativeLinearSolverEvent) e; final RealVector x = evt.getSolution(); final RealVector b = evt.getRightHandSideVector(); final RealVector r = b.subtract(a.operate(x)); final double rnorm = r.getNorm(); Assert.assertEquals("iteration performed (residual)", rnorm, evt.getNormOfResidual(), FastMath.max(1E-5 * rnorm, 1E-10)); } public void initializationPerformed(final IterationEvent e) { doTestNormOfResidual(e); } public void iterationPerformed(final IterationEvent e) { doTestNormOfResidual(e); } public void iterationStarted(final IterationEvent e) { doTestNormOfResidual(e); } public void terminationPerformed(final IterationEvent e) { doTestNormOfResidual(e); } }; solver = new SymmLQ(maxIterations, 1E-10, true); solver.getIterationManager().addIterationListener(listener); final RealVector b = new ArrayRealVector(n); for (int j = 0; j < n; j++) { b.set(0.); b.setEntry(j, 1.); solver.solve(a, b); } }
@Test public void testPreconditionedNormOfResidual() { final int n = 5; final int maxIterations = 100; final RealLinearOperator a = new HilbertMatrix(n); final JacobiPreconditioner m = JacobiPreconditioner.create(a); final RealLinearOperator p = m.sqrt(); final PreconditionedIterativeLinearSolver solver; final IterationListener listener = new IterationListener() { private void doTestNormOfResidual(final IterationEvent e) { final IterativeLinearSolverEvent evt; evt = (IterativeLinearSolverEvent) e; final RealVector x = evt.getSolution(); final RealVector b = evt.getRightHandSideVector(); final RealVector r = b.subtract(a.operate(x)); final double rnorm = p.operate(r).getNorm(); Assert.assertEquals("iteration performed (residual)", rnorm, evt.getNormOfResidual(), FastMath.max(1E-5 * rnorm, 1E-10)); } public void initializationPerformed(final IterationEvent e) { doTestNormOfResidual(e); } public void iterationPerformed(final IterationEvent e) { doTestNormOfResidual(e); } public void iterationStarted(final IterationEvent e) { doTestNormOfResidual(e); } public void terminationPerformed(final IterationEvent e) { doTestNormOfResidual(e); } }; solver = new SymmLQ(maxIterations, 1E-10, true); solver.getIterationManager().addIterationListener(listener); final RealVector b = new ArrayRealVector(n); for (int j = 0; j < n; j++) { b.set(0.); b.setEntry(j, 1.); solver.solve(a, m, b); } }