diff --git a/src/java/org/apache/commons/math/linear/DecompositionSolver.java b/src/java/org/apache/commons/math/linear/DecompositionSolver.java index 8295160f6..d8c249524 100644 --- a/src/java/org/apache/commons/math/linear/DecompositionSolver.java +++ b/src/java/org/apache/commons/math/linear/DecompositionSolver.java @@ -22,10 +22,11 @@ import java.io.Serializable; /** * A base interface to decomposition algorithms that can solve A × X = B. * <p>This interface is the common base of decomposition algorithms like - * {@link QRDecomposition}, {@link LUDecomposition} or {@link - * SingularValueDecomposition}. All these algorithms decompose an A matrix has a - * product of several specific matrices from which they can solve A × X = B - * in least squares sense: they find X such that ||A × X - B|| is minimal.</p> + * {@link QRDecomposition}, {@link LUDecomposition}, {@link + * SingularValueDecomposition} or {@link EigenDecomposition}. All these + * algorithms decompose an A matrix has a product of several specific matrices + * from which they can solve A × X = B in least squares sense: they find X + * such that ||A × X - B|| is minimal.</p> * <p>Some solvers like {@link LUDecomposition} can only find the solution for * square matrices and when the solution is an exact linear solution, i.e. when * ||A × X - B|| is exactly 0. Other solvers can also find solutions diff --git a/src/java/org/apache/commons/math/linear/EigenDecomposition.java b/src/java/org/apache/commons/math/linear/EigenDecomposition.java new file mode 100644 index 000000000..e2770195e --- /dev/null +++ b/src/java/org/apache/commons/math/linear/EigenDecomposition.java @@ -0,0 +1,90 @@ +/* + * 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.math.linear; + +/** + * An interface to classes that implement an algorithm to calculate the + * eigen decomposition of a real symmetric matrix. + * <p>The eigen decomposition of matrix A is a set of two matrices: + * V and D such that A = V × D × V<sup>T</sup>. + * Let A be an m × n matrix, then V is an m × m orthogonal matrix + * and D is a m × n diagonal matrix.</p> + * <p>This interface is similar in spirit to the <code>EigenvalueDecomposition</code> + * class from the now defunct <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> + * library, with the following changes:</p> + * <ul> + * <li><code>solve</code> methods have been added (in the superinterface),</li> + * <li>a {@link DecompositionSolver#decompose(RealMatrix) decompose(RealMatrix)} + * method has been added (in the superinterface),</li> + * <li>a {@link DecompositionSolver#isNonSingular() isNonSingular} method has + * been added (in the superinterface),</li> + * <li>a {@link DecompositionSolver#getInverse() getInverse} method has been + * added (in the superinterface),</li> + * <li>a {@link #getVt() getVt} method has been added,</li> + * <li>the <code>getRealEigenvalues</code> method has been renamed as {@link + * #getEigenValues() getEigenValues},</li> + * <li>the <code>getImagEigenvalues</code> method has been removed</li> + * </ul> + * @see <a href="http://mathworld.wolfram.com/EigenDecomposition.html">MathWorld</a> + * @see <a href="http://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix">Wikipedia</a> + * @version $Revision$ $Date$ + * @since 2.0 + */ +public interface EigenDecomposition extends DecompositionSolver { + + /** + * Returns the matrix V of the decomposition. + * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p> + * <p>The columns of V are the eigenvectors of the original matrix.</p> + * @return the V matrix + * @exception IllegalStateException if {@link + * DecompositionSolver#decompose(RealMatrix) decompose} has not been called + */ + RealMatrix getV() throws IllegalStateException; + + /** + * Returns the diagonal matrix D of the decomposition. + * <p>D is a diagonal matrix.</p> + * <p>The values on the diagonal are the eigenvalues of the original matrix.</p> + * @return the D matrix + * @exception IllegalStateException if {@link + * DecompositionSolver#decompose(RealMatrix) decompose} has not been called + * @see #getEigenValues() + */ + RealMatrix getD() throws IllegalStateException; + + /** + * Returns the transpose of the matrix V of the decomposition. + * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p> + * <p>The columns of V are the eigenvectors of the original matrix.</p> + * @return the transpose of the V matrix + * @exception IllegalStateException if {@link + * DecompositionSolver#decompose(RealMatrix) decompose} has not been called + */ + RealMatrix getVt() throws IllegalStateException; + + /** + * Returns the eigenvalues of the original matrix. + * @return eigenvalues of the original matrix + * @exception IllegalStateException if {@link + * DecompositionSolver#decompose(RealMatrix) decompose} has not been called + * @see #getD() + */ + double[] getEigenValues() throws IllegalStateException; + +} diff --git a/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java b/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java new file mode 100644 index 000000000..e7b7db7f6 --- /dev/null +++ b/src/java/org/apache/commons/math/linear/SingularValueDecomposition.java @@ -0,0 +1,140 @@ +/* + * 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.math.linear; + +import org.apache.commons.math.ConvergenceException; + +/** + * An interface to classes that implement an algorithm to calculate the + * Singular Value Decomposition of a real matrix. + * <p>The Singular Value Decomposition of matrix A is a set of three matrices: + * U, Σ and V such that A = U × Σ × V<sup>T</sup>. + * Let A be an m × n matrix, then U is an m × m orthogonal matrix, + * Σ is a m × n diagonal matrix with positive diagonal elements, + * and V is an n × n orthogonal matrix.</p> + * <p>This interface is similar to the class with similar name from the now defunct + * <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a> library, with the + * following changes:</p> + * <ul> + * <li><code>solve</code> methods have been added (in the superinterface),</li> + * <li>a {@link DecompositionSolver#decompose(RealMatrix) decompose(RealMatrix)} + * method has been added (in the superinterface),</li> + * <li>a {@link #decompose(RealMatrix, int) decompose(RealMatrix), int)} method + * has been added,</li> + * <li>a {@link DecompositionSolver#isNonSingular() isNonSingular} method has + * been added (in the superinterface),</li> + * <li>a {@link DecompositionSolver#getInverse() getInverse} method has been + * added (in the superinterface),</li> + * <li>the <code>norm2</code> method which has been renamed as {@link #getNorm() + * getNorm},</li> + * <li>the <code>cond</code> method which has been renamed as {@link + * #getConditionNumber() getConditionNumber},</li> + * <li>the <code>rank</code> method which has been renamed as {@link #getRank() + * getRank}</li> + * </ul> + * @see <a href="http://mathworld.wolfram.com/SingularValueDecomposition.html">MathWorld</a> + * @see <a href="http://en.wikipedia.org/wiki/Singular_value_decomposition">Wikipedia</a> + * @version $Revision$ $Date$ + * @since 2.0 + */ +public interface SingularValueDecomposition extends DecompositionSolver { + + /** + * Decompose a matrix to find its largest singular values. + * @param matrix + * @param maxSingularValues maximal number of singular values to compute + * @exception InvalidMatrixException (wrapping a {@link ConvergenceException} + * if algorithm fails to converge + */ + void decompose(RealMatrix matrix, int maxSingularValues) + throws InvalidMatrixException; + + /** + * Returns the matrix U of the decomposition. + * <p>U is an orthogonal matrix, i.e. its transpose is also its inverse.</p> + * @return the U matrix + * @exception IllegalStateException if neither {@link + * DecompositionSolver#decompose(RealMatrix) decompose} nor {@link + * #decompose(RealMatrix, int)} have not been called + */ + RealMatrix getU() throws IllegalStateException; + + /** + * Returns the diagonal matrix Σ of the decomposition. + * <p>Σ is a diagonal matrix.</p> + * @return the Σ matrix + * @exception IllegalStateException if neither {@link + * DecompositionSolver#decompose(RealMatrix) decompose} nor {@link + * #decompose(RealMatrix, int)} have not been called + */ + RealMatrix getS() throws IllegalStateException; + + /** + * Returns the diagonal elements of the matrix Σ of the decomposition. + * @return the diagonal elements of the Σ matrix + * @exception IllegalStateException if neither {@link + * DecompositionSolver#decompose(RealMatrix) decompose} nor {@link + * #decompose(RealMatrix, int)} have not been called + */ + double[] getSingularValues() throws IllegalStateException; + + /** + * Returns the matrix V of the decomposition. + * <p>V is an orthogonal matrix, i.e. its transpose is also its inverse.</p> + * @return the V matrix (or null if decomposed matrix is singular) + * @exception IllegalStateException if neither {@link + * DecompositionSolver#decompose(RealMatrix) decompose} nor {@link + * #decompose(RealMatrix, int)} have not been called + */ + RealMatrix getV() throws IllegalStateException; + + /** + * Returns the L<sub>2</sub> norm of the matrix. + * <p>The L<sub>2</sub> norm is max(|A × u|<sub>2</sub> / + * |u|<sub>2</sub>), where |.|<sub>2</sub> denotes the vectorial 2-norm + * (i.e. the traditional euclidian norm).</p> + * @return norm + * @exception IllegalStateException if neither {@link + * DecompositionSolver#decompose(RealMatrix) decompose} nor {@link + * #decompose(RealMatrix, int)} have not been called + */ + double getNorm() throws IllegalStateException; + + /** + * Return the condition number of the matrix. + * @return condition number of the matrix + * @exception IllegalStateException if neither {@link + * DecompositionSolver#decompose(RealMatrix) decompose} nor {@link + * #decompose(RealMatrix, int)} have not been called + */ + double getConditionNumber() throws IllegalStateException; + + /** + * Return the effective numerical matrix rank. + * <p>The effective numerical rank is the number of non-negligible + * singular values. The threshold used to identify non-negligible + * terms is max(m,n) × ulp(s<sub>1</sub>) where ulp(s<sub>1</sub>) + * is the least significant bit of the largest singular value.</p> + * @return effective numerical matrix rank + * @exception IllegalStateException if neither {@link + * DecompositionSolver#decompose(RealMatrix) decompose} nor {@link + * #decompose(RealMatrix, int)} have not been called + */ + int getRank() throws IllegalStateException; + +}