CEBL  2.1
MNF.cpp
Go to the documentation of this file.
1 //local includes
2 #include "MNF.hpp"
3 
4 //std includes
5 #include <iostream>
6 
7 //namespaces
8 using namespace cppR;
9 using namespace ublas;
10 using namespace std;
11 
12 
13 namespace CEBL
14 {
15  void MNF::mnf(const ublas::matrix<double> & data)
16  {
17  matrix<double> X = data;
18 
19  int nSamples = ncol(X);
20  X -= createMatrix(rep(rowMeans(X), nSamples), 0, nSamples);
21 
22  //R code: X %*% t(X)
23  matrix<double> covX = prod(X, t(X));
24 
25  //first in pair is eigenvalues, second is eigenvectors
26  //R code: eigen(covX)
27  EigStruct<double> r = eigen(covX);
28 
29  //eigenvectors
30  //R code: r$vectors
31  matrix<double> Vx = r.vectors;
32 
33  //sqrt of eigenvalues
34  ublas::vector<double> DSx = vsqrt(r.values);
35  matrix<double> INVDSx = diag(1.0/DSx);
36 
37  //R code: matrix(0, nrow(X), nSamples)
38  matrix<double> SX = createMatrix(0, nrow(X), nSamples);
39 
40  //R code: SX[,2:nSamples] <- X[,1:(nSamples-1)]
41  submatrix(SX,0,0,1,nSamples-1) = submatrix(X,0,0,0,nSamples-2);
42 
43 
44  //SX[,1] <- X[,2];
45  column(SX,0) = column(X,1);
46 
47  matrix<double> Z1 = prod(SX, t(X));
48 
49  matrix<double> Z2 = prod(X, t(SX));
50 
51  //double s1 = frobeniusNorm(static_cast<matrix<double> >(X-SX)) / frobeniusNorm(X);
52 
53  //get singular value decomposition of Z2
54  SvdStruct<double> svd_value = svd(Z2);
55 
56  //s2 is max of the singular values of Z2
57  //double s2 = max(svd_value.d);
58 
59  matrix<double> Z3 = covX;
60 
61 
62  matrix<double> Z4 = prod(SX, t(SX));
63 
64 
65  matrix<double> Z = (Z3+Z4-Z1-Z2) * 0.5;
66 
67  //this part is a little ugly
68  //R code: ZHAT <- INVDSx %*% t(Vx) %*% Z %*% Vx %*% INVDSx
69  matrix<double> p1,p2,p3;
70  p1 = prod(Vx, INVDSx);
71  p2 = prod(Z, p1);
72  p3 = prod(t(Vx),p2);
73  matrix<double> ZHAT = prod(INVDSx, p3);
74  //-----------
75 
76  r = eigen(ZHAT);
77  matrix<double> PSIHAT = r.vectors;
78 
79  psi = prod(p1, PSIHAT);
80  phi = prod(t(X), psi);
81 
82  phi = t(phi);
83  psi = t(psi);
84  }
85 
86  /*********************************************************/
87  void MNF::make(const ublas::matrix<double> & data, const std::vector<int> &remove)
88  {
89  matrix<double> X = static_cast<matrix<double> >(data);
90  int n_samples = ncol(X);
91  int n_components = nrow(X);
92  this->means = rowMeans(X);
93 
94  //R Code: Xm <- X - matrix(rep(means,nSamples),ncol=nSamples)
95  matrix<double> Xm = X - createMatrix(rep(means, n_samples),0,n_samples);
96 
97  mnf(Xm);
98 
99  ublas::vector<double> z = rep(1,n_components);
100 
101  //set components of z specified in remove to 0.0
102  for(unsigned int i=0; i < remove.size(); i++)
103  //make sure subscript is within bounds
104  if(unsigned(remove[i]) < z.size())
105  //loop through columns of z
106  //for(int j=0;j<z.size2();j++)
107  //set cell to 0.0
108  z[remove[i]] = 0.0;
109 
110  matrix<double> selector = diag(z);
111 
112  matrix<double> spsi = solve(psi);
113  matrix<double> ppsi_sel = prod(spsi, selector);
114  this->filter = prod(ppsi_sel
115  ,psi);
116  created = true;
117  }
118 
119  //filter data
120  ublas::matrix<double> MNF::apply(const ublas::matrix<double> &data) const
121  {
122 
123  ublas::matrix<double> X = data;
124  int n_samples = ncol(X);
125  matrix<double> X1 = X - createMatrix(rep(means, n_samples),0,n_samples);
126  matrix<double> filtered = prod(filter, X1);
127  ublas::matrix<double> filtered_ret = filtered;
128  return filtered_ret;
129  }
130 
131  ublas::matrix<double> MNF::extract(const ublas::matrix<double> & data)
132  {
133 
134  mnf(data);
135  ublas::matrix<double> m = static_cast<ublas::matrix<double> >(phi * 20);
136  return m;
137  }
138 
139 
140  map<string, SerializedObject> MNF::save() const
141  {
142  map<string, SerializedObject> ret;
143  ret["created"] = serialize(created);
144  ret["psi"] = serialize(psi);
145  ret["phi"] = serialize(phi);
146  ret["filter"] = serialize(filter);
147  ret["means"] = serialize(means);
148 
149  return ret;
150  }
151  void MNF::load(map<string, SerializedObject> objects)
152  {
153  deserialize(objects["created"], created);
154  deserialize(objects["psi"],psi);
155  deserialize(objects["phi"],phi);
156  deserialize(objects["filter"],filter);
157  deserialize(objects["means"],means);
158  }
159 }
160 
161 
162 
163 /*************************************************************/
164 //DYNAMIC LOADING
165 
167 {
168  return new CEBL::MNF;
169 }
170 
171 extern "C" void ObjectDestroy(CEBL::Filter* p)
172 {
173  delete p;
174 }