CEBL  2.1
WindowedSVD.cpp
Go to the documentation of this file.
1 #include "WindowedSVD.hpp"
2 
3 using namespace cppR;
4 
5 typedef ublas::matrix<double> Matrix;
6 
7 namespace CEBL
8 {
9  //default constructor
10  WindowedSVD::WindowedSVD()
11  {
12  n_lags = 0;
13  window_size = 64;
14  window_overlap = 32;
15  raw_buffer.resize(0,0);
16  plugin_name = "Windowed SVD";
17  }
18 
19  std::map<std::string, CEBL::Param> WindowedSVD::getParamsList()
20  {
21  std::map<std::string, CEBL::Param> params;
22  CEBL::Param lags("Lags", "How many lags?", n_lags);
23  CEBL::Param wsize("Window Size", "How many samples per window?", window_size);
24  CEBL::Param wover("Window Overlap", "How many samples do windows overlap??", window_overlap);
25  lags.setMax(500);
26  lags.setMin(0);
27 
28  wsize.setMax(9999999);
29  wsize.setMin(1);
30 
31  wover.setMax(9999999);
32  wover.setMin(0);
33 
34  params["lags"] = lags;
35  params["wsize"] = wsize;
36  params["wover"] = wover;
37 
38  return params;
39  }
40  void WindowedSVD::setParamsList( std::map<std::string, CEBL::Param> &p)
41  {
42  int new_lags = p["lags"].getInt();
43  int new_ws = p["wsize"].getInt();
44  int new_wo = p["wover"].getInt();
45 
46  if(new_lags != n_lags || new_ws != window_size || new_wo != window_overlap)
47  {
48  n_lags = new_lags;
49  window_size = new_ws;
50  window_overlap = new_wo;
51  reset();
52  }
53  }
54 
55 
57  ublas::matrix<double> WindowedSVD::use(const ublas::matrix<double> &data)
58  {
59  // make sure the new data coming in matches the buffer
60  if(nrow(raw_buffer) > 0 && nrow(raw_buffer)!=nrow(data))
61  reset();
62  // make sure parameters will work with the data passed in
63  if(nrow(data)*(n_lags+1) > window_size)
64  throw("Window size must be larger than the number of features * (lags+1).");
65 
66  bool debug = false;
67  if(debug)
68  {
69  cout << "\n\n\nReceived " << ncol(data) << " new samples.\n";
70  cout << "Already have " << ncol(raw_buffer) << " buffered samples\n";
71  //cout << "And " << ncol(lagged_buffer) << " left over lagged samples\n";
72  }
73 
74  if(ncol(raw_buffer)==0) {
75  raw_buffer = data;
76  } else {
77  raw_buffer = cbind(raw_buffer, data);
78  }
79 
80  Matrix lagged_data;
81  int nColsBuffer = ncol(raw_buffer);
82  int window_shift = window_size - window_overlap;
83 
84  lagged_data = cppR::Lag(raw_buffer,n_lags);
85 
86  int num_windows = int((ncol(lagged_data)-window_size)/window_shift);
87  if (num_windows < 0)
88  num_windows = 0;
89  // num_raw_samples_left used later to shrink raw_buffer to just unused samples, for next time
90  int num_lagged_samples_left = ncol(lagged_data) - (num_windows-1) * window_shift - (num_windows>0 ? window_size : 0);
91  int num_raw_samples_left = num_lagged_samples_left + n_lags;
92 
93  Matrix svdized;
94  svdized.resize(0,0);
95 
96  if(debug)
97  {
98  cout << "After lagging there are " << ncol(raw_buffer) << " buffered samples\n";
99  cout << "And " << ncol(lagged_data) << " samples of lagged data\n";
100  cout << "From this, we can create " << num_windows << " windows of " << window_size
101  << " samples shifted by " << window_shift << endl;
102  }
103 
104  if(num_windows == 0)
105  {
106  Matrix t;
107  t.resize(0,0);
108  return(t);
109  }
110 
111  for(int w=0; w < num_windows; w++)
112  {
113  this->inturruptionPoint();
114 
115  // window is all rows of lagged_data and window_size cols
116  Matrix window = submatrix(lagged_data, 0, 0,
117  w * window_shift, w * window_shift + window_size -1);
118 
119  SvdStruct<double> sv = svd(window);
120 
121  if (debug) {
122  cout << "sv: ";
123  for (unsigned int i = 0; i < sv.d.size(); i++)
124  cout << sv.d[i] << " ";
125  cout << endl;
126 
127  cout << "size of u " << nrow(sv.u) << "x" << ncol(sv.u) << endl;
128  cout << "size of d " << sv.d.size() << endl;
129  cout << "size of v " << nrow(sv.v) << "x" << ncol(sv.v) << endl;
130  }
131 
132  Matrix singular_vectors = submatrix(sv.u, 0,0,0,nrow(window)-1);
133 
134  Matrix temp;
135  temp.resize(0,1);
136  for(int i=0;i<ncol(singular_vectors);i++)
137  {
138  this->inturruptionPoint();
139  Matrix col = createMatrix(ublas::vector<double>(column(singular_vectors,i)),nrow(singular_vectors),1);
140  temp = rbind(temp,Matrix(col));
141  }
142  if(ncol(svdized)!=0)
143  svdized = cbind(svdized, temp);
144  else
145  svdized = temp;
146  }
147 
148  // Set raw buffer to whatever is left
149  raw_buffer = submatrix(raw_buffer, 0,0, nColsBuffer - num_raw_samples_left - 1, nColsBuffer-1);
150 
151  return(svdized);
152  }
153 
154  map<string, SerializedObject> WindowedSVD::save() const
155  {
156  map<string, SerializedObject> ret;
157  ret["n_lags"] = serialize(n_lags);
158  ret["window_size"] = serialize(window_size);
159  ret["window_overlap"] = serialize(window_overlap);
160 
161  return ret;
162  }
163  void WindowedSVD::load(map<string, SerializedObject> objects)
164  {
165  deserialize(objects["n_lags"],n_lags);
166  deserialize(objects["window_size"],window_size);
167  deserialize(objects["window_overlap"],window_overlap);
168  }
169 
171  void WindowedSVD::reset()
172  {
173  raw_buffer.resize(0,0);
174  }
175 
176 }
177 
178 /*************************************************************/
179 //DYNAMIC LOADING
180 
182 {
183  return new CEBL::WindowedSVD;
184 }
185 
186 extern "C" void ObjectDestroy(CEBL::Feature* p)
187 {
188  delete p;
189 }