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.  *      https://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. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.linear;

  22. import org.hipparchus.exception.LocalizedCoreFormats;
  23. import org.hipparchus.exception.MathIllegalArgumentException;
  24. import org.hipparchus.exception.MathIllegalStateException;
  25. import org.hipparchus.exception.NullArgumentException;
  26. import org.hipparchus.util.IterationManager;
  27. import org.hipparchus.util.MathUtils;

  28. /**
  29.  * This abstract class defines an iterative solver for the linear system A
  30.  * &middot; x = b. In what follows, the <em>residual</em> r is defined as r = b
  31.  * - A &middot; x, where A is the linear operator of the linear system, b is the
  32.  * right-hand side vector, and x the current estimate of the solution.
  33.  *
  34.  */
  35. public abstract class IterativeLinearSolver {

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

  38.     /**
  39.      * Creates a new instance of this class, with default iteration manager.
  40.      *
  41.      * @param maxIterations the maximum number of iterations
  42.      */
  43.     protected IterativeLinearSolver(final int maxIterations) {
  44.         this.manager = new IterationManager(maxIterations);
  45.     }

  46.     /**
  47.      * Creates a new instance of this class, with custom iteration manager.
  48.      *
  49.      * @param manager the custom iteration manager
  50.      * @throws NullArgumentException if {@code manager} is {@code null}
  51.      */
  52.     protected IterativeLinearSolver(final IterationManager manager)
  53.         throws NullArgumentException {
  54.         MathUtils.checkNotNull(manager);
  55.         this.manager = manager;
  56.     }

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

  90.     /**
  91.      * Returns the iteration manager attached to this solver.
  92.      *
  93.      * @return the manager
  94.      */
  95.     public IterationManager getIterationManager() {
  96.         return manager;
  97.     }

  98.     /**
  99.      * Returns an estimate of the solution to the linear system A &middot; x =
  100.      * b.
  101.      *
  102.      * @param a the linear operator A of the system
  103.      * @param b the right-hand side vector
  104.      * @return a new vector containing the solution
  105.      * @throws NullArgumentException if one of the parameters is {@code null}
  106.      * @throws MathIllegalArgumentException if {@code a} is not square
  107.      * @throws MathIllegalArgumentException if {@code b} has dimensions
  108.      * inconsistent with {@code a}
  109.      * @throws MathIllegalStateException at exhaustion of the iteration count,
  110.      * unless a custom
  111.      * {@link org.hipparchus.util.Incrementor.MaxCountExceededCallback callback}
  112.      * has been set at construction of the {@link IterationManager}
  113.      */
  114.     public RealVector solve(final RealLinearOperator a, final RealVector b)
  115.         throws MathIllegalArgumentException, NullArgumentException, MathIllegalStateException {
  116.         MathUtils.checkNotNull(a);
  117.         final RealVector x = new ArrayRealVector(a.getColumnDimension());
  118.         x.set(0.);
  119.         return solveInPlace(a, b, x);
  120.     }

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

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