the lastest pca lib by Castle

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

Committer:
castlefei
Date:
Mon Nov 25 14:26:29 2019 +0000
Revision:
0:8670ef66c0e3
PCA lib by Castle; ;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
castlefei 0:8670ef66c0e3 1
castlefei 0:8670ef66c0e3 2 #include "pca.h"
castlefei 0:8670ef66c0e3 3 #include <Eigen/Dense.h>
castlefei 0:8670ef66c0e3 4
castlefei 0:8670ef66c0e3 5 using namespace Eigen;
castlefei 0:8670ef66c0e3 6
castlefei 0:8670ef66c0e3 7 /*
castlefei 0:8670ef66c0e3 8 * Normalize the Matrix X
castlefei 0:8670ef66c0e3 9 */
castlefei 0:8670ef66c0e3 10 MatrixXd PCA::featurnormail(MatrixXd &X)
castlefei 0:8670ef66c0e3 11 {
castlefei 0:8670ef66c0e3 12 //I don't know why to use the transpose
castlefei 0:8670ef66c0e3 13 //compute the mean of every dimension
castlefei 0:8670ef66c0e3 14 MatrixXd X1 = X.transpose();
castlefei 0:8670ef66c0e3 15 MatrixXd meanval = X1.colwise().mean();
castlefei 0:8670ef66c0e3 16
castlefei 0:8670ef66c0e3 17 //normalization
castlefei 0:8670ef66c0e3 18 RowVectorXd meanvecRow = meanval;
castlefei 0:8670ef66c0e3 19 X1.rowwise() -= meanvecRow;
castlefei 0:8670ef66c0e3 20
castlefei 0:8670ef66c0e3 21 return X1.transpose();
castlefei 0:8670ef66c0e3 22 }
castlefei 0:8670ef66c0e3 23
castlefei 0:8670ef66c0e3 24 /*
castlefei 0:8670ef66c0e3 25 * Compute the Covariane Matrix of X, put to C
castlefei 0:8670ef66c0e3 26 * C = 1/m * X * X.transpose
castlefei 0:8670ef66c0e3 27 */
castlefei 0:8670ef66c0e3 28 void PCA::ComComputeCov(MatrixXd &X, MatrixXd &C)
castlefei 0:8670ef66c0e3 29 {
castlefei 0:8670ef66c0e3 30
castlefei 0:8670ef66c0e3 31 C = X*X.adjoint();//same as XT*X a
castlefei 0:8670ef66c0e3 32 //translate to array
castlefei 0:8670ef66c0e3 33 C = C.array() / X.cols();
castlefei 0:8670ef66c0e3 34 }
castlefei 0:8670ef66c0e3 35
castlefei 0:8670ef66c0e3 36
castlefei 0:8670ef66c0e3 37 /*
castlefei 0:8670ef66c0e3 38 * Compute the eigenvalue and eigenvector of C
castlefei 0:8670ef66c0e3 39 * val = (first eigenvalue) --smallest --not important
castlefei 0:8670ef66c0e3 40 * .
castlefei 0:8670ef66c0e3 41 * .
castlefei 0:8670ef66c0e3 42 * .
castlefei 0:8670ef66c0e3 43 * (last eigenvalue) --largest -- important
castlefei 0:8670ef66c0e3 44 *
castlefei 0:8670ef66c0e3 45 * vec = (first eigenvector, ... , last eigenvector)
castlefei 0:8670ef66c0e3 46 * not important important
castlefei 0:8670ef66c0e3 47 */
castlefei 0:8670ef66c0e3 48 void PCA::ComputEig(MatrixXd &C, MatrixXd &vec, MatrixXd &val)
castlefei 0:8670ef66c0e3 49 {
castlefei 0:8670ef66c0e3 50 //SelfAdjointEigenSolver will sort the values automatically
castlefei 0:8670ef66c0e3 51 SelfAdjointEigenSolver<MatrixXd> eig(C);
castlefei 0:8670ef66c0e3 52 vec = eig.eigenvectors();
castlefei 0:8670ef66c0e3 53 val = eig.eigenvalues();
castlefei 0:8670ef66c0e3 54 }
castlefei 0:8670ef66c0e3 55
castlefei 0:8670ef66c0e3 56 /* Compute the dimension need to include enough information of raw data.
castlefei 0:8670ef66c0e3 57 * form large index to small index, since the val is sorted from small to large.
castlefei 0:8670ef66c0e3 58 * in some cases, just decide the number of dimension, instead of compute it.
castlefei 0:8670ef66c0e3 59 */
castlefei 0:8670ef66c0e3 60 int PCA::ComputDim(MatrixXd &val)
castlefei 0:8670ef66c0e3 61 {
castlefei 0:8670ef66c0e3 62 int dim;
castlefei 0:8670ef66c0e3 63 double sum = 0;
castlefei 0:8670ef66c0e3 64 for (int i = val.rows() - 1; i >= 0;--i)
castlefei 0:8670ef66c0e3 65 {
castlefei 0:8670ef66c0e3 66 sum += val(i, 0);
castlefei 0:8670ef66c0e3 67 dim = i;
castlefei 0:8670ef66c0e3 68 if (sum / val.sum()>=0.8)//80% of the information
castlefei 0:8670ef66c0e3 69 break;
castlefei 0:8670ef66c0e3 70 }
castlefei 0:8670ef66c0e3 71 return val.rows() - dim;
castlefei 0:8670ef66c0e3 72 }