the lastest pca lib by Castle

Dependents:   the-lastest-code mbed-test-i2c-PCA-biquad-peakdet

pca.cpp

Committer:
castlefei
Date:
2019-11-25
Revision:
0:8670ef66c0e3

File content as of revision 0:8670ef66c0e3:


#include "pca.h"
#include <Eigen/Dense.h>

using namespace Eigen;

 /*
  * Normalize the Matrix X
  */
 MatrixXd PCA::featurnormail(MatrixXd &X)
{
    //I don't know why to use the transpose
    //compute the mean of every dimension
    MatrixXd X1 = X.transpose();
    MatrixXd meanval = X1.colwise().mean();
    
    //normalization
    RowVectorXd meanvecRow = meanval;
    X1.rowwise() -= meanvecRow;
    
    return X1.transpose();
}

 /*
  * Compute the Covariane Matrix of X, put to C
  * C = 1/m * X * X.transpose 
  */
void PCA::ComComputeCov(MatrixXd &X, MatrixXd &C)
{
   
    C = X*X.adjoint();//same as XT*X a
    //translate to array
    C = C.array() / X.cols();
}
 
 
/*
 * Compute the eigenvalue and eigenvector of C
 * val = (first eigenvalue) --smallest --not important
 *              .
 *              .
 *              .
 *       (last eigenvalue)  --largest -- important
 *
 * vec = (first eigenvector, ... , last eigenvector)
 *           not important          important
 */
void PCA::ComputEig(MatrixXd &C, MatrixXd &vec, MatrixXd &val)
{
    //SelfAdjointEigenSolver will sort the values automatically
    SelfAdjointEigenSolver<MatrixXd> eig(C);
    vec = eig.eigenvectors();
    val = eig.eigenvalues();
}
 
/* Compute the dimension need to include enough information of raw data.
 * form large index to small index, since the val is sorted from small to large.
 * in some cases, just decide the number of dimension, instead of compute it.
 */
int PCA::ComputDim(MatrixXd &val)
{
    int dim;
    double sum = 0;
    for (int i = val.rows() - 1; i >= 0;--i)
    {
        sum += val(i, 0);
        dim = i;
        if (sum / val.sum()>=0.8)//80% of the information
            break;
    }
    return val.rows() - dim;
}