-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathpcacalculator.h
77 lines (67 loc) · 2.77 KB
/
pcacalculator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#ifndef PCACALCULATOR_H
#define PCACALCULATOR_H
#include <Eigen/Core>
#include <Eigen/SVD>
#include <Eigen/Eigenvalues>
template <size_t DIMENSION>
class PCACalculator
{
public:
enum Method
{
SLOW = 0,
FAST = 1
};
static void calculate(const Eigen::Matrix<float, DIMENSION, -1> &matrix,
Eigen::Matrix<float, DIMENSION, 1> &mean,
Eigen::Matrix<float, DIMENSION, DIMENSION> &eigenVectors,
Eigen::Matrix<float, DIMENSION, 1> &eigenValues,
Method method = SLOW)
{
mean = matrix.rowwise().mean();
Eigen::Matrix<float, -1, DIMENSION> meanCentered = (matrix.colwise() - mean).transpose();
if (method == SLOW)
{
Eigen::JacobiSVD<Eigen::Matrix<float, -1, DIMENSION> > svd(meanCentered, Eigen::ComputeFullV);
Eigen::Matrix<float, DIMENSION, DIMENSION> v = svd.matrixV();
Eigen::Matrix<float, DIMENSION, 1> s = svd.singularValues();
eigenVectors = v;
eigenValues = s;
}
else
{
Eigen::SelfAdjointEigenSolver<Eigen::Matrix<float, -1, DIMENSION> > solver(meanCentered, Eigen::ComputeFullV);
Eigen::Matrix<float, DIMENSION, DIMENSION> v = solver.eigenvectors();
Eigen::Matrix<float, DIMENSION, 1> s = solver.eigenvalues();
eigenVectors = v;//.rowwise().reverse();
eigenValues = s;//.colwise().reverse();
}
}
static void calculate(const Eigen::Matrix<float, DIMENSION, -1> &matrix,
Eigen::Matrix<float, DIMENSION, DIMENSION> &eigenVectors,
Eigen::Matrix<float, DIMENSION, 1> &eigenValues,
Method method = SLOW)
{
Eigen::Matrix<float, DIMENSION, 1> mean;
calculate(matrix, mean, eigenVectors, eigenValues, method);
}
static void calculate(const Eigen::Matrix<float, DIMENSION, -1> &matrix,
Eigen::Matrix<float, DIMENSION, 1> &eigenValues,
Method method = SLOW)
{
Eigen::Matrix<float, DIMENSION, 1> mean;
Eigen::Matrix<float, DIMENSION, DIMENSION> eigenVectors;
calculate(matrix, mean, eigenVectors, eigenValues, method);
}
static void calculate(const Eigen::Matrix<float, DIMENSION, -1> &matrix,
Eigen::Matrix<float, DIMENSION, DIMENSION> &eigenVectors,
Method method = SLOW)
{
Eigen::Matrix<float, DIMENSION, 1> mean;
Eigen::Matrix<float, DIMENSION, 1> eigenValues;
calculate(matrix, mean, eigenVectors, eigenValues, method);
}
};
template class PCACalculator<3>;
typedef PCACalculator<3> PCACalculator3d;
#endif // PCACALCULATOR_H