net.maizegenetics.stats.PCA.PrinComp Maven / Gradle / Ivy
package net.maizegenetics.stats.PCA;
import net.maizegenetics.matrixalgebra.Matrix.DoubleMatrix;
import net.maizegenetics.matrixalgebra.Matrix.DoubleMatrixFactory;
import net.maizegenetics.matrixalgebra.decomposition.SingularValueDecomposition;
public class PrinComp {
public enum PC_TYPE {corr, cov};
SingularValueDecomposition svd;
DoubleMatrix datamatrix;
/**
* The class uses singular value decomposition to find the eigenvalues, eigenvectors and principal components of either the covariance or correlation matrix
* of the data. If covariance, then the result is the equivalent of finding the eighvalue decomposition of XX'/(n-1) where X is the data matrix with the
* column means subtracted from the columns. If correlation, the column values are also scaled.
* That is, after the mean is subtracted, the values are divided by the standard deviation.
* @param data a matrix of data
* @param type should the analysis use the covariance (cov) or the correlation (corr) matrix of the data
*/
public PrinComp(DoubleMatrix data, PC_TYPE type) {
datamatrix = data;
datamatrix = centerCols(data);
if (type == PC_TYPE.corr) scaleCenteredMatrix(datamatrix);
double multiplier = 1.0 / Math.sqrt(datamatrix.numberOfRows() - 1);
svd = datamatrix.scalarMult(multiplier).getSingularValueDecomposition();
}
/**
* @return a double[] of eigenvalues from the decomposition of either the covariance or correlation matrix of the data
*/
public double[] getEigenValues() {
double[] singularvals = svd.getSingularValues();
int n = singularvals.length;
double[] eigenvals = new double[n];
for (int i = 0; i < n; i++) eigenvals[i] = singularvals[i] * singularvals[i];
return eigenvals;
}
/**
* @return a column vector of eigenvalues from the decomposition of either the covariance or correlation matrix of the data
*/
public DoubleMatrix getEigenValuesAsColumnVector() {
double[] eigenvals = getEigenValues();
int n = eigenvals.length;
return DoubleMatrixFactory.DEFAULT.make(n, 1, eigenvals);
}
/**
* @return a square matrix with diagonal equal to the eigenvalues of the covariance or correlation matrix of the data
*/
public DoubleMatrix getEigenvalueMatrix() {
return DoubleMatrixFactory.DEFAULT.diagonal(getEigenValues());
}
/**
* @return the eigenvectors from the decomposition of either the covariance or correlation matrix of the data
*/
public DoubleMatrix getEigenVectors() {
return svd.getV(false);
}
/**
* calculated as data * eigenvectors
* @return all of the principal components
*/
public DoubleMatrix getPrincipalComponents() {
return datamatrix.mult(svd.getV(false));
}
private DoubleMatrix centerCols(DoubleMatrix data) {
int nrows = data.numberOfRows();
int ncols = data.numberOfColumns();
DoubleMatrix dm = data.copy();
for (int c = 0; c < ncols; c++) {
double colmean = dm.columnSum(c) / nrows;
for (int r = 0; r < nrows; r++) {
dm.set(r, c, dm.get(r, c) - colmean);
}
}
return dm;
}
private void scaleCenteredMatrix(DoubleMatrix data) {
int nrows = data.numberOfRows();
int ncols = data.numberOfColumns();
for (int c = 0; c < ncols; c++) {
double sumsq = 0;
for (int r = 0; r < nrows; r++) {
double val = data.get(r, c);
sumsq += val * val;
}
double stdDev = Math.sqrt(sumsq/(nrows - 1));
for (int r = 0; r < nrows; r++) {
double val = data.get(r, c);
data.set(r, c, val/stdDev);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy