Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5BD3B10ADC for ; Mon, 16 Feb 2015 22:46:11 +0000 (UTC) Received: (qmail 46503 invoked by uid 500); 16 Feb 2015 22:39:31 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 46155 invoked by uid 500); 16 Feb 2015 22:39:31 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 46040 invoked by uid 99); 16 Feb 2015 22:39:31 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 16 Feb 2015 22:39:31 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 4DB22E04D2; Mon, 16 Feb 2015 22:39:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tn@apache.org To: commits@commons.apache.org Date: Mon, 16 Feb 2015 22:39:32 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [02/82] [partial] [math] Update for next development iteration: commons-math4 http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java b/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java deleted file mode 100644 index 97bd8b7..0000000 --- a/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolver.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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 residual 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; -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolverEvent.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolverEvent.java b/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolverEvent.java deleted file mode 100644 index 780068c..0000000 --- a/src/main/java/org/apache/commons/math3/linear/IterativeLinearSolverEvent.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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.util.IterationEvent; -import org.apache.commons.math3.exception.MathUnsupportedOperationException; - -/** - * This is the base class for all events occurring during the iterations of a - * {@link IterativeLinearSolver}. - * - * @since 3.0 - */ -public abstract class IterativeLinearSolverEvent - extends IterationEvent { - /** Serialization identifier. */ - private static final long serialVersionUID = 20120129L; - - /** - * Creates a new instance of this class. - * - * @param source the iterative algorithm on which the event initially - * occurred - * @param iterations the number of iterations performed at the time - * {@code this} event is created - */ - public IterativeLinearSolverEvent(final Object source, final int iterations) { - super(source, iterations); - } - - /** - * Returns the current right-hand side of the linear system to be solved. - * This method should return an unmodifiable view, or a deep copy of the - * actual right-hand side vector, in order not to compromise subsequent - * iterations of the source {@link IterativeLinearSolver}. - * - * @return the right-hand side vector, b - */ - public abstract RealVector getRightHandSideVector(); - - /** - * Returns the norm of the residual. The returned value is not required to - * be exact. Instead, the norm of the so-called updated - * residual (if available) should be returned. For example, the - * {@link ConjugateGradient conjugate gradient} method computes a sequence - * of residuals, the norm of which is cheap to compute. However, due to - * accumulation of round-off errors, this residual might differ from the - * true residual after some iterations. See e.g. A. Greenbaum and - * Z. Strakos, Predicting the Behavior of Finite Precision Lanzos and - * Conjugate Gradient Computations, Technical Report 538, Department of - * Computer Science, New York University, 1991 (available - * here). - * - * @return the norm of the residual, ||r|| - */ - public abstract double getNormOfResidual(); - - /** - *

- * Returns the residual. This is an optional operation, as all iterative - * linear solvers do not provide cheap estimate of the updated residual - * vector, in which case - *

- *
    - *
  • this method should throw a - * {@link MathUnsupportedOperationException},
  • - *
  • {@link #providesResidual()} returns {@code false}.
  • - *
- *

- * The default implementation throws a - * {@link MathUnsupportedOperationException}. If this method is overriden, - * then {@link #providesResidual()} should be overriden as well. - *

- * - * @return the updated residual, r - */ - public RealVector getResidual() { - throw new MathUnsupportedOperationException(); - } - - /** - * Returns the current estimate of the solution to the linear system to be - * solved. This method should return an unmodifiable view, or a deep copy of - * the actual current solution, in order not to compromise subsequent - * iterations of the source {@link IterativeLinearSolver}. - * - * @return the solution, x - */ - public abstract RealVector getSolution(); - - /** - * Returns {@code true} if {@link #getResidual()} is supported. The default - * implementation returns {@code false}. - * - * @return {@code false} if {@link #getResidual()} throws a - * {@link MathUnsupportedOperationException} - */ - public boolean providesResidual() { - return false; - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/JacobiPreconditioner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/JacobiPreconditioner.java b/src/main/java/org/apache/commons/math3/linear/JacobiPreconditioner.java deleted file mode 100644 index 1506fe5..0000000 --- a/src/main/java/org/apache/commons/math3/linear/JacobiPreconditioner.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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.analysis.function.Sqrt; -import org.apache.commons.math3.util.MathArrays; - -/** - * This class implements the standard Jacobi (diagonal) preconditioner. For a - * matrix Aij, this preconditioner is - * M = diag(1 / A11, 1 / A22, …). - * - * @since 3.0 - */ -public class JacobiPreconditioner extends RealLinearOperator { - - /** The diagonal coefficients of the preconditioner. */ - private final ArrayRealVector diag; - - /** - * Creates a new instance of this class. - * - * @param diag the diagonal coefficients of the linear operator to be - * preconditioned - * @param deep {@code true} if a deep copy of the above array should be - * performed - */ - public JacobiPreconditioner(final double[] diag, final boolean deep) { - this.diag = new ArrayRealVector(diag, deep); - } - - /** - * Creates a new instance of this class. This method extracts the diagonal - * coefficients of the specified linear operator. If {@code a} does not - * extend {@link AbstractRealMatrix}, then the coefficients of the - * underlying matrix are not accessible, coefficient extraction is made by - * matrix-vector products with the basis vectors (and might therefore take - * some time). With matrices, direct entry access is carried out. - * - * @param a the linear operator for which the preconditioner should be built - * @return the diagonal preconditioner made of the inverse of the diagonal - * coefficients of the specified linear operator - * @throws NonSquareOperatorException if {@code a} is not square - */ - public static JacobiPreconditioner create(final RealLinearOperator a) - throws NonSquareOperatorException { - final int n = a.getColumnDimension(); - if (a.getRowDimension() != n) { - throw new NonSquareOperatorException(a.getRowDimension(), n); - } - final double[] diag = new double[n]; - if (a instanceof AbstractRealMatrix) { - final AbstractRealMatrix m = (AbstractRealMatrix) a; - for (int i = 0; i < n; i++) { - diag[i] = m.getEntry(i, i); - } - } else { - final ArrayRealVector x = new ArrayRealVector(n); - for (int i = 0; i < n; i++) { - x.set(0.); - x.setEntry(i, 1.); - diag[i] = a.operate(x).getEntry(i); - } - } - return new JacobiPreconditioner(diag, false); - } - - /** {@inheritDoc} */ - @Override - public int getColumnDimension() { - return diag.getDimension(); - } - - /** {@inheritDoc} */ - @Override - public int getRowDimension() { - return diag.getDimension(); - } - - /** {@inheritDoc} */ - @Override - public RealVector operate(final RealVector x) { - // Dimension check is carried out by ebeDivide - return new ArrayRealVector(MathArrays.ebeDivide(x.toArray(), - diag.toArray()), - false); - } - - /** - * Returns the square root of {@code this} diagonal operator. More - * precisely, this method returns - * P = diag(1 / √A11, 1 / √A22, …). - * - * @return the square root of {@code this} preconditioner - * @since 3.1 - */ - public RealLinearOperator sqrt() { - final RealVector sqrtDiag = diag.map(new Sqrt()); - return new RealLinearOperator() { - /** {@inheritDoc} */ - @Override - public RealVector operate(final RealVector x) { - return new ArrayRealVector(MathArrays.ebeDivide(x.toArray(), - sqrtDiag.toArray()), - false); - } - - /** {@inheritDoc} */ - @Override - public int getRowDimension() { - return sqrtDiag.getDimension(); - } - - /** {@inheritDoc} */ - @Override - public int getColumnDimension() { - return sqrtDiag.getDimension(); - } - }; - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/LUDecomposition.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/LUDecomposition.java b/src/main/java/org/apache/commons/math3/linear/LUDecomposition.java deleted file mode 100644 index 368bc30..0000000 --- a/src/main/java/org/apache/commons/math3/linear/LUDecomposition.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * 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.util.FastMath; - -/** - * Calculates the LUP-decomposition of a square matrix. - *

The LUP-decomposition of a matrix A consists of three matrices L, U and - * P that satisfy: P×A = L×U. L is lower triangular (with unit - * diagonal terms), U is upper triangular and P is a permutation matrix. All - * matrices are m×m.

- *

As shown by the presence of the P matrix, this decomposition is - * implemented using partial pivoting.

- *

This class is based on the class with similar name from the - * JAMA library.

- *
    - *
  • a {@link #getP() getP} method has been added,
  • - *
  • the {@code det} method has been renamed as {@link #getDeterminant() - * getDeterminant},
  • - *
  • the {@code getDoublePivot} method has been removed (but the int based - * {@link #getPivot() getPivot} method has been kept),
  • - *
  • the {@code solve} and {@code isNonSingular} methods have been replaced - * by a {@link #getSolver() getSolver} method and the equivalent methods - * provided by the returned {@link DecompositionSolver}.
  • - *
- * - * @see MathWorld - * @see Wikipedia - * @since 2.0 (changed to concrete class in 3.0) - */ -public class LUDecomposition { - /** Default bound to determine effective singularity in LU decomposition. */ - private static final double DEFAULT_TOO_SMALL = 1e-11; - /** Entries of LU decomposition. */ - private final double[][] lu; - /** Pivot permutation associated with LU decomposition. */ - private final int[] pivot; - /** Parity of the permutation associated with the LU decomposition. */ - private boolean even; - /** Singularity indicator. */ - private boolean singular; - /** Cached value of L. */ - private RealMatrix cachedL; - /** Cached value of U. */ - private RealMatrix cachedU; - /** Cached value of P. */ - private RealMatrix cachedP; - - /** - * Calculates the LU-decomposition of the given matrix. - * This constructor uses 1e-11 as default value for the singularity - * threshold. - * - * @param matrix Matrix to decompose. - * @throws NonSquareMatrixException if matrix is not square. - */ - public LUDecomposition(RealMatrix matrix) { - this(matrix, DEFAULT_TOO_SMALL); - } - - /** - * Calculates the LU-decomposition of the given matrix. - * @param matrix The matrix to decompose. - * @param singularityThreshold threshold (based on partial row norm) - * under which a matrix is considered singular - * @throws NonSquareMatrixException if matrix is not square - */ - public LUDecomposition(RealMatrix matrix, double singularityThreshold) { - if (!matrix.isSquare()) { - throw new NonSquareMatrixException(matrix.getRowDimension(), - matrix.getColumnDimension()); - } - - final int m = matrix.getColumnDimension(); - lu = matrix.getData(); - pivot = new int[m]; - cachedL = null; - cachedU = null; - cachedP = null; - - // Initialize permutation array and parity - for (int row = 0; row < m; row++) { - pivot[row] = row; - } - even = true; - singular = false; - - // Loop over columns - for (int col = 0; col < m; col++) { - - // upper - for (int row = 0; row < col; row++) { - final double[] luRow = lu[row]; - double sum = luRow[col]; - for (int i = 0; i < row; i++) { - sum -= luRow[i] * lu[i][col]; - } - luRow[col] = sum; - } - - // lower - int max = col; // permutation row - double largest = Double.NEGATIVE_INFINITY; - for (int row = col; row < m; row++) { - final double[] luRow = lu[row]; - double sum = luRow[col]; - for (int i = 0; i < col; i++) { - sum -= luRow[i] * lu[i][col]; - } - luRow[col] = sum; - - // maintain best permutation choice - if (FastMath.abs(sum) > largest) { - largest = FastMath.abs(sum); - max = row; - } - } - - // Singularity check - if (FastMath.abs(lu[max][col]) < singularityThreshold) { - singular = true; - return; - } - - // Pivot if necessary - if (max != col) { - double tmp = 0; - final double[] luMax = lu[max]; - final double[] luCol = lu[col]; - for (int i = 0; i < m; i++) { - tmp = luMax[i]; - luMax[i] = luCol[i]; - luCol[i] = tmp; - } - int temp = pivot[max]; - pivot[max] = pivot[col]; - pivot[col] = temp; - even = !even; - } - - // Divide the lower elements by the "winning" diagonal elt. - final double luDiag = lu[col][col]; - for (int row = col + 1; row < m; row++) { - lu[row][col] /= luDiag; - } - } - } - - /** - * Returns the matrix L of the decomposition. - *

L is a lower-triangular matrix

- * @return the L matrix (or null if decomposed matrix is singular) - */ - public RealMatrix getL() { - if ((cachedL == null) && !singular) { - final int m = pivot.length; - cachedL = MatrixUtils.createRealMatrix(m, m); - for (int i = 0; i < m; ++i) { - final double[] luI = lu[i]; - for (int j = 0; j < i; ++j) { - cachedL.setEntry(i, j, luI[j]); - } - cachedL.setEntry(i, i, 1.0); - } - } - return cachedL; - } - - /** - * Returns the matrix U of the decomposition. - *

U is an upper-triangular matrix

- * @return the U matrix (or null if decomposed matrix is singular) - */ - public RealMatrix getU() { - if ((cachedU == null) && !singular) { - final int m = pivot.length; - cachedU = MatrixUtils.createRealMatrix(m, m); - for (int i = 0; i < m; ++i) { - final double[] luI = lu[i]; - for (int j = i; j < m; ++j) { - cachedU.setEntry(i, j, luI[j]); - } - } - } - return cachedU; - } - - /** - * Returns the P rows permutation matrix. - *

P is a sparse matrix with exactly one element set to 1.0 in - * each row and each column, all other elements being set to 0.0.

- *

The positions of the 1 elements are given by the {@link #getPivot() - * pivot permutation vector}.

- * @return the P rows permutation matrix (or null if decomposed matrix is singular) - * @see #getPivot() - */ - public RealMatrix getP() { - if ((cachedP == null) && !singular) { - final int m = pivot.length; - cachedP = MatrixUtils.createRealMatrix(m, m); - for (int i = 0; i < m; ++i) { - cachedP.setEntry(i, pivot[i], 1.0); - } - } - return cachedP; - } - - /** - * Returns the pivot permutation vector. - * @return the pivot permutation vector - * @see #getP() - */ - public int[] getPivot() { - return pivot.clone(); - } - - /** - * Return the determinant of the matrix - * @return determinant of the matrix - */ - public double getDeterminant() { - if (singular) { - return 0; - } else { - final int m = pivot.length; - double determinant = even ? 1 : -1; - for (int i = 0; i < m; i++) { - determinant *= lu[i][i]; - } - return determinant; - } - } - - /** - * Get a solver for finding the A × X = B solution in exact linear - * sense. - * @return a solver - */ - public DecompositionSolver getSolver() { - return new Solver(lu, pivot, singular); - } - - /** Specialized solver. */ - private static class Solver implements DecompositionSolver { - - /** Entries of LU decomposition. */ - private final double[][] lu; - - /** Pivot permutation associated with LU decomposition. */ - private final int[] pivot; - - /** Singularity indicator. */ - private final boolean singular; - - /** - * Build a solver from decomposed matrix. - * @param lu entries of LU decomposition - * @param pivot pivot permutation associated with LU decomposition - * @param singular singularity indicator - */ - private Solver(final double[][] lu, final int[] pivot, final boolean singular) { - this.lu = lu; - this.pivot = pivot; - this.singular = singular; - } - - /** {@inheritDoc} */ - public boolean isNonSingular() { - return !singular; - } - - /** {@inheritDoc} */ - public RealVector solve(RealVector b) { - final int m = pivot.length; - if (b.getDimension() != m) { - throw new DimensionMismatchException(b.getDimension(), m); - } - if (singular) { - throw new SingularMatrixException(); - } - - final double[] bp = new double[m]; - - // Apply permutations to b - for (int row = 0; row < m; row++) { - bp[row] = b.getEntry(pivot[row]); - } - - // Solve LY = b - for (int col = 0; col < m; col++) { - final double bpCol = bp[col]; - for (int i = col + 1; i < m; i++) { - bp[i] -= bpCol * lu[i][col]; - } - } - - // Solve UX = Y - for (int col = m - 1; col >= 0; col--) { - bp[col] /= lu[col][col]; - final double bpCol = bp[col]; - for (int i = 0; i < col; i++) { - bp[i] -= bpCol * lu[i][col]; - } - } - - return new ArrayRealVector(bp, false); - } - - /** {@inheritDoc} */ - public RealMatrix solve(RealMatrix b) { - - final int m = pivot.length; - if (b.getRowDimension() != m) { - throw new DimensionMismatchException(b.getRowDimension(), m); - } - if (singular) { - throw new SingularMatrixException(); - } - - final int nColB = b.getColumnDimension(); - - // Apply permutations to b - final double[][] bp = new double[m][nColB]; - for (int row = 0; row < m; row++) { - final double[] bpRow = bp[row]; - final int pRow = pivot[row]; - for (int col = 0; col < nColB; col++) { - bpRow[col] = b.getEntry(pRow, col); - } - } - - // Solve LY = b - for (int col = 0; col < m; col++) { - final double[] bpCol = bp[col]; - for (int i = col + 1; i < m; i++) { - final double[] bpI = bp[i]; - final double luICol = lu[i][col]; - for (int j = 0; j < nColB; j++) { - bpI[j] -= bpCol[j] * luICol; - } - } - } - - // Solve UX = Y - for (int col = m - 1; col >= 0; col--) { - final double[] bpCol = bp[col]; - final double luDiag = lu[col][col]; - for (int j = 0; j < nColB; j++) { - bpCol[j] /= luDiag; - } - for (int i = 0; i < col; i++) { - final double[] bpI = bp[i]; - final double luICol = lu[i][col]; - for (int j = 0; j < nColB; j++) { - bpI[j] -= bpCol[j] * luICol; - } - } - } - - return new Array2DRowRealMatrix(bp, false); - } - - /** - * Get the inverse of the decomposed matrix. - * - * @return the inverse matrix. - * @throws SingularMatrixException if the decomposed matrix is singular. - */ - public RealMatrix getInverse() { - return solve(MatrixUtils.createRealIdentityMatrix(pivot.length)); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/MatrixDimensionMismatchException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/MatrixDimensionMismatchException.java b/src/main/java/org/apache/commons/math3/linear/MatrixDimensionMismatchException.java deleted file mode 100644 index effbf11..0000000 --- a/src/main/java/org/apache/commons/math3/linear/MatrixDimensionMismatchException.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.MultiDimensionMismatchException; -import org.apache.commons.math3.exception.util.LocalizedFormats; - -/** - * Exception to be thrown when either the number of rows or the number of - * columns of a matrix do not match the expected values. - * - * @since 3.0 - */ -public class MatrixDimensionMismatchException extends MultiDimensionMismatchException { - /** Serializable version Id. */ - private static final long serialVersionUID = -8415396756375798143L; - - /** - * Construct an exception from the mismatched dimensions. - * - * @param wrongRowDim Wrong row dimension. - * @param wrongColDim Wrong column dimension. - * @param expectedRowDim Expected row dimension. - * @param expectedColDim Expected column dimension. - */ - public MatrixDimensionMismatchException(int wrongRowDim, - int wrongColDim, - int expectedRowDim, - int expectedColDim) { - super(LocalizedFormats.DIMENSIONS_MISMATCH_2x2, - new Integer[] { wrongRowDim, wrongColDim }, - new Integer[] { expectedRowDim, expectedColDim }); - } - - /** - * @return the expected row dimension. - */ - public int getWrongRowDimension() { - return getWrongDimension(0); - } - /** - * @return the expected row dimension. - */ - public int getExpectedRowDimension() { - return getExpectedDimension(0); - } - /** - * @return the wrong column dimension. - */ - public int getWrongColumnDimension() { - return getWrongDimension(1); - } - /** - * @return the expected column dimension. - */ - public int getExpectedColumnDimension() { - return getExpectedDimension(1); - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java b/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java deleted file mode 100644 index 23c11e0..0000000 --- a/src/main/java/org/apache/commons/math3/linear/MatrixUtils.java +++ /dev/null @@ -1,1119 +0,0 @@ -/* - * 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 java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Arrays; - -import org.apache.commons.math3.Field; -import org.apache.commons.math3.FieldElement; -import org.apache.commons.math3.exception.DimensionMismatchException; -import org.apache.commons.math3.exception.MathArithmeticException; -import org.apache.commons.math3.exception.NoDataException; -import org.apache.commons.math3.exception.NullArgumentException; -import org.apache.commons.math3.exception.NumberIsTooSmallException; -import org.apache.commons.math3.exception.OutOfRangeException; -import org.apache.commons.math3.exception.ZeroException; -import org.apache.commons.math3.exception.util.LocalizedFormats; -import org.apache.commons.math3.fraction.BigFraction; -import org.apache.commons.math3.fraction.Fraction; -import org.apache.commons.math3.util.FastMath; -import org.apache.commons.math3.util.MathArrays; -import org.apache.commons.math3.util.MathUtils; -import org.apache.commons.math3.util.Precision; - -/** - * A collection of static methods that operate on or return matrices. - * - */ -public class MatrixUtils { - - /** - * The default format for {@link RealMatrix} objects. - * @since 3.1 - */ - public static final RealMatrixFormat DEFAULT_FORMAT = RealMatrixFormat.getInstance(); - - /** - * A format for {@link RealMatrix} objects compatible with octave. - * @since 3.1 - */ - public static final RealMatrixFormat OCTAVE_FORMAT = new RealMatrixFormat("[", "]", "", "", "; ", ", "); - - /** - * Private constructor. - */ - private MatrixUtils() { - super(); - } - - /** - * Returns a {@link RealMatrix} with specified dimensions. - *

The type of matrix returned depends on the dimension. Below - * 212 elements (i.e. 4096 elements or 64×64 for a - * square matrix) which can be stored in a 32kB array, a {@link - * Array2DRowRealMatrix} instance is built. Above this threshold a {@link - * BlockRealMatrix} instance is built.

- *

The matrix elements are all set to 0.0.

- * @param rows number of rows of the matrix - * @param columns number of columns of the matrix - * @return RealMatrix with specified dimensions - * @see #createRealMatrix(double[][]) - */ - public static RealMatrix createRealMatrix(final int rows, final int columns) { - return (rows * columns <= 4096) ? - new Array2DRowRealMatrix(rows, columns) : new BlockRealMatrix(rows, columns); - } - - /** - * Returns a {@link FieldMatrix} with specified dimensions. - *

The type of matrix returned depends on the dimension. Below - * 212 elements (i.e. 4096 elements or 64×64 for a - * square matrix), a {@link FieldMatrix} instance is built. Above - * this threshold a {@link BlockFieldMatrix} instance is built.

- *

The matrix elements are all set to field.getZero().

- * @param the type of the field elements - * @param field field to which the matrix elements belong - * @param rows number of rows of the matrix - * @param columns number of columns of the matrix - * @return FieldMatrix with specified dimensions - * @see #createFieldMatrix(FieldElement[][]) - * @since 2.0 - */ - public static > FieldMatrix createFieldMatrix(final Field field, - final int rows, - final int columns) { - return (rows * columns <= 4096) ? - new Array2DRowFieldMatrix(field, rows, columns) : new BlockFieldMatrix(field, rows, columns); - } - - /** - * Returns a {@link RealMatrix} whose entries are the the values in the - * the input array. - *

The type of matrix returned depends on the dimension. Below - * 212 elements (i.e. 4096 elements or 64×64 for a - * square matrix) which can be stored in a 32kB array, a {@link - * Array2DRowRealMatrix} instance is built. Above this threshold a {@link - * BlockRealMatrix} instance is built.

- *

The input array is copied, not referenced.

- * - * @param data input array - * @return RealMatrix containing the values of the array - * @throws org.apache.commons.math3.exception.DimensionMismatchException - * if {@code data} is not rectangular (not all rows have the same length). - * @throws NoDataException if a row or column is empty. - * @throws NullArgumentException if either {@code data} or {@code data[0]} - * is {@code null}. - * @throws DimensionMismatchException if {@code data} is not rectangular. - * @see #createRealMatrix(int, int) - */ - public static RealMatrix createRealMatrix(double[][] data) - throws NullArgumentException, DimensionMismatchException, - NoDataException { - if (data == null || - data[0] == null) { - throw new NullArgumentException(); - } - return (data.length * data[0].length <= 4096) ? - new Array2DRowRealMatrix(data) : new BlockRealMatrix(data); - } - - /** - * Returns a {@link FieldMatrix} whose entries are the the values in the - * the input array. - *

The type of matrix returned depends on the dimension. Below - * 212 elements (i.e. 4096 elements or 64×64 for a - * square matrix), a {@link FieldMatrix} instance is built. Above - * this threshold a {@link BlockFieldMatrix} instance is built.

- *

The input array is copied, not referenced.

- * @param the type of the field elements - * @param data input array - * @return a matrix containing the values of the array. - * @throws org.apache.commons.math3.exception.DimensionMismatchException - * if {@code data} is not rectangular (not all rows have the same length). - * @throws NoDataException if a row or column is empty. - * @throws NullArgumentException if either {@code data} or {@code data[0]} - * is {@code null}. - * @see #createFieldMatrix(Field, int, int) - * @since 2.0 - */ - public static > FieldMatrix createFieldMatrix(T[][] data) - throws DimensionMismatchException, NoDataException, NullArgumentException { - if (data == null || - data[0] == null) { - throw new NullArgumentException(); - } - return (data.length * data[0].length <= 4096) ? - new Array2DRowFieldMatrix(data) : new BlockFieldMatrix(data); - } - - /** - * Returns dimension x dimension identity matrix. - * - * @param dimension dimension of identity matrix to generate - * @return identity matrix - * @throws IllegalArgumentException if dimension is not positive - * @since 1.1 - */ - public static RealMatrix createRealIdentityMatrix(int dimension) { - final RealMatrix m = createRealMatrix(dimension, dimension); - for (int i = 0; i < dimension; ++i) { - m.setEntry(i, i, 1.0); - } - return m; - } - - /** - * Returns dimension x dimension identity matrix. - * - * @param the type of the field elements - * @param field field to which the elements belong - * @param dimension dimension of identity matrix to generate - * @return identity matrix - * @throws IllegalArgumentException if dimension is not positive - * @since 2.0 - */ - public static > FieldMatrix - createFieldIdentityMatrix(final Field field, final int dimension) { - final T zero = field.getZero(); - final T one = field.getOne(); - final T[][] d = MathArrays.buildArray(field, dimension, dimension); - for (int row = 0; row < dimension; row++) { - final T[] dRow = d[row]; - Arrays.fill(dRow, zero); - dRow[row] = one; - } - return new Array2DRowFieldMatrix(field, d, false); - } - - /** - * Returns a diagonal matrix with specified elements. - * - * @param diagonal diagonal elements of the matrix (the array elements - * will be copied) - * @return diagonal matrix - * @since 2.0 - */ - public static RealMatrix createRealDiagonalMatrix(final double[] diagonal) { - final RealMatrix m = createRealMatrix(diagonal.length, diagonal.length); - for (int i = 0; i < diagonal.length; ++i) { - m.setEntry(i, i, diagonal[i]); - } - return m; - } - - /** - * Returns a diagonal matrix with specified elements. - * - * @param the type of the field elements - * @param diagonal diagonal elements of the matrix (the array elements - * will be copied) - * @return diagonal matrix - * @since 2.0 - */ - public static > FieldMatrix - createFieldDiagonalMatrix(final T[] diagonal) { - final FieldMatrix m = - createFieldMatrix(diagonal[0].getField(), diagonal.length, diagonal.length); - for (int i = 0; i < diagonal.length; ++i) { - m.setEntry(i, i, diagonal[i]); - } - return m; - } - - /** - * Creates a {@link RealVector} using the data from the input array. - * - * @param data the input data - * @return a data.length RealVector - * @throws NoDataException if {@code data} is empty. - * @throws NullArgumentException if {@code data} is {@code null}. - */ - public static RealVector createRealVector(double[] data) - throws NoDataException, NullArgumentException { - if (data == null) { - throw new NullArgumentException(); - } - return new ArrayRealVector(data, true); - } - - /** - * Creates a {@link FieldVector} using the data from the input array. - * - * @param the type of the field elements - * @param data the input data - * @return a data.length FieldVector - * @throws NoDataException if {@code data} is empty. - * @throws NullArgumentException if {@code data} is {@code null}. - * @throws ZeroException if {@code data} has 0 elements - */ - public static > FieldVector createFieldVector(final T[] data) - throws NoDataException, NullArgumentException, ZeroException { - if (data == null) { - throw new NullArgumentException(); - } - if (data.length == 0) { - throw new ZeroException(LocalizedFormats.VECTOR_MUST_HAVE_AT_LEAST_ONE_ELEMENT); - } - return new ArrayFieldVector(data[0].getField(), data, true); - } - - /** - * Create a row {@link RealMatrix} using the data from the input - * array. - * - * @param rowData the input row data - * @return a 1 x rowData.length RealMatrix - * @throws NoDataException if {@code rowData} is empty. - * @throws NullArgumentException if {@code rowData} is {@code null}. - */ - public static RealMatrix createRowRealMatrix(double[] rowData) - throws NoDataException, NullArgumentException { - if (rowData == null) { - throw new NullArgumentException(); - } - final int nCols = rowData.length; - final RealMatrix m = createRealMatrix(1, nCols); - for (int i = 0; i < nCols; ++i) { - m.setEntry(0, i, rowData[i]); - } - return m; - } - - /** - * Create a row {@link FieldMatrix} using the data from the input - * array. - * - * @param the type of the field elements - * @param rowData the input row data - * @return a 1 x rowData.length FieldMatrix - * @throws NoDataException if {@code rowData} is empty. - * @throws NullArgumentException if {@code rowData} is {@code null}. - */ - public static > FieldMatrix - createRowFieldMatrix(final T[] rowData) - throws NoDataException, NullArgumentException { - if (rowData == null) { - throw new NullArgumentException(); - } - final int nCols = rowData.length; - if (nCols == 0) { - throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_COLUMN); - } - final FieldMatrix m = createFieldMatrix(rowData[0].getField(), 1, nCols); - for (int i = 0; i < nCols; ++i) { - m.setEntry(0, i, rowData[i]); - } - return m; - } - - /** - * Creates a column {@link RealMatrix} using the data from the input - * array. - * - * @param columnData the input column data - * @return a columnData x 1 RealMatrix - * @throws NoDataException if {@code columnData} is empty. - * @throws NullArgumentException if {@code columnData} is {@code null}. - */ - public static RealMatrix createColumnRealMatrix(double[] columnData) - throws NoDataException, NullArgumentException { - if (columnData == null) { - throw new NullArgumentException(); - } - final int nRows = columnData.length; - final RealMatrix m = createRealMatrix(nRows, 1); - for (int i = 0; i < nRows; ++i) { - m.setEntry(i, 0, columnData[i]); - } - return m; - } - - /** - * Creates a column {@link FieldMatrix} using the data from the input - * array. - * - * @param the type of the field elements - * @param columnData the input column data - * @return a columnData x 1 FieldMatrix - * @throws NoDataException if {@code data} is empty. - * @throws NullArgumentException if {@code columnData} is {@code null}. - */ - public static > FieldMatrix - createColumnFieldMatrix(final T[] columnData) - throws NoDataException, NullArgumentException { - if (columnData == null) { - throw new NullArgumentException(); - } - final int nRows = columnData.length; - if (nRows == 0) { - throw new NoDataException(LocalizedFormats.AT_LEAST_ONE_ROW); - } - final FieldMatrix m = createFieldMatrix(columnData[0].getField(), nRows, 1); - for (int i = 0; i < nRows; ++i) { - m.setEntry(i, 0, columnData[i]); - } - return m; - } - - /** - * Checks whether a matrix is symmetric, within a given relative tolerance. - * - * @param matrix Matrix to check. - * @param relativeTolerance Tolerance of the symmetry check. - * @param raiseException If {@code true}, an exception will be raised if - * the matrix is not symmetric. - * @return {@code true} if {@code matrix} is symmetric. - * @throws NonSquareMatrixException if the matrix is not square. - * @throws NonSymmetricMatrixException if the matrix is not symmetric. - */ - private static boolean isSymmetricInternal(RealMatrix matrix, - double relativeTolerance, - boolean raiseException) { - final int rows = matrix.getRowDimension(); - if (rows != matrix.getColumnDimension()) { - if (raiseException) { - throw new NonSquareMatrixException(rows, matrix.getColumnDimension()); - } else { - return false; - } - } - for (int i = 0; i < rows; i++) { - for (int j = i + 1; j < rows; j++) { - final double mij = matrix.getEntry(i, j); - final double mji = matrix.getEntry(j, i); - if (FastMath.abs(mij - mji) > - FastMath.max(FastMath.abs(mij), FastMath.abs(mji)) * relativeTolerance) { - if (raiseException) { - throw new NonSymmetricMatrixException(i, j, relativeTolerance); - } else { - return false; - } - } - } - } - return true; - } - - /** - * Checks whether a matrix is symmetric. - * - * @param matrix Matrix to check. - * @param eps Relative tolerance. - * @throws NonSquareMatrixException if the matrix is not square. - * @throws NonSymmetricMatrixException if the matrix is not symmetric. - * @since 3.1 - */ - public static void checkSymmetric(RealMatrix matrix, - double eps) { - isSymmetricInternal(matrix, eps, true); - } - - /** - * Checks whether a matrix is symmetric. - * - * @param matrix Matrix to check. - * @param eps Relative tolerance. - * @return {@code true} if {@code matrix} is symmetric. - * @since 3.1 - */ - public static boolean isSymmetric(RealMatrix matrix, - double eps) { - return isSymmetricInternal(matrix, eps, false); - } - - /** - * Check if matrix indices are valid. - * - * @param m Matrix. - * @param row Row index to check. - * @param column Column index to check. - * @throws OutOfRangeException if {@code row} or {@code column} is not - * a valid index. - */ - public static void checkMatrixIndex(final AnyMatrix m, - final int row, final int column) - throws OutOfRangeException { - checkRowIndex(m, row); - checkColumnIndex(m, column); - } - - /** - * Check if a row index is valid. - * - * @param m Matrix. - * @param row Row index to check. - * @throws OutOfRangeException if {@code row} is not a valid index. - */ - public static void checkRowIndex(final AnyMatrix m, final int row) - throws OutOfRangeException { - if (row < 0 || - row >= m.getRowDimension()) { - throw new OutOfRangeException(LocalizedFormats.ROW_INDEX, - row, 0, m.getRowDimension() - 1); - } - } - - /** - * Check if a column index is valid. - * - * @param m Matrix. - * @param column Column index to check. - * @throws OutOfRangeException if {@code column} is not a valid index. - */ - public static void checkColumnIndex(final AnyMatrix m, final int column) - throws OutOfRangeException { - if (column < 0 || column >= m.getColumnDimension()) { - throw new OutOfRangeException(LocalizedFormats.COLUMN_INDEX, - column, 0, m.getColumnDimension() - 1); - } - } - - /** - * Check if submatrix ranges indices are valid. - * Rows and columns are indicated counting from 0 to {@code n - 1}. - * - * @param m Matrix. - * @param startRow Initial row index. - * @param endRow Final row index. - * @param startColumn Initial column index. - * @param endColumn Final column index. - * @throws OutOfRangeException if the indices are invalid. - * @throws NumberIsTooSmallException if {@code endRow < startRow} or - * {@code endColumn < startColumn}. - */ - public static void checkSubMatrixIndex(final AnyMatrix m, - final int startRow, final int endRow, - final int startColumn, final int endColumn) - throws NumberIsTooSmallException, OutOfRangeException { - checkRowIndex(m, startRow); - checkRowIndex(m, endRow); - if (endRow < startRow) { - throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_ROW_AFTER_FINAL_ROW, - endRow, startRow, false); - } - - checkColumnIndex(m, startColumn); - checkColumnIndex(m, endColumn); - if (endColumn < startColumn) { - throw new NumberIsTooSmallException(LocalizedFormats.INITIAL_COLUMN_AFTER_FINAL_COLUMN, - endColumn, startColumn, false); - } - - - } - - /** - * Check if submatrix ranges indices are valid. - * Rows and columns are indicated counting from 0 to n-1. - * - * @param m Matrix. - * @param selectedRows Array of row indices. - * @param selectedColumns Array of column indices. - * @throws NullArgumentException if {@code selectedRows} or - * {@code selectedColumns} are {@code null}. - * @throws NoDataException if the row or column selections are empty (zero - * length). - * @throws OutOfRangeException if row or column selections are not valid. - */ - public static void checkSubMatrixIndex(final AnyMatrix m, - final int[] selectedRows, - final int[] selectedColumns) - throws NoDataException, NullArgumentException, OutOfRangeException { - if (selectedRows == null) { - throw new NullArgumentException(); - } - if (selectedColumns == null) { - throw new NullArgumentException(); - } - if (selectedRows.length == 0) { - throw new NoDataException(LocalizedFormats.EMPTY_SELECTED_ROW_INDEX_ARRAY); - } - if (selectedColumns.length == 0) { - throw new NoDataException(LocalizedFormats.EMPTY_SELECTED_COLUMN_INDEX_ARRAY); - } - - for (final int row : selectedRows) { - checkRowIndex(m, row); - } - for (final int column : selectedColumns) { - checkColumnIndex(m, column); - } - } - - /** - * Check if matrices are addition compatible. - * - * @param left Left hand side matrix. - * @param right Right hand side matrix. - * @throws MatrixDimensionMismatchException if the matrices are not addition - * compatible. - */ - public static void checkAdditionCompatible(final AnyMatrix left, final AnyMatrix right) - throws MatrixDimensionMismatchException { - if ((left.getRowDimension() != right.getRowDimension()) || - (left.getColumnDimension() != right.getColumnDimension())) { - throw new MatrixDimensionMismatchException(left.getRowDimension(), left.getColumnDimension(), - right.getRowDimension(), right.getColumnDimension()); - } - } - - /** - * Check if matrices are subtraction compatible - * - * @param left Left hand side matrix. - * @param right Right hand side matrix. - * @throws MatrixDimensionMismatchException if the matrices are not addition - * compatible. - */ - public static void checkSubtractionCompatible(final AnyMatrix left, final AnyMatrix right) - throws MatrixDimensionMismatchException { - if ((left.getRowDimension() != right.getRowDimension()) || - (left.getColumnDimension() != right.getColumnDimension())) { - throw new MatrixDimensionMismatchException(left.getRowDimension(), left.getColumnDimension(), - right.getRowDimension(), right.getColumnDimension()); - } - } - - /** - * Check if matrices are multiplication compatible - * - * @param left Left hand side matrix. - * @param right Right hand side matrix. - * @throws DimensionMismatchException if matrices are not multiplication - * compatible. - */ - public static void checkMultiplicationCompatible(final AnyMatrix left, final AnyMatrix right) - throws DimensionMismatchException { - - if (left.getColumnDimension() != right.getRowDimension()) { - throw new DimensionMismatchException(left.getColumnDimension(), - right.getRowDimension()); - } - } - - /** - * Convert a {@link FieldMatrix}/{@link Fraction} matrix to a {@link RealMatrix}. - * @param m Matrix to convert. - * @return the converted matrix. - */ - public static Array2DRowRealMatrix fractionMatrixToRealMatrix(final FieldMatrix m) { - final FractionMatrixConverter converter = new FractionMatrixConverter(); - m.walkInOptimizedOrder(converter); - return converter.getConvertedMatrix(); - } - - /** Converter for {@link FieldMatrix}/{@link Fraction}. */ - private static class FractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor { - /** Converted array. */ - private double[][] data; - /** Simple constructor. */ - public FractionMatrixConverter() { - super(Fraction.ZERO); - } - - /** {@inheritDoc} */ - @Override - public void start(int rows, int columns, - int startRow, int endRow, int startColumn, int endColumn) { - data = new double[rows][columns]; - } - - /** {@inheritDoc} */ - @Override - public void visit(int row, int column, Fraction value) { - data[row][column] = value.doubleValue(); - } - - /** - * Get the converted matrix. - * - * @return the converted matrix. - */ - Array2DRowRealMatrix getConvertedMatrix() { - return new Array2DRowRealMatrix(data, false); - } - - } - - /** - * Convert a {@link FieldMatrix}/{@link BigFraction} matrix to a {@link RealMatrix}. - * - * @param m Matrix to convert. - * @return the converted matrix. - */ - public static Array2DRowRealMatrix bigFractionMatrixToRealMatrix(final FieldMatrix m) { - final BigFractionMatrixConverter converter = new BigFractionMatrixConverter(); - m.walkInOptimizedOrder(converter); - return converter.getConvertedMatrix(); - } - - /** Converter for {@link FieldMatrix}/{@link BigFraction}. */ - private static class BigFractionMatrixConverter extends DefaultFieldMatrixPreservingVisitor { - /** Converted array. */ - private double[][] data; - /** Simple constructor. */ - public BigFractionMatrixConverter() { - super(BigFraction.ZERO); - } - - /** {@inheritDoc} */ - @Override - public void start(int rows, int columns, - int startRow, int endRow, int startColumn, int endColumn) { - data = new double[rows][columns]; - } - - /** {@inheritDoc} */ - @Override - public void visit(int row, int column, BigFraction value) { - data[row][column] = value.doubleValue(); - } - - /** - * Get the converted matrix. - * - * @return the converted matrix. - */ - Array2DRowRealMatrix getConvertedMatrix() { - return new Array2DRowRealMatrix(data, false); - } - } - - /** Serialize a {@link RealVector}. - *

- * This method is intended to be called from within a private - * writeObject method (after a call to - * oos.defaultWriteObject()) in a class that has a - * {@link RealVector} field, which should be declared transient. - * This way, the default handling does not serialize the vector (the {@link - * RealVector} interface is not serializable by default) but this method does - * serialize it specifically. - *

- *

- * The following example shows how a simple class with a name and a real vector - * should be written: - *


-     * public class NamedVector implements Serializable {
-     *
-     *     private final String name;
-     *     private final transient RealVector coefficients;
-     *
-     *     // omitted constructors, getters ...
-     *
-     *     private void writeObject(ObjectOutputStream oos) throws IOException {
-     *         oos.defaultWriteObject();  // takes care of name field
-     *         MatrixUtils.serializeRealVector(coefficients, oos);
-     *     }
-     *
-     *     private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
-     *         ois.defaultReadObject();  // takes care of name field
-     *         MatrixUtils.deserializeRealVector(this, "coefficients", ois);
-     *     }
-     *
-     * }
-     * 
- *

- * - * @param vector real vector to serialize - * @param oos stream where the real vector should be written - * @exception IOException if object cannot be written to stream - * @see #deserializeRealVector(Object, String, ObjectInputStream) - */ - public static void serializeRealVector(final RealVector vector, - final ObjectOutputStream oos) - throws IOException { - final int n = vector.getDimension(); - oos.writeInt(n); - for (int i = 0; i < n; ++i) { - oos.writeDouble(vector.getEntry(i)); - } - } - - /** Deserialize a {@link RealVector} field in a class. - *

- * This method is intended to be called from within a private - * readObject method (after a call to - * ois.defaultReadObject()) in a class that has a - * {@link RealVector} field, which should be declared transient. - * This way, the default handling does not deserialize the vector (the {@link - * RealVector} interface is not serializable by default) but this method does - * deserialize it specifically. - *

- * @param instance instance in which the field must be set up - * @param fieldName name of the field within the class (may be private and final) - * @param ois stream from which the real vector should be read - * @exception ClassNotFoundException if a class in the stream cannot be found - * @exception IOException if object cannot be read from the stream - * @see #serializeRealVector(RealVector, ObjectOutputStream) - */ - public static void deserializeRealVector(final Object instance, - final String fieldName, - final ObjectInputStream ois) - throws ClassNotFoundException, IOException { - try { - - // read the vector data - final int n = ois.readInt(); - final double[] data = new double[n]; - for (int i = 0; i < n; ++i) { - data[i] = ois.readDouble(); - } - - // create the instance - final RealVector vector = new ArrayRealVector(data, false); - - // set up the field - final java.lang.reflect.Field f = - instance.getClass().getDeclaredField(fieldName); - f.setAccessible(true); - f.set(instance, vector); - - } catch (NoSuchFieldException nsfe) { - IOException ioe = new IOException(); - ioe.initCause(nsfe); - throw ioe; - } catch (IllegalAccessException iae) { - IOException ioe = new IOException(); - ioe.initCause(iae); - throw ioe; - } - - } - - /** Serialize a {@link RealMatrix}. - *

- * This method is intended to be called from within a private - * writeObject method (after a call to - * oos.defaultWriteObject()) in a class that has a - * {@link RealMatrix} field, which should be declared transient. - * This way, the default handling does not serialize the matrix (the {@link - * RealMatrix} interface is not serializable by default) but this method does - * serialize it specifically. - *

- *

- * The following example shows how a simple class with a name and a real matrix - * should be written: - *


-     * public class NamedMatrix implements Serializable {
-     *
-     *     private final String name;
-     *     private final transient RealMatrix coefficients;
-     *
-     *     // omitted constructors, getters ...
-     *
-     *     private void writeObject(ObjectOutputStream oos) throws IOException {
-     *         oos.defaultWriteObject();  // takes care of name field
-     *         MatrixUtils.serializeRealMatrix(coefficients, oos);
-     *     }
-     *
-     *     private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
-     *         ois.defaultReadObject();  // takes care of name field
-     *         MatrixUtils.deserializeRealMatrix(this, "coefficients", ois);
-     *     }
-     *
-     * }
-     * 
- *

- * - * @param matrix real matrix to serialize - * @param oos stream where the real matrix should be written - * @exception IOException if object cannot be written to stream - * @see #deserializeRealMatrix(Object, String, ObjectInputStream) - */ - public static void serializeRealMatrix(final RealMatrix matrix, - final ObjectOutputStream oos) - throws IOException { - final int n = matrix.getRowDimension(); - final int m = matrix.getColumnDimension(); - oos.writeInt(n); - oos.writeInt(m); - for (int i = 0; i < n; ++i) { - for (int j = 0; j < m; ++j) { - oos.writeDouble(matrix.getEntry(i, j)); - } - } - } - - /** Deserialize a {@link RealMatrix} field in a class. - *

- * This method is intended to be called from within a private - * readObject method (after a call to - * ois.defaultReadObject()) in a class that has a - * {@link RealMatrix} field, which should be declared transient. - * This way, the default handling does not deserialize the matrix (the {@link - * RealMatrix} interface is not serializable by default) but this method does - * deserialize it specifically. - *

- * @param instance instance in which the field must be set up - * @param fieldName name of the field within the class (may be private and final) - * @param ois stream from which the real matrix should be read - * @exception ClassNotFoundException if a class in the stream cannot be found - * @exception IOException if object cannot be read from the stream - * @see #serializeRealMatrix(RealMatrix, ObjectOutputStream) - */ - public static void deserializeRealMatrix(final Object instance, - final String fieldName, - final ObjectInputStream ois) - throws ClassNotFoundException, IOException { - try { - - // read the matrix data - final int n = ois.readInt(); - final int m = ois.readInt(); - final double[][] data = new double[n][m]; - for (int i = 0; i < n; ++i) { - final double[] dataI = data[i]; - for (int j = 0; j < m; ++j) { - dataI[j] = ois.readDouble(); - } - } - - // create the instance - final RealMatrix matrix = new Array2DRowRealMatrix(data, false); - - // set up the field - final java.lang.reflect.Field f = - instance.getClass().getDeclaredField(fieldName); - f.setAccessible(true); - f.set(instance, matrix); - - } catch (NoSuchFieldException nsfe) { - IOException ioe = new IOException(); - ioe.initCause(nsfe); - throw ioe; - } catch (IllegalAccessException iae) { - IOException ioe = new IOException(); - ioe.initCause(iae); - throw ioe; - } - } - - /**Solve a system of composed of a Lower Triangular Matrix - * {@link RealMatrix}. - *

- * This method is called to solve systems of equations which are - * of the lower triangular form. The matrix {@link RealMatrix} - * is assumed, though not checked, to be in lower triangular form. - * The vector {@link RealVector} is overwritten with the solution. - * The matrix is checked that it is square and its dimensions match - * the length of the vector. - *

- * @param rm RealMatrix which is lower triangular - * @param b RealVector this is overwritten - * @throws DimensionMismatchException if the matrix and vector are not - * conformable - * @throws NonSquareMatrixException if the matrix {@code rm} is not square - * @throws MathArithmeticException if the absolute value of one of the diagonal - * coefficient of {@code rm} is lower than {@link Precision#SAFE_MIN} - */ - public static void solveLowerTriangularSystem(RealMatrix rm, RealVector b) - throws DimensionMismatchException, MathArithmeticException, - NonSquareMatrixException { - if ((rm == null) || (b == null) || ( rm.getRowDimension() != b.getDimension())) { - throw new DimensionMismatchException( - (rm == null) ? 0 : rm.getRowDimension(), - (b == null) ? 0 : b.getDimension()); - } - if( rm.getColumnDimension() != rm.getRowDimension() ){ - throw new NonSquareMatrixException(rm.getRowDimension(), - rm.getColumnDimension()); - } - int rows = rm.getRowDimension(); - for( int i = 0 ; i < rows ; i++ ){ - double diag = rm.getEntry(i, i); - if( FastMath.abs(diag) < Precision.SAFE_MIN ){ - throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); - } - double bi = b.getEntry(i)/diag; - b.setEntry(i, bi ); - for( int j = i+1; j< rows; j++ ){ - b.setEntry(j, b.getEntry(j)-bi*rm.getEntry(j,i) ); - } - } - } - - /** Solver a system composed of an Upper Triangular Matrix - * {@link RealMatrix}. - *

- * This method is called to solve systems of equations which are - * of the lower triangular form. The matrix {@link RealMatrix} - * is assumed, though not checked, to be in upper triangular form. - * The vector {@link RealVector} is overwritten with the solution. - * The matrix is checked that it is square and its dimensions match - * the length of the vector. - *

- * @param rm RealMatrix which is upper triangular - * @param b RealVector this is overwritten - * @throws DimensionMismatchException if the matrix and vector are not - * conformable - * @throws NonSquareMatrixException if the matrix {@code rm} is not - * square - * @throws MathArithmeticException if the absolute value of one of the diagonal - * coefficient of {@code rm} is lower than {@link Precision#SAFE_MIN} - */ - public static void solveUpperTriangularSystem(RealMatrix rm, RealVector b) - throws DimensionMismatchException, MathArithmeticException, - NonSquareMatrixException { - if ((rm == null) || (b == null) || ( rm.getRowDimension() != b.getDimension())) { - throw new DimensionMismatchException( - (rm == null) ? 0 : rm.getRowDimension(), - (b == null) ? 0 : b.getDimension()); - } - if( rm.getColumnDimension() != rm.getRowDimension() ){ - throw new NonSquareMatrixException(rm.getRowDimension(), - rm.getColumnDimension()); - } - int rows = rm.getRowDimension(); - for( int i = rows-1 ; i >-1 ; i-- ){ - double diag = rm.getEntry(i, i); - if( FastMath.abs(diag) < Precision.SAFE_MIN ){ - throw new MathArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); - } - double bi = b.getEntry(i)/diag; - b.setEntry(i, bi ); - for( int j = i-1; j>-1; j-- ){ - b.setEntry(j, b.getEntry(j)-bi*rm.getEntry(j,i) ); - } - } - } - - /** - * Computes the inverse of the given matrix by splitting it into - * 4 sub-matrices. - * - * @param m Matrix whose inverse must be computed. - * @param splitIndex Index that determines the "split" line and - * column. - * The element corresponding to this index will part of the - * upper-left sub-matrix. - * @return the inverse of {@code m}. - * @throws NonSquareMatrixException if {@code m} is not square. - */ - public static RealMatrix blockInverse(RealMatrix m, - int splitIndex) { - final int n = m.getRowDimension(); - if (m.getColumnDimension() != n) { - throw new NonSquareMatrixException(m.getRowDimension(), - m.getColumnDimension()); - } - - final int splitIndex1 = splitIndex + 1; - - final RealMatrix a = m.getSubMatrix(0, splitIndex, 0, splitIndex); - final RealMatrix b = m.getSubMatrix(0, splitIndex, splitIndex1, n - 1); - final RealMatrix c = m.getSubMatrix(splitIndex1, n - 1, 0, splitIndex); - final RealMatrix d = m.getSubMatrix(splitIndex1, n - 1, splitIndex1, n - 1); - - final SingularValueDecomposition aDec = new SingularValueDecomposition(a); - final DecompositionSolver aSolver = aDec.getSolver(); - if (!aSolver.isNonSingular()) { - throw new SingularMatrixException(); - } - final RealMatrix aInv = aSolver.getInverse(); - - final SingularValueDecomposition dDec = new SingularValueDecomposition(d); - final DecompositionSolver dSolver = dDec.getSolver(); - if (!dSolver.isNonSingular()) { - throw new SingularMatrixException(); - } - final RealMatrix dInv = dSolver.getInverse(); - - final RealMatrix tmp1 = a.subtract(b.multiply(dInv).multiply(c)); - final SingularValueDecomposition tmp1Dec = new SingularValueDecomposition(tmp1); - final DecompositionSolver tmp1Solver = tmp1Dec.getSolver(); - if (!tmp1Solver.isNonSingular()) { - throw new SingularMatrixException(); - } - final RealMatrix result00 = tmp1Solver.getInverse(); - - final RealMatrix tmp2 = d.subtract(c.multiply(aInv).multiply(b)); - final SingularValueDecomposition tmp2Dec = new SingularValueDecomposition(tmp2); - final DecompositionSolver tmp2Solver = tmp2Dec.getSolver(); - if (!tmp2Solver.isNonSingular()) { - throw new SingularMatrixException(); - } - final RealMatrix result11 = tmp2Solver.getInverse(); - - final RealMatrix result01 = aInv.multiply(b).multiply(result11).scalarMultiply(-1); - final RealMatrix result10 = dInv.multiply(c).multiply(result00).scalarMultiply(-1); - - final RealMatrix result = new Array2DRowRealMatrix(n, n); - result.setSubMatrix(result00.getData(), 0, 0); - result.setSubMatrix(result01.getData(), 0, splitIndex1); - result.setSubMatrix(result10.getData(), splitIndex1, 0); - result.setSubMatrix(result11.getData(), splitIndex1, splitIndex1); - - return result; - } - - /** - * Computes the inverse of the given matrix. - *

- * By default, the inverse of the matrix is computed using the QR-decomposition, - * unless a more efficient method can be determined for the input matrix. - *

- * Note: this method will use a singularity threshold of 0, - * use {@link #inverse(RealMatrix, double)} if a different threshold is needed. - * - * @param matrix Matrix whose inverse shall be computed - * @return the inverse of {@code matrix} - * @throws NullArgumentException if {@code matrix} is {@code null} - * @throws SingularMatrixException if m is singular - * @throws NonSquareMatrixException if matrix is not square - * @since 3.3 - */ - public static RealMatrix inverse(RealMatrix matrix) - throws NullArgumentException, SingularMatrixException, NonSquareMatrixException { - return inverse(matrix, 0); - } - - /** - * Computes the inverse of the given matrix. - *

- * By default, the inverse of the matrix is computed using the QR-decomposition, - * unless a more efficient method can be determined for the input matrix. - * - * @param matrix Matrix whose inverse shall be computed - * @param threshold Singularity threshold - * @return the inverse of {@code m} - * @throws NullArgumentException if {@code matrix} is {@code null} - * @throws SingularMatrixException if matrix is singular - * @throws NonSquareMatrixException if matrix is not square - * @since 3.3 - */ - public static RealMatrix inverse(RealMatrix matrix, double threshold) - throws NullArgumentException, SingularMatrixException, NonSquareMatrixException { - - MathUtils.checkNotNull(matrix); - - if (!matrix.isSquare()) { - throw new NonSquareMatrixException(matrix.getRowDimension(), - matrix.getColumnDimension()); - } - - if (matrix instanceof DiagonalMatrix) { - return ((DiagonalMatrix) matrix).inverse(threshold); - } else { - QRDecomposition decomposition = new QRDecomposition(matrix, threshold); - return decomposition.getSolver().getInverse(); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteMatrixException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteMatrixException.java b/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteMatrixException.java deleted file mode 100644 index a0fbf17..0000000 --- a/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteMatrixException.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.NumberIsTooSmallException; -import org.apache.commons.math3.exception.util.LocalizedFormats; -import org.apache.commons.math3.exception.util.ExceptionContext; - -/** - * Exception to be thrown when a positive definite matrix is expected. - * - * @since 3.0 - */ -public class NonPositiveDefiniteMatrixException extends NumberIsTooSmallException { - /** Serializable version Id. */ - private static final long serialVersionUID = 1641613838113738061L; - /** Index (diagonal element). */ - private final int index; - /** Threshold. */ - private final double threshold; - - /** - * Construct an exception. - * - * @param wrong Value that fails the positivity check. - * @param index Row (and column) index. - * @param threshold Absolute positivity threshold. - */ - public NonPositiveDefiniteMatrixException(double wrong, - int index, - double threshold) { - super(wrong, threshold, false); - this.index = index; - this.threshold = threshold; - - final ExceptionContext context = getContext(); - context.addMessage(LocalizedFormats.NOT_POSITIVE_DEFINITE_MATRIX); - context.addMessage(LocalizedFormats.ARRAY_ELEMENT, wrong, index); - } - - /** - * @return the row index. - */ - public int getRow() { - return index; - } - /** - * @return the column index. - */ - public int getColumn() { - return index; - } - /** - * @return the absolute positivity threshold. - */ - public double getThreshold() { - return threshold; - } -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7b4803f/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteOperatorException.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteOperatorException.java b/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteOperatorException.java deleted file mode 100644 index f322218..0000000 --- a/src/main/java/org/apache/commons/math3/linear/NonPositiveDefiniteOperatorException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.MathIllegalArgumentException; -import org.apache.commons.math3.exception.util.LocalizedFormats; - -/** - * Exception to be thrown when a symmetric, definite positive - * {@link RealLinearOperator} is expected. - * Since the coefficients of the matrix are not accessible, the most - * general definition is used to check that {@code A} is not positive - * definite, i.e. there exists {@code x} such that {@code x' A x <= 0}. - * In the terminology of this exception, {@code A} is the "offending" - * linear operator and {@code x} the "offending" vector. - * - * @since 3.0 - */ -public class NonPositiveDefiniteOperatorException - extends MathIllegalArgumentException { - /** Serializable version Id. */ - private static final long serialVersionUID = 917034489420549847L; - - /** Creates a new instance of this class. */ - public NonPositiveDefiniteOperatorException() { - super(LocalizedFormats.NON_POSITIVE_DEFINITE_OPERATOR); - } -}