gov.sandia.cognition.math.matrix.decomposition.AbstractSingularValueDecomposition Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cognitive-foundry Show documentation
Show all versions of cognitive-foundry Show documentation
A single jar with all the Cognitive Foundry components.
/*
* File: AbstractSingularValueDecomposition.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright February 21, 2006, Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
* or on behalf of the U.S. Government. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*
*/
package gov.sandia.cognition.math.matrix.decomposition;
import gov.sandia.cognition.annotation.CodeReview;
import gov.sandia.cognition.math.matrix.Matrix;
/**
* Abstract container class that stores the matrices for a Singular Value
* Decomposition (SVD) and related operations but does not actually perform
* a singular value decomposition
*
* @author Kevin R. Dixon
* @since 1.0
*
*/
@CodeReview(
reviewer="Jonathan McClain",
date="2006-05-16",
changesNeeded=false,
comments={
"Made very minor changes.",
"Otherwise, looks fine."
}
)
public abstract class AbstractSingularValueDecomposition
extends java.lang.Object
implements SingularValueDecomposition
{
/** Matrix that has the left singular vectors */
private Matrix U;
/** Diagonal matrix of singular values */
private Matrix S;
/** Transpose of the matrix containing the right singular vectors */
private Matrix Vtranspose;
/**
* Default constructor that nulls out all matrices
*/
public AbstractSingularValueDecomposition()
{
this( null, null, null );
}
/**
* Creates a new instance of AbstractSingularValueDecomposition where
* U*S*Vtranspose = original_matrix
*
* @param U
* orthonormal matrix of left singular vectors
* @param S
* PSD diagonal matrix of singular values, sorted in descending order
* @param Vtranspose
* transpose of the orthonormal matrix of the right singular vectors
*/
public AbstractSingularValueDecomposition(
Matrix U,
Matrix S,
Matrix Vtranspose )
{
this.setU( U );
this.setS( S );
this.setVtranspose( Vtranspose );
}
public Matrix getU()
{
return this.U;
}
/**
* setter for left singular vectors
* @param U left singular vectors
*/
protected void setU( Matrix U )
{
this.U = U;
}
public Matrix getS()
{
return this.S;
}
/**
* setter for the singular values matrix
* @param S singular values matrix
*/
protected void setS(
Matrix S )
{
this.S = S;
}
public Matrix getVtranspose()
{
return this.Vtranspose;
}
/**
* sets the transpose of the right singular vectors matrix
* @param Vtranspose transpose of the right singular vectors matrix
*/
protected void setVtranspose(
Matrix Vtranspose )
{
this.Vtranspose = Vtranspose;
}
public double norm2()
{
double maxSV = this.getS().getElement( 0, 0 );
return maxSV;
}
public double conditionNumber()
{
int N = this.getS().getNumRows();
double maxSV = this.getS().getElement( 0, 0 );
double minSV = this.getS().getElement( N - 1, N - 1 );
double conditionNumber;
if (minSV > 0.0)
{
conditionNumber = maxSV / minSV;
}
else
{
conditionNumber = Double.POSITIVE_INFINITY;
}
return conditionNumber;
}
public int rank()
{
return this.effectiveRank( 0.0 );
}
public int effectiveRank(
double effectiveZero )
{
int n, N = Math.min(this.getS().getNumRows(), this.getS().getNumColumns());
for (n = 0; n < N; n++)
{
if (this.getS().getElement( n, n ) <= effectiveZero)
{
break;
}
}
return n;
}
public Matrix pseudoInverse()
{
return this.pseudoInverse( 0.0 );
}
public Matrix pseudoInverse(
double effectiveZero )
{
Matrix V = this.getVtranspose().transpose();
Matrix Utranspose = this.getU().transpose();
Matrix Spinv = this.getS().transpose();
int N = Math.min( Spinv.getNumRows(), Spinv.getNumColumns() );
for (int i = 0; i < N; i++)
{
double singularValue = Spinv.getElement( i, i );
double svinv;
if (singularValue <= effectiveZero)
{
svinv = 0.0;
}
else
{
svinv = 1.0 / singularValue;
}
Spinv.setElement( i, i, svinv );
}
return V.times( Spinv ).times( Utranspose );
}
}