From 7d5ea6a07469d0ee08b1693ac9a35faa0b4118e2 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Tue, 30 Sep 2008 15:09:17 +0000 Subject: [PATCH] added interfaces for eigen decomposition and for singular value decomposition the implementation for this interfaces is not ready yet, but it seems important to show what the interface will look like. JIRA: MATH-220 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_0@700492 13f79535-47bb-0310-9956-ffa450edef68 --- .../math/linear/DecompositionSolver.java | 9 +- .../math/linear/EigenDecomposition.java | 90 +++++++++++ .../linear/SingularValueDecomposition.java | 140 ++++++++++++++++++ 3 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 src/java/org/apache/commons/math/linear/EigenDecomposition.java create mode 100644 src/java/org/apache/commons/math/linear/SingularValueDecomposition.java 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. *

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.

+ * {@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.

*

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. + *

The eigen decomposition of matrix A is a set of two matrices: + * V and D such that A = V × D × VT. + * Let A be an m × n matrix, then V is an m × m orthogonal matrix + * and D is a m × n diagonal matrix.

+ *

This interface is similar in spirit to the EigenvalueDecomposition + * class from the now defunct JAMA + * library, with the following changes:

+ * + * @see MathWorld + * @see Wikipedia + * @version $Revision$ $Date$ + * @since 2.0 + */ +public interface EigenDecomposition extends DecompositionSolver { + + /** + * Returns the matrix V of the decomposition. + *

V is an orthogonal matrix, i.e. its transpose is also its inverse.

+ *

The columns of V are the eigenvectors of the original matrix.

+ * @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. + *

D is a diagonal matrix.

+ *

The values on the diagonal are the eigenvalues of the original matrix.

+ * @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. + *

V is an orthogonal matrix, i.e. its transpose is also its inverse.

+ *

The columns of V are the eigenvectors of the original matrix.

+ * @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. + *

The Singular Value Decomposition of matrix A is a set of three matrices: + * U, Σ and V such that A = U × Σ × VT. + * 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.

+ *

This interface is similar to the class with similar name from the now defunct + * JAMA library, with the + * following changes:

+ * + * @see MathWorld + * @see Wikipedia + * @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. + *

U is an orthogonal matrix, i.e. its transpose is also its inverse.

+ * @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. + *

Σ is a diagonal matrix.

+ * @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. + *

V is an orthogonal matrix, i.e. its transpose is also its inverse.

+ * @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 L2 norm of the matrix. + *

The L2 norm is max(|A × u|2 / + * |u|2), where |.|2 denotes the vectorial 2-norm + * (i.e. the traditional euclidian norm).

+ * @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. + *

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(s1) where ulp(s1) + * is the least significant bit of the largest singular value.

+ * @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; + +}