You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ce...@apache.org on 2012/03/22 08:15:24 UTC

svn commit: r1303674 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math3/linear/SymmLQ.java test/java/org/apache/commons/math3/linear/SymmLQTest.java

Author: celestin
Date: Thu Mar 22 07:15:24 2012
New Revision: 1303674

URL: http://svn.apache.org/viewvc?rev=1303674&view=rev
Log:
In o.a.c.m3.SymmLQ.State, created accessors
  - RealVector getRightHandSideVector(),
  - RealVector getSolution(),
  - double getNormOfResidual(),
see MATH-761.

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SymmLQ.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SymmLQTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SymmLQ.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SymmLQ.java?rev=1303674&r1=1303673&r2=1303674&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SymmLQ.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/linear/SymmLQ.java Thu Mar 22 07:15:24 2012
@@ -307,6 +307,12 @@ public class SymmLQ
         /** The value of beta[k+1] * M * P' * v[k+1]. */
         private RealVector r2;
 
+        /**
+         * The value of the updated, preconditioned residual P * r. This value is
+         * given by {@code min(}{@link #cgnorm}{@code , }{@link #lqnorm}{@code )}.
+         */
+        private double rnorm;
+
         /** Copy of the {@code shift} parameter. */
         private final double shift;
 
@@ -331,7 +337,7 @@ public class SymmLQ
          * the value of xL[k-1] if {@code goodb} is {@code false}, (xL[k-1] -
          * bstep[k-1] * v[1]) otherwise.
          */
-        private final RealVector x;
+        private final RealVector xL;
 
         /** The value of beta[k+1] * P' * v[k+1]. */
         private RealVector y;
@@ -375,7 +381,7 @@ public class SymmLQ
             this.a = a;
             this.minv = minv;
             this.b = b;
-            this.x = x;
+            this.xL = x;
             this.goodb = goodb;
             this.shift = shift;
             this.minvb = minv == null ? b : minv.operate(b);
@@ -477,19 +483,19 @@ public class SymmLQ
          * the convergence tests involve only cgnorm, so we're unlikely to stop
          * at an LQ point, except if the iteration limit interferes.
          *
-         * @param xRefined the vector to be updated with the refined value of x
+         * @param xC the vector to be updated with the refined value of xL
          */
-        public void refine(final RealVector xRefined) {
-            final int n = this.x.getDimension();
+        void moveToCG(final RealVector xC) {
+            final int n = this.xL.getDimension();
             if (lqnorm < cgnorm) {
                 if (!goodb) {
-                    xRefined.setSubVector(0, this.x);
+                    xC.setSubVector(0, this.xL);
                 } else {
                     final double step = bstep / beta1;
                     for (int i = 0; i < n; i++) {
                         final double bi = minvb.getEntry(i);
-                        final double xi = this.x.getEntry(i);
-                        xRefined.setEntry(i, xi + step * bi);
+                        final double xi = this.xL.getEntry(i);
+                        xC.setEntry(i, xi + step * bi);
                     }
                 }
             } else {
@@ -500,16 +506,16 @@ public class SymmLQ
                 // ynorm = FastMath.sqrt(ynorm2 + zbar * zbar);
                 if (!goodb) {
                     for (int i = 0; i < n; i++) {
-                        final double xi = this.x.getEntry(i);
+                        final double xi = this.xL.getEntry(i);
                         final double wi = wbar.getEntry(i);
-                        xRefined.setEntry(i, xi + zbar * wi);
+                        xC.setEntry(i, xi + zbar * wi);
                     }
                 } else {
                     for (int i = 0; i < n; i++) {
-                        final double xi = this.x.getEntry(i);
+                        final double xi = this.xL.getEntry(i);
                         final double wi = wbar.getEntry(i);
                         final double bi = minvb.getEntry(i);
-                        xRefined.setEntry(i, xi + zbar * wi + step * bi);
+                        xC.setEntry(i, xi + zbar * wi + step * bi);
                     }
                 }
             }
@@ -521,7 +527,7 @@ public class SymmLQ
          * 1.
          */
         private void init() {
-            this.x.set(0.);
+            this.xL.set(0.);
             /*
              * Set up y for the first Lanczos vector. y and beta1 will be zero
              * if b = 0.
@@ -696,12 +702,12 @@ public class SymmLQ
              */
             final double zetaC = zeta * c;
             final double zetaS = zeta * s;
-            final int n = x.getDimension();
+            final int n = xL.getDimension();
             for (int i = 0; i < n; i++) {
-                final double xi = x.getEntry(i);
+                final double xi = xL.getEntry(i);
                 final double vi = v.getEntry(i);
                 final double wi = wbar.getEntry(i);
-                x.setEntry(i, xi + wi * zetaC + vi * zetaS);
+                xL.setEntry(i, xi + wi * zetaC + vi * zetaS);
                 wbar.setEntry(i, wi * s - vi * c);
             }
             /*
@@ -770,6 +776,7 @@ public class SymmLQ
                  */
                 throw new SingularOperatorException();
             }
+            rnorm = FastMath.min(cgnorm, lqnorm);
             hasConverged = (cgnorm <= epsx) || (cgnorm <= epsr);
         }
 
@@ -778,7 +785,7 @@ public class SymmLQ
          *
          * @return {@code true} if convergence of the iterations has occured
          */
-        public boolean hasConverged() {
+        boolean hasConverged() {
             return hasConverged;
         }
 
@@ -787,7 +794,7 @@ public class SymmLQ
          *
          * @return the boolean value of {@code b == 0}
          */
-        public boolean bEqualsNullVector() {
+        boolean bEqualsNullVector() {
             return bIsNull;
         }
 
@@ -797,9 +804,36 @@ public class SymmLQ
          *
          * @return {@code true} if {@code beta < }{@link #MACH_PREC}
          */
-        public boolean betaEqualsZero() {
+        boolean betaEqualsZero() {
             return beta < MACH_PREC;
         }
+
+        /**
+         * Returns the right-hand side vector.
+         *
+         * @return the right-hand side vector, b
+         */
+        RealVector getRightHandSideVector() {
+            return b;
+        }
+
+        /**
+         * Returns the current estimate of the solution (LQ point).
+         *
+         * @return the solution, xL
+         */
+        RealVector getSolution() {
+            return xL;
+        }
+
+        /**
+         * Returns the norm of the updated, preconditioned residual.
+         *
+         * @return the norm of the residual, ||P * r||
+         */
+        double getNormOfResidual() {
+            return rnorm;
+        }
     }
 
     /**
@@ -835,21 +869,20 @@ public class SymmLQ
         /** {@inheritDoc} */
         @Override
         public double getNormOfResidual() {
-            return FastMath.min(state.cgnorm, state.lqnorm);
+            return state.getNormOfResidual();
         }
 
         /** {@inheritDoc} */
         @Override
         public RealVector getRightHandSideVector() {
-            return RealVector.unmodifiableRealVector(state.b);
+            return RealVector.unmodifiableRealVector(state.getRightHandSideVector());
         }
 
         /** {@inheritDoc} */
         @Override
         public RealVector getSolution() {
-            final int n = state.x.getDimension();
-            final RealVector x = new ArrayRealVector(n);
-            state.refine(x);
+            final RealVector x = state.getSolution().copy();
+            state.moveToCG(x);
             return x;
         }
     }
@@ -1180,7 +1213,11 @@ public class SymmLQ
         manager.resetIterationCount();
         manager.incrementIterationCount();
 
-        final State state = new State(a, minv, b, x, goodb, shift, delta, check);
+        final State state = new State(a, minv, b, x.copy(), goodb, shift, delta, check);
+        /*
+         * There is no need to create a new SymmLQEvent each time the state is
+         * updated, as SymmLQEvent keeps a reference to the current state.
+         */
         final IterativeLinearSolverEvent event = new SymmLQEvent(this, state);
         if (state.bEqualsNullVector()) {
             /* If b = 0 exactly, stop with x = 0. */
@@ -1199,14 +1236,7 @@ public class SymmLQ
                 manager.fireIterationPerformedEvent(event);
             } while (!state.hasConverged());
         }
-        state.refine(x);
-        /*
-         * The following two lines are a hack because state.x is now refined,
-         * so further calls to state.refine() (via event.getSolution()) should
-         * *not* return an altered value of state.x.
-         */
-        state.bstep = 0.;
-        state.gammaZeta = 0.;
+        state.moveToCG(x);
         manager.fireTerminationEvent(event);
         return x;
     }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SymmLQTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SymmLQTest.java?rev=1303674&r1=1303673&r2=1303674&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SymmLQTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/linear/SymmLQTest.java Thu Mar 22 07:15:24 2012
@@ -19,6 +19,7 @@ package org.apache.commons.math3.linear;
 import java.util.Arrays;
 
 import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.MathUnsupportedOperationException;
 import org.apache.commons.math3.util.FastMath;
 import org.apache.commons.math3.util.IterationEvent;
 import org.apache.commons.math3.util.IterationListener;
@@ -496,18 +497,21 @@ public class SymmLQTest {
             public void iterationPerformed(final IterationEvent e) {
                 ++count[2];
                 Assert.assertEquals("iteration performed",
-                    count[2], e.getIterations() - 1);
+                                    count[2],
+                                    e.getIterations() - 1);
             }
 
             public void iterationStarted(final IterationEvent e) {
                 ++count[1];
                 Assert.assertEquals("iteration started",
-                    count[1], e.getIterations() - 1);
+                                    count[1],
+                                    e.getIterations() - 1);
             }
 
             public void terminationPerformed(final IterationEvent e) {
                 ++count[3];
-                final IterativeLinearSolverEvent ilse = (IterativeLinearSolverEvent) e;
+                final IterativeLinearSolverEvent ilse;
+                ilse = (IterativeLinearSolverEvent) e;
                 xFromListener.setSubVector(0, ilse.getSolution());
             }
         };
@@ -524,8 +528,9 @@ public class SymmLQTest {
             msg = String.format("column %d (finalization)", j);
             Assert.assertEquals(msg, 1, count[3]);
             /*
-             *  Check that solution is not "over-refined". When the last iteration has
-             *  occurred, no further refinement should be performed.
+             *  Check that solution is not "over-refined". When the last
+             *  iteration has occurred, no further refinement should be
+             *  performed.
              */
             for (int i = 0; i < n; i++){
                 msg = String.format("row %d, column %d", i, j);