-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathPLSduino.cpp~
More file actions
126 lines (110 loc) · 2.5 KB
/
Copy pathPLSduino.cpp~
File metadata and controls
126 lines (110 loc) · 2.5 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
PLS.cpp - Library for Partial least squares
created by Jamal Makkor public@makkor.de
Released into the public domain.
*/
#include "Arduino.h"
#include "PLSduino.h"
#include <ArduinoEigenDense.h>
using Eigen::MatrixXf;
using Eigen::VectorXf;
PLS::PLS( )
{
Serial.begin(9600); // Initialize serial communication
}
PLS::PLS(int brate)
{
Serial.begin(brate); // Initialize serial communication
}
PLS::PLS(
const MatrixXf &B,
const MatrixXf &meanX,
const MatrixXf &meanY ) : B(B), mean0X(meanX), mean0Y(meanY)
{
// nothing to do
}
PLS::~PLS()
{
//Default destructor
}
void PLS::train(
const MatrixXf &Xdata,
const MatrixXf &Ydata,
float epsilon )
{
if (Xdata.rows() != Ydata.rows()){
Serial.println("X and Y dimentionality does not match");
return;
}
MatrixXf X, Y;
X = Xdata;
mean0X = X.colwise().mean();
Y = Ydata;
mean0Y = Y.colwise().mean();
for (int i = 0; i < X.rows(); ++i)
X.row(i) = X.row(i) - mean0X;
for (int i = 0; i < Y.rows(); ++i)
Y.row(i) = Y.row(i) - mean0Y;
MatrixXf T, U, W, C, P, Q, Bdiag;
VectorXf t, w, u_old,e, c, p, q, b;
VectorXf u = VectorXf::Random(X.rows());
while (1)
{
while (1)
{
//maximizing infomation content in from X and Y
w = X.transpose() * u;
w = w / w.norm();
t = X * w; // latent vector in X
t = t / t.norm();
c = Y.transpose() * t;
c = c / c.norm();
u_old = u;
u = Y * c; // latent vector in Y
e = u- u_old; // try to minimise the error
float error = e.norm();
if (error < epsilon) break;
}
b = t.transpose() * u;
assert(b.cols() == 1 && b.rows() == 1);
if (C.cols() == 0)
C = c;
else
C.conservativeResize(C.rows(), C.cols() + 1);
C.col(C.cols() - 1) = c;
float temp = t.norm();
p = X.transpose() * t / (temp * temp);
if (P.cols() == 0)
P = p;
else
P.conservativeResize(P.rows(), P.cols() + 1);
P.col(P.cols() - 1) = p;
if (Bdiag.cols() == 0)
Bdiag = b;
else
Bdiag.conservativeResize(Bdiag.rows(), Bdiag.cols() + 1);
Bdiag.col(Bdiag.cols() - 1) = b;
X = X - t * p.transpose();
Y = Y - t * c.transpose();
if (X.norm() < 0.001) break;
}
Bdiag = Bdiag.diagonal();
MatrixXf P_t = P.transpose();
B = Eigen::pseudoInverse(P_t);
B = B * Bdiag;
B = B * C.transpose();
}
MatrixXf PLS::predict(
const MatrixXf &v ) const
{
MatrixXf temp;
MatrixXf result = MatrixXf::Zero(v.rows(),B.cols());
temp = v;
for (int i = 0; i < temp.rows(); ++i)
{
temp.row(i) -= mean0X;
result.row(i) = temp.row(i) * B;
result.row(i) += mean0Y;
}
return result;
}