blob: 995ee5136d41e099db8f5f7358e3bf8ffb440ed9 [file] [log] [blame]
/*
* 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.math4.linear;
import org.apache.commons.math4.exception.DimensionMismatchException;
import org.apache.commons.math4.exception.MaxCountExceededException;
import org.apache.commons.math4.exception.NullArgumentException;
import org.apache.commons.math4.util.IterationManager;
import org.apache.commons.math4.util.MathUtils;
/**
* This abstract class defines an iterative solver for the linear system A
* &middot; x = b. In what follows, the <em>residual</em> r is defined as r = b
* - A &middot; 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 &middot; 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.math4.util.IntegerSequence.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 &middot; 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.math4.util.IntegerSequence.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 &middot; 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.math4.util.IntegerSequence.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;
}