pls.cpp
Go to the documentation of this file.
1/* *********************
2 * @file pls.cpp
3 *
4 * @author Stefan Ulbrich
5 * @date 2013-2014
6 *
7 * @brief This file contains implementation of the PLS algorithm.
8 * *********************/
9#include <vector>
10
11#include "kbm.h"
12
13namespace memoryx::KBM
14{
15 /*
16 * In case that regression and reconstruction should be separated later,
17 * store the projection parameter in the data structure defined if
18 * the makro is activated. Will come in handy for an incremental version.
19 */
20 //#define SEPARATE_REGRESSION_RECONSTRUCTION
21
22#ifdef SEPARATE_REGRESSION_RECONSTRUCTION
23 struct Projection
24 {
25 Vector p;
26 Vector u;
27 Real q;
28 Projection(Vector p_, Vector u_, Real q_) : p(p_), u(u_), q(q_){};
29 };
30#endif
31
32 Matrix
33 PLS::solve(const Matrix& input, const Matrix output, Real threshold)
34 {
35
36#ifdef SEPARATE_REGRESSION_RECONSTRUCTION
37 std::vector<std::vector<Projection>> projections;
38#endif
39
40 // Results stored in the following matrix. It has to be initialized with zeros.
41 Matrix parameters = Matrix::Zero(output.rows(), input.rows());
42
43 // PLS 1 optimizes all output dimensions separately
44 for (int d = 0; d < output.rows(); d++)
45 {
46
47#ifdef SEPARATE_REGRESSION_RECONSTRUCTION
48 projections.push_back(std::vector<Projection>());
49#endif
50 // Make working copies
51 Matrix input_d = input;
52 Vector output_d = output.row(d);
53
54 // In order to reconstruct the parameters, the identity matrix is transformed according to
55 // projections defined during the regression.
56 Matrix identity = Matrix::Identity(input.rows(), input.rows());
57
58 for (int k = 0; k < input.rows(); k++) // maximal 3^{d_i} projections
59 {
60 // Step 1: Regression
61 Vector u = input_d * output_d;
62 Vector s = input_d.transpose() * u;
63 Real q = s.dot(output_d) / s.dot(s);
64 output_d = output_d - q * s;
65 Real mean_error = output_d.array().abs().mean();
66 Vector p = (input_d * s) / (s.dot(s));
67 // input_d' = input_d - p * s % minimal
68 input_d = input_d - p * s.transpose();
69
70#ifdef SEPARATE_REGRESSION_RECONSTRUCTION
71 projections[d].push_back(Projection(p, u, q));
72#endif
73 // Step 2: Parameter reconstruction (uses u,p,q from first step)
74 // For separation these projection parameters can be stored in a std::vector
75 s = identity.transpose() * u;
76 parameters.row(d) += q * s.transpose();
77 identity -= p * s.transpose();
78
79 // Step 3: Stopping condition
80 if (mean_error < threshold)
81 {
82 break;
83 }
84 } // for (int k)
85 } // for (int d)
86
87 return parameters;
88 }
89
90
91} // namespace memoryx::KBM
Eigen::Matrix< T, 3, 1 > Vector
#define q
Matrix KBM_IMPORT_EXPORT solve(const Matrix &input, const Matrix output, Real threshold)
Solves a linear system of equations using the partial least squares algorithm.
Definition pls.cpp:33
Eigen::MatrixXd Matrix
Definition kbm.h:40
Eigen::VectorXd Vector
Definition kbm.h:41
double Real
Type definition of the underlying Realing point type.
Definition kbm.h:39