001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.math3.linear;
018    
019    import org.apache.commons.math3.util.IterationEvent;
020    import org.apache.commons.math3.exception.MathUnsupportedOperationException;
021    
022    /**
023     * This is the base class for all events occuring during the iterations of a
024     * {@link IterativeLinearSolver}.
025     *
026     * @version $Id: IterativeLinearSolverEvent.java 1416643 2012-12-03 19:37:14Z tn $
027     * @since 3.0
028     */
029    public abstract class IterativeLinearSolverEvent
030        extends IterationEvent {
031        /** Serialization identifier. */
032        private static final long serialVersionUID = 20120129L;
033    
034        /**
035         * Creates a new instance of this class.
036         *
037         * @param source the iterative algorithm on which the event initially
038         * occurred
039         * @param iterations the number of iterations performed at the time
040         * {@code this} event is created
041         */
042        public IterativeLinearSolverEvent(final Object source, final int iterations) {
043            super(source, iterations);
044        }
045    
046        /**
047         * Returns the current right-hand side of the linear system to be solved.
048         * This method should return an unmodifiable view, or a deep copy of the
049         * actual right-hand side vector, in order not to compromise subsequent
050         * iterations of the source {@link IterativeLinearSolver}.
051         *
052         * @return the right-hand side vector, b
053         */
054        public abstract RealVector getRightHandSideVector();
055    
056        /**
057         * Returns the norm of the residual. The returned value is not required to
058         * be <em>exact</em>. Instead, the norm of the so-called <em>updated</em>
059         * residual (if available) should be returned. For example, the
060         * {@link ConjugateGradient conjugate gradient} method computes a sequence
061         * of residuals, the norm of which is cheap to compute. However, due to
062         * accumulation of round-off errors, this residual might differ from the
063         * true residual after some iterations. See e.g. A. Greenbaum and
064         * Z. Strakos, <em>Predicting the Behavior of Finite Precision Lanzos and
065         * Conjugate Gradient Computations</em>, Technical Report 538, Department of
066         * Computer Science, New York University, 1991 (available
067         * <a href="http://www.archive.org/details/predictingbehavi00gree">here</a>).
068         *
069         * @return the norm of the residual, ||r||
070         */
071        public abstract double getNormOfResidual();
072    
073        /**
074         * <p>
075         * Returns the residual. This is an optional operation, as all iterative
076         * linear solvers do not provide cheap estimate of the updated residual
077         * vector, in which case
078         * </p>
079         * <ul>
080         * <li>this method should throw a
081         * {@link MathUnsupportedOperationException},</li>
082         * <li>{@link #providesResidual()} returns {@code false}.</li>
083         * </ul>
084         * <p>
085         * The default implementation throws a
086         * {@link MathUnsupportedOperationException}. If this method is overriden,
087         * then {@link #providesResidual()} should be overriden as well.
088         * </p>
089         *
090         * @return the updated residual, r
091         */
092        public RealVector getResidual() {
093            throw new MathUnsupportedOperationException();
094        }
095    
096        /**
097         * Returns the current estimate of the solution to the linear system to be
098         * solved. This method should return an unmodifiable view, or a deep copy of
099         * the actual current solution, in order not to compromise subsequent
100         * iterations of the source {@link IterativeLinearSolver}.
101         *
102         * @return the solution, x
103         */
104        public abstract RealVector getSolution();
105    
106        /**
107         * Returns {@code true} if {@link #getResidual()} is supported. The default
108         * implementation returns {@code false}.
109         *
110         * @return {@code false} if {@link #getResidual()} throws a
111         * {@link MathUnsupportedOperationException}
112         */
113        public boolean providesResidual() {
114            return false;
115        }
116    }