/*
* Copyright 2004-2010 Information & Software Engineering Group (188/1)
* Institute of Software Technology and Interactive Systems
* Vienna University of Technology, Austria
*
* Licensed 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.ifs.tuwien.ac.at/dm/somtoolbox/license.html
*
* 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 at.tuwien.ifs.somtoolbox.util;
import org.math.array.DoubleArray;
import org.math.array.StatisticSample;
/**
* Principal Component Analysis
*
* @version $Id: PCA.java 3587 2010-05-21 10:35:33Z mayer $
*/
public class PCA {
double[][] X; // initial datas : lines = events and columns = variables
double[] meanX, stdevX;
double[][] Z; // X centered reduced
double[][] cov; // Z covariance matrix
public double[][] U; // projection matrix
public double[] info; // information matrix
public PCA(double[][] X) {
this.X = X;
stdevX = StatisticSample.stddeviation(X);
meanX = StatisticSample.mean(X);
Z = centerReduce(X);
cov = StatisticSample.covariance(Z);
Jama.EigenvalueDecomposition e = org.math.array.LinearAlgebra.eigen(cov);
U = DoubleArray.transpose(e.getV().getArray());
info = e.getRealEigenvalues(); // covariance matrix is symetric, so only real eigenvalues...
}
// normalization of x relatively to X mean and standard deviation
public double[][] centerReduce(double[][] x) {
double[][] y = new double[x.length][x[0].length];
for (int i = 0; i < y.length; i++) {
for (int j = 0; j < y[i].length; j++) {
y[i][j] = (x[i][j] - meanX[j]) / stdevX[j];
}
}
return y;
}
// de-normalization of y relatively to X mean and standard deviation
public double[] invCenterReduce(double[] y) {
return invCenterReduce(new double[][] { y })[0];
}
// de-normalization of y relatively to X mean and standard deviation
public double[][] invCenterReduce(double[][] y) {
double[][] x = new double[y.length][y[0].length];
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < x[i].length; j++) {
x[i][j] = y[i][j] * stdevX[j] + meanX[j];
}
}
return x;
}
}