IterativeLinearSolver.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.math4.legacy.linear;

  18. import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
  19. import org.apache.commons.math4.legacy.exception.MaxCountExceededException;
  20. import org.apache.commons.math4.legacy.exception.NullArgumentException;

  21. /**
  22.  * This abstract class defines an iterative solver for the linear system A
  23.  * &middot; x = b. In what follows, the <em>residual</em> r is defined as r = b
  24.  * - A &middot; x, where A is the linear operator of the linear system, b is the
  25.  * right-hand side vector, and x the current estimate of the solution.
  26.  *
  27.  * @since 3.0
  28.  */
  29. public abstract class IterativeLinearSolver {

  30.     /** The object in charge of managing the iterations. */
  31.     private final IterationManager manager;

  32.     /**
  33.      * Creates a new instance of this class, with default iteration manager.
  34.      *
  35.      * @param maxIterations the maximum number of iterations
  36.      */
  37.     public IterativeLinearSolver(final int maxIterations) {
  38.         this.manager = new IterationManager(maxIterations);
  39.     }

  40.     /**
  41.      * Creates a new instance of this class, with custom iteration manager.
  42.      *
  43.      * @param manager the custom iteration manager
  44.      * @throws NullArgumentException if {@code manager} is {@code null}
  45.      */
  46.     public IterativeLinearSolver(final IterationManager manager)
  47.         throws NullArgumentException {
  48.         NullArgumentException.check(manager);
  49.         this.manager = manager;
  50.     }

  51.     /**
  52.      * Performs all dimension checks on the parameters of
  53.      * {@link #solve(RealLinearOperator, RealVector, RealVector) solve} and
  54.      * {@link #solveInPlace(RealLinearOperator, RealVector, RealVector) solveInPlace},
  55.      * and throws an exception if one of the checks fails.
  56.      *
  57.      * @param a the linear operator A of the system
  58.      * @param b the right-hand side vector
  59.      * @param x0 the initial guess of the solution
  60.      * @throws NullArgumentException if one of the parameters is {@code null}
  61.      * @throws NonSquareOperatorException if {@code a} is not square
  62.      * @throws DimensionMismatchException if {@code b} or {@code x0} have
  63.      * dimensions inconsistent with {@code a}
  64.      */
  65.     protected static void checkParameters(final RealLinearOperator a,
  66.         final RealVector b, final RealVector x0) throws
  67.         NullArgumentException, NonSquareOperatorException,
  68.         DimensionMismatchException {
  69.         NullArgumentException.check(a);
  70.         NullArgumentException.check(b);
  71.         NullArgumentException.check(x0);
  72.         if (a.getRowDimension() != a.getColumnDimension()) {
  73.             throw new NonSquareOperatorException(a.getRowDimension(),
  74.                                                        a.getColumnDimension());
  75.         }
  76.         if (b.getDimension() != a.getRowDimension()) {
  77.             throw new DimensionMismatchException(b.getDimension(),
  78.                                                  a.getRowDimension());
  79.         }
  80.         if (x0.getDimension() != a.getColumnDimension()) {
  81.             throw new DimensionMismatchException(x0.getDimension(),
  82.                                                  a.getColumnDimension());
  83.         }
  84.     }

  85.     /**
  86.      * Returns the iteration manager attached to this solver.
  87.      *
  88.      * @return the manager
  89.      */
  90.     public IterationManager getIterationManager() {
  91.         return manager;
  92.     }

  93.     /**
  94.      * Returns an estimate of the solution to the linear system A &middot; x =
  95.      * b.
  96.      *
  97.      * @param a the linear operator A of the system
  98.      * @param b the right-hand side vector
  99.      * @return a new vector containing the solution
  100.      * @throws NullArgumentException if one of the parameters is {@code null}
  101.      * @throws NonSquareOperatorException if {@code a} is not square
  102.      * @throws DimensionMismatchException if {@code b} has dimensions
  103.      * inconsistent with {@code a}
  104.      * @throws MaxCountExceededException at exhaustion of the iteration count,
  105.      * unless a custom
  106.      * {@link org.apache.commons.math4.legacy.core.IntegerSequence.Incrementor.MaxCountExceededCallback callback}
  107.      * has been set at construction of the {@link IterationManager}
  108.      */
  109.     public RealVector solve(final RealLinearOperator a, final RealVector b)
  110.         throws NullArgumentException, NonSquareOperatorException,
  111.         DimensionMismatchException, MaxCountExceededException {
  112.         NullArgumentException.check(a);
  113.         final RealVector x = new ArrayRealVector(a.getColumnDimension());
  114.         x.set(0.);
  115.         return solveInPlace(a, b, x);
  116.     }

  117.     /**
  118.      * Returns an estimate of the solution to the linear system A &middot; x =
  119.      * b.
  120.      *
  121.      * @param a the linear operator A of the system
  122.      * @param b the right-hand side vector
  123.      * @param x0 the initial guess of the solution
  124.      * @return a new vector containing the solution
  125.      * @throws NullArgumentException if one of the parameters is {@code null}
  126.      * @throws NonSquareOperatorException if {@code a} is not square
  127.      * @throws DimensionMismatchException if {@code b} or {@code x0} have
  128.      * dimensions inconsistent with {@code a}
  129.      * @throws MaxCountExceededException at exhaustion of the iteration count,
  130.      * unless a custom
  131.      * {@link org.apache.commons.math4.legacy.core.IntegerSequence.Incrementor.MaxCountExceededCallback callback}
  132.      * has been set at construction of the {@link IterationManager}
  133.      */
  134.     public RealVector solve(RealLinearOperator a, RealVector b, RealVector x0)
  135.         throws NullArgumentException, NonSquareOperatorException,
  136.         DimensionMismatchException, MaxCountExceededException {
  137.         NullArgumentException.check(x0);
  138.         return solveInPlace(a, b, x0.copy());
  139.     }

  140.     /**
  141.      * Returns an estimate of the solution to the linear system A &middot; x =
  142.      * b. The solution is computed in-place (initial guess is modified).
  143.      *
  144.      * @param a the linear operator A of the system
  145.      * @param b the right-hand side vector
  146.      * @param x0 initial guess of the solution
  147.      * @return a reference to {@code x0} (shallow copy) updated with the
  148.      * solution
  149.      * @throws NullArgumentException if one of the parameters is {@code null}
  150.      * @throws NonSquareOperatorException if {@code a} is not square
  151.      * @throws DimensionMismatchException if {@code b} or {@code x0} have
  152.      * dimensions inconsistent with {@code a}
  153.      * @throws MaxCountExceededException at exhaustion of the iteration count,
  154.      * unless a custom
  155.      * {@link org.apache.commons.math4.legacy.core.IntegerSequence.Incrementor.MaxCountExceededCallback callback}
  156.      * has been set at construction of the {@link IterationManager}
  157.      */
  158.     public abstract RealVector solveInPlace(RealLinearOperator a, RealVector b,
  159.         RealVector x0) throws NullArgumentException, NonSquareOperatorException,
  160.         DimensionMismatchException, MaxCountExceededException;
  161. }