diff options
Diffstat (limited to 'src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java')
-rw-r--r-- | src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java b/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java new file mode 100644 index 0000000..cb7fa90 --- /dev/null +++ b/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java @@ -0,0 +1,166 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math3.linear; + +import org.apache.commons.math3.exception.DimensionMismatchException; +import org.apache.commons.math3.exception.MaxCountExceededException; +import org.apache.commons.math3.exception.NullArgumentException; +import org.apache.commons.math3.util.IterationManager; +import org.apache.commons.math3.util.MathUtils; + +/** + * This abstract class defines an iterative solver for the linear system A · x = b. In what + * follows, the <em>residual</em> r is defined as r = b - A · x, where A is the linear + * operator of the linear system, b is the right-hand side vector, and x the current estimate of the + * solution. + * + * @since 3.0 + */ +public abstract class IterativeLinearSolver { + + /** The object in charge of managing the iterations. */ + private final IterationManager manager; + + /** + * Creates a new instance of this class, with default iteration manager. + * + * @param maxIterations the maximum number of iterations + */ + public IterativeLinearSolver(final int maxIterations) { + this.manager = new IterationManager(maxIterations); + } + + /** + * Creates a new instance of this class, with custom iteration manager. + * + * @param manager the custom iteration manager + * @throws NullArgumentException if {@code manager} is {@code null} + */ + public IterativeLinearSolver(final IterationManager manager) throws NullArgumentException { + MathUtils.checkNotNull(manager); + this.manager = manager; + } + + /** + * Performs all dimension checks on the parameters of {@link #solve(RealLinearOperator, + * RealVector, RealVector) solve} and {@link #solveInPlace(RealLinearOperator, RealVector, + * RealVector) solveInPlace}, and throws an exception if one of the checks fails. + * + * @param a the linear operator A of the system + * @param b the right-hand side vector + * @param x0 the initial guess of the solution + * @throws NullArgumentException if one of the parameters is {@code null} + * @throws NonSquareOperatorException if {@code a} is not square + * @throws DimensionMismatchException if {@code b} or {@code x0} have dimensions inconsistent + * with {@code a} + */ + protected static void checkParameters( + final RealLinearOperator a, final RealVector b, final RealVector x0) + throws NullArgumentException, NonSquareOperatorException, DimensionMismatchException { + MathUtils.checkNotNull(a); + MathUtils.checkNotNull(b); + MathUtils.checkNotNull(x0); + if (a.getRowDimension() != a.getColumnDimension()) { + throw new NonSquareOperatorException(a.getRowDimension(), a.getColumnDimension()); + } + if (b.getDimension() != a.getRowDimension()) { + throw new DimensionMismatchException(b.getDimension(), a.getRowDimension()); + } + if (x0.getDimension() != a.getColumnDimension()) { + throw new DimensionMismatchException(x0.getDimension(), a.getColumnDimension()); + } + } + + /** + * Returns the iteration manager attached to this solver. + * + * @return the manager + */ + public IterationManager getIterationManager() { + return manager; + } + + /** + * Returns an estimate of the solution to the linear system A · x = b. + * + * @param a the linear operator A of the system + * @param b the right-hand side vector + * @return a new vector containing the solution + * @throws NullArgumentException if one of the parameters is {@code null} + * @throws NonSquareOperatorException if {@code a} is not square + * @throws DimensionMismatchException if {@code b} has dimensions inconsistent with {@code a} + * @throws MaxCountExceededException at exhaustion of the iteration count, unless a custom + * {@link org.apache.commons.math3.util.Incrementor.MaxCountExceededCallback callback} has + * been set at construction of the {@link IterationManager} + */ + public RealVector solve(final RealLinearOperator a, final RealVector b) + throws NullArgumentException, + NonSquareOperatorException, + DimensionMismatchException, + MaxCountExceededException { + MathUtils.checkNotNull(a); + final RealVector x = new ArrayRealVector(a.getColumnDimension()); + x.set(0.); + return solveInPlace(a, b, x); + } + + /** + * Returns an estimate of the solution to the linear system A · x = b. + * + * @param a the linear operator A of the system + * @param b the right-hand side vector + * @param x0 the initial guess of the solution + * @return a new vector containing the solution + * @throws NullArgumentException if one of the parameters is {@code null} + * @throws NonSquareOperatorException if {@code a} is not square + * @throws DimensionMismatchException if {@code b} or {@code x0} have dimensions inconsistent + * with {@code a} + * @throws MaxCountExceededException at exhaustion of the iteration count, unless a custom + * {@link org.apache.commons.math3.util.Incrementor.MaxCountExceededCallback callback} has + * been set at construction of the {@link IterationManager} + */ + public RealVector solve(RealLinearOperator a, RealVector b, RealVector x0) + throws NullArgumentException, + NonSquareOperatorException, + DimensionMismatchException, + MaxCountExceededException { + MathUtils.checkNotNull(x0); + return solveInPlace(a, b, x0.copy()); + } + + /** + * Returns an estimate of the solution to the linear system A · x = b. The solution is + * computed in-place (initial guess is modified). + * + * @param a the linear operator A of the system + * @param b the right-hand side vector + * @param x0 initial guess of the solution + * @return a reference to {@code x0} (shallow copy) updated with the solution + * @throws NullArgumentException if one of the parameters is {@code null} + * @throws NonSquareOperatorException if {@code a} is not square + * @throws DimensionMismatchException if {@code b} or {@code x0} have dimensions inconsistent + * with {@code a} + * @throws MaxCountExceededException at exhaustion of the iteration count, unless a custom + * {@link org.apache.commons.math3.util.Incrementor.MaxCountExceededCallback callback} has + * been set at construction of the {@link IterationManager} + */ + public abstract RealVector solveInPlace(RealLinearOperator a, RealVector b, RealVector x0) + throws NullArgumentException, + NonSquareOperatorException, + DimensionMismatchException, + MaxCountExceededException; +} |