summaryrefslogtreecommitdiff
path: root/src/main/java/org/apache/commons/math3/linear/PreconditionedIterativeLinearSolver.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/apache/commons/math3/linear/PreconditionedIterativeLinearSolver.java')
-rw-r--r--src/main/java/org/apache/commons/math3/linear/PreconditionedIterativeLinearSolver.java205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/main/java/org/apache/commons/math3/linear/PreconditionedIterativeLinearSolver.java b/src/main/java/org/apache/commons/math3/linear/PreconditionedIterativeLinearSolver.java
new file mode 100644
index 0000000..6808d46
--- /dev/null
+++ b/src/main/java/org/apache/commons/math3/linear/PreconditionedIterativeLinearSolver.java
@@ -0,0 +1,205 @@
+/*
+ * 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 preconditioned iterative solvers. When A is ill-conditioned, instead
+ * of solving system A &middot; x = b directly, it is preferable to solve either <center> (M
+ * &middot; A) &middot; x = M &middot; b </center> (left preconditioning), or <center> (A &middot;
+ * M) &middot; y = b, &nbsp;&nbsp;&nbsp;&nbsp;followed by M &middot; y = x </center> (right
+ * preconditioning), where M approximates in some way A<sup>-1</sup>, while matrix-vector products
+ * of the type M &middot; y remain comparatively easy to compute. In this library, M (not
+ * M<sup>-1</sup>!) is called the <em>preconditionner</em>.
+ *
+ * <p>Concrete implementations of this abstract class must be provided with the preconditioner M, as
+ * a {@link RealLinearOperator}.
+ *
+ * @since 3.0
+ */
+public abstract class PreconditionedIterativeLinearSolver extends IterativeLinearSolver {
+
+ /**
+ * Creates a new instance of this class, with default iteration manager.
+ *
+ * @param maxIterations the maximum number of iterations
+ */
+ public PreconditionedIterativeLinearSolver(final int maxIterations) {
+ super(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 PreconditionedIterativeLinearSolver(final IterationManager manager)
+ throws NullArgumentException {
+ super(manager);
+ }
+
+ /**
+ * Returns an estimate of the solution to the linear system A &middot; x = b.
+ *
+ * @param a the linear operator A of the system
+ * @param m the preconditioner, M (can be {@code null})
+ * @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} or {@code m} is not square
+ * @throws DimensionMismatchException if {@code m}, {@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(
+ final RealLinearOperator a,
+ final RealLinearOperator m,
+ final RealVector b,
+ final RealVector x0)
+ throws NullArgumentException,
+ NonSquareOperatorException,
+ DimensionMismatchException,
+ MaxCountExceededException {
+ MathUtils.checkNotNull(x0);
+ return solveInPlace(a, m, b, x0.copy());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ 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, null, b, x);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public RealVector solve(final RealLinearOperator a, final RealVector b, final RealVector x0)
+ throws NullArgumentException,
+ NonSquareOperatorException,
+ DimensionMismatchException,
+ MaxCountExceededException {
+ MathUtils.checkNotNull(x0);
+ return solveInPlace(a, null, b, x0.copy());
+ }
+
+ /**
+ * Performs all dimension checks on the parameters of {@link #solve(RealLinearOperator,
+ * RealLinearOperator, RealVector, RealVector) solve} and {@link
+ * #solveInPlace(RealLinearOperator, RealLinearOperator, RealVector, RealVector) solveInPlace},
+ * and throws an exception if one of the checks fails.
+ *
+ * @param a the linear operator A of the system
+ * @param m the preconditioner, M (can be {@code null})
+ * @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} or {@code m} is not square
+ * @throws DimensionMismatchException if {@code m}, {@code b} or {@code x0} have dimensions
+ * inconsistent with {@code a}
+ */
+ protected static void checkParameters(
+ final RealLinearOperator a,
+ final RealLinearOperator m,
+ final RealVector b,
+ final RealVector x0)
+ throws NullArgumentException, NonSquareOperatorException, DimensionMismatchException {
+ checkParameters(a, b, x0);
+ if (m != null) {
+ if (m.getColumnDimension() != m.getRowDimension()) {
+ throw new NonSquareOperatorException(m.getColumnDimension(), m.getRowDimension());
+ }
+ if (m.getRowDimension() != a.getRowDimension()) {
+ throw new DimensionMismatchException(m.getRowDimension(), a.getRowDimension());
+ }
+ }
+ }
+
+ /**
+ * Returns an estimate of the solution to the linear system A &middot; x = b.
+ *
+ * @param a the linear operator A of the system
+ * @param m the preconditioner, M (can be {@code null})
+ * @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} or {@code m} is not square
+ * @throws DimensionMismatchException if {@code m} or {@code b} 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, RealLinearOperator m, RealVector b)
+ throws NullArgumentException,
+ NonSquareOperatorException,
+ DimensionMismatchException,
+ MaxCountExceededException {
+ MathUtils.checkNotNull(a);
+ final RealVector x = new ArrayRealVector(a.getColumnDimension());
+ return solveInPlace(a, m, b, x);
+ }
+
+ /**
+ * Returns an estimate of the solution to the linear system A &middot; x = b. The solution is
+ * computed in-place (initial guess is modified).
+ *
+ * @param a the linear operator A of the system
+ * @param m the preconditioner, M (can be {@code null})
+ * @param b the right-hand side vector
+ * @param x0 the 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} or {@code m} is not square
+ * @throws DimensionMismatchException if {@code m}, {@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, RealLinearOperator m, RealVector b, RealVector x0)
+ throws NullArgumentException,
+ NonSquareOperatorException,
+ DimensionMismatchException,
+ MaxCountExceededException;
+
+ /** {@inheritDoc} */
+ @Override
+ public RealVector solveInPlace(
+ final RealLinearOperator a, final RealVector b, final RealVector x0)
+ throws NullArgumentException,
+ NonSquareOperatorException,
+ DimensionMismatchException,
+ MaxCountExceededException {
+ return solveInPlace(a, null, b, x0);
+ }
+}