SHOGUN  v1.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RandomFourierGaussPreproc.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2010-2011 Alexander Binder
8  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  * Copyright (C) 2010-2011 Berlin Institute of Technology
10  */
11 
13 #include <cmath>
14 
15 using namespace shogun;
16 
18 
21 
24 
27 
29  {
30  if(feats.randomcoeff_additive==NULL)
31  {
32  throw ShogunException(
33  "void CRandomFourierGaussPreproc::copy(...): feats.randomcoeff_additive==NULL && cur_dim_feature_space>0 \n");
34  }
35 
38  }
39  else
40  {
41  randomcoeff_additive = NULL;
42  }
43 
45  {
46  if(feats.randomcoeff_multiplicative==NULL)
47  {
48  throw ShogunException(
49  "void CRandomFourierGaussPreproc::copy(...): feats.randomcoeff_multiplicative==NULL && cur_dim_feature_space>0 &&(cur_dim_input_space>0) \n");
50  }
51 
54  }
55  else
56  {
58  }
59 
60 }
61 
64  dim_feature_space = 1000;
65  dim_input_space = 0;
68 
71 
72  kernelwidth=1;
74 
75  //m_parameter is inherited from CSGObject,
76  //serialization initialization
77  if(m_parameters)
78  {
79  m_parameters->add(&dim_input_space,"dim_input_space");
80  m_parameters->add(&cur_dim_input_space,"cur_dim_input_space");
81  m_parameters->add(&dim_feature_space,"dim_feature_space");
82  m_parameters->add(&kernelwidth,"kernelwidth");
83  m_parameters->add(&cur_kernelwidth,"cur_kernelwidth");
84 
85 
86  m_parameters->add(&cur_dim_feature_space,"cur_dim_feature_space");
89  }
90 
91 }
92 
94  const CRandomFourierGaussPreproc & feats) :
96 
99 
100  //m_parameter is inherited from CSGObject,
101  //serialization initialization
102  if(m_parameters)
103  {
104  m_parameters->add(&dim_input_space,"dim_input_space");
105  m_parameters->add(&cur_dim_input_space,"cur_dim_input_space");
106  m_parameters->add(&dim_feature_space,"dim_feature_space");
107  m_parameters->add(&kernelwidth,"kernelwidth");
108  m_parameters->add(&cur_kernelwidth,"cur_kernelwidth");
109 
110  m_parameters->add(&cur_dim_feature_space,"cur_dim_feature_space");
113  }
114 
115  copy(feats);
116 }
117 
119 
122 
123 }
124 
126  return C_SIMPLE;
127 }
128 
130  return F_DREAL;
131 }
132 
134  return ((int32_t) dim_feature_space);
135 }
136 
138  if (dim <= 0) {
139  throw ShogunException(
140  "void CRandomFourierGaussPreproc::set_dim_feature_space(const int32 dim): dim<=0 is not allowed");
141  }
142 
143  dim_feature_space = dim;
144 
145 }
146 
148  return ((int32_t) dim_input_space);
149 }
150 
152  if (kernelwidth2 <= 0) {
153  throw ShogunException(
154  "void CRandomFourierGaussPreproc::set_kernelwidth(const float64_t kernelwidth2 ): kernelwidth2 <= 0 is not allowed");
155  }
156  kernelwidth=kernelwidth2;
157 }
158 
160  return (kernelwidth);
161 }
162 
164  if (dim <= 0) {
165  throw ShogunException(
166  "void CRandomFourierGaussPreproc::set_dim_input_space(const int32 dim): dim<=0 is not allowed");
167  }
168 
169  dim_input_space = dim;
170 
171 }
172 
174 
176  && (dim_input_space > 0) && (dim_feature_space > 0)) {
178 
179  // already inited
180  return true;
181  } else {
182  return false;
183  }
184  }
185 
186  return false;
187 }
188 
190  if (dim_feature_space <= 0) {
191  throw ShogunException(
192  "bool CRandomFourierGaussPreproc::init_randomcoefficients(): dim_feature_space<=0 is not allowed\n");
193  }
194  if (dim_input_space <= 0) {
195  throw ShogunException(
196  "bool CRandomFourierGaussPreproc::init_randomcoefficients(): dim_input_space<=0 is not allowed\n");
197  }
198 
199  if (test_rfinited()) {
200  return false;
201  }
202 
203 
204  SG_INFO("initializing randomcoefficients \n") ;
205 
206  float64_t pi = 3.14159265;
207 
208 
213 
214 
219 
221 
222  for (int32_t i = 0; i < cur_dim_feature_space; ++i) {
223  randomcoeff_additive[i] = CMath::random((float64_t) 0.0, 2 * pi);
224  }
225 
226  for (int32_t i = 0; i < cur_dim_feature_space; ++i) {
227  for (int32_t k = 0; k < cur_dim_input_space; ++k) {
228  float64_t x1,x2;
229  float64_t s = 2;
230  while ((s >= 1) ) {
231  // Marsaglia polar for gaussian
232  x1 = CMath::random((float64_t) -1.0, (float64_t) 1.0);
233  x2 = CMath::random((float64_t) -1.0, (float64_t) 1.0);
234  s=x1*x1+x2*x2;
235  }
236 
237  // = x1/CMath::sqrt(val)* CMath::sqrt(-2*CMath::log(val));
238  randomcoeff_multiplicative[i*cur_dim_input_space+k] = x1*CMath::sqrt(-2*CMath::log(s)/s )/kernelwidth;
239  }
240  }
241 
242  SG_INFO("finished: initializing randomcoefficients \n") ;
243 
244  return true;
245 }
246 
248  float64_t ** randomcoeff_additive2,
249  float64_t ** randomcoeff_multiplicative2, int32_t *dim_feature_space2,
250  int32_t *dim_input_space2, float64_t* kernelwidth2) const {
251 
252  ASSERT(randomcoeff_additive2);
253  ASSERT(randomcoeff_multiplicative2);
254 
255  if (!test_rfinited()) {
256  *dim_feature_space2 = 0;
257  *dim_input_space2 = 0;
258  *kernelwidth2=1;
259  *randomcoeff_additive2 = NULL;
260  *randomcoeff_multiplicative2 = NULL;
261  return;
262  }
263 
264  *dim_feature_space2 = cur_dim_feature_space;
265  *dim_input_space2 = cur_dim_input_space;
266  *kernelwidth2=cur_kernelwidth;
267 
268  *randomcoeff_additive2 = SG_MALLOC(float64_t, cur_dim_feature_space);
269  *randomcoeff_multiplicative2 = SG_MALLOC(float64_t, cur_dim_feature_space*cur_dim_input_space);
270 
272  *randomcoeff_additive2);
274  *randomcoeff_multiplicative2);
275 
276 
277 }
278 
280  float64_t *randomcoeff_additive2,
281  float64_t * randomcoeff_multiplicative2,
282  const int32_t dim_feature_space2, const int32_t dim_input_space2, const float64_t kernelwidth2) {
283  dim_feature_space = dim_feature_space2;
284  dim_input_space = dim_input_space2;
285  kernelwidth=kernelwidth2;
286 
291 
295 
296  if( (dim_feature_space>0) && (dim_input_space>0) )
297  {
300 
301  std::copy(randomcoeff_additive2, randomcoeff_additive2
303  std::copy(randomcoeff_multiplicative2, randomcoeff_multiplicative2
304  + cur_dim_feature_space*cur_dim_input_space, randomcoeff_multiplicative);
305  }
306 
307 }
308 
309 bool CRandomFourierGaussPreproc::init(CFeatures *f) {
310  if (f->get_feature_class() != get_feature_class()) {
311  throw ShogunException(
312  "CRandomFourierGaussPreproc::init (CFeatures *f) requires CSimpleFeatures<float64_t> as features\n");
313  }
314  if (f->get_feature_type() != get_feature_type()) {
315  throw ShogunException(
316  "CRandomFourierGaussPreproc::init (CFeatures *f) requires CSimpleFeatures<float64_t> as features\n");
317  }
318  if (dim_feature_space <= 0) {
319  throw ShogunException(
320  "CRandomFourierGaussPreproc::init (CFeatures *f): dim_feature_space<=0 is not allowed, use void set_dim_feature_space(const int32 dim) before!\n");
321  }
322 
323  SG_INFO("calling CRandomFourierGaussPreproc::init(...)\n");
324  int32_t num_features =
325  ((CSimpleFeatures<float64_t>*) f)->get_num_features();
326 
327  if (!test_rfinited()) {
328  dim_input_space = num_features;
330  ASSERT( test_rfinited());
331  return true;
332  } else {
333  dim_input_space = num_features;
334  // does not reinit if dimension is the same to avoid overriding a previous call of set_randomcoefficients(...)
335  bool inited = init_randomcoefficients();
336  return inited;
337  }
338 
339 }
340 
342 {
343  if (!test_rfinited()) {
344  throw ShogunException(
345  "float64_t * CRandomFourierGaussPreproc::apply_to_feature_vector(...): test_rfinited()==false: you need to call before CRandomFourierGaussPreproc::init (CFeatures *f) OR 1. set_dim_feature_space(const int32 dim), 2. set_dim_input_space(const int32 dim), 3. init_randomcoefficients() or set_randomcoefficients(...) \n");
346  }
347 
350 
351  for (int32_t od = 0; od < cur_dim_feature_space; ++od) {
352  res[od] = val * cos(randomcoeff_additive[od] + CMath::dot(vector.vector,
353  randomcoeff_multiplicative+od*cur_dim_input_space, cur_dim_input_space));
354  }
355 
357 }
358 
360 {
361  init(features);
362 
363  // version for case dim_feature_space < dim_input space with direct transformation on feature matrix ??
364 
365  int32_t num_vectors = 0;
366  int32_t num_features = 0;
367  float64_t* m = ((CSimpleFeatures<float64_t>*) features)->get_feature_matrix(
368  num_features, num_vectors);
369  SG_INFO("get Feature matrix: %ix%i\n", num_vectors, num_features);
370 
371  if (num_features!=cur_dim_input_space)
372  {
373  throw ShogunException(
374  "float64_t * CRandomFourierGaussPreproc::apply_to_feature_matrix(CFeatures *f): num_features!=cur_dim_input_space is not allowed\n");
375  }
376 
377  if (m) {
378  float64_t* res = SG_MALLOC(float64_t, num_vectors * cur_dim_feature_space);
379  if (res == NULL) {
380  throw ShogunException(
381  "CRandomFourierGaussPreproc::apply_to_feature_matrix(...): memory allocation failed \n");
382  }
383  float64_t val = CMath::sqrt(2.0 / cur_dim_feature_space);
384 
385  for (int32_t vec = 0; vec < num_vectors; vec++) {
386  for (int32_t od = 0; od < cur_dim_feature_space; ++od) {
387  res[od + vec * cur_dim_feature_space] = val * cos(
389  + CMath::dot(m+vec * num_features,
391  cur_dim_input_space));
392  }
393  }
394  ((CSimpleFeatures<float64_t>*) features)->set_feature_matrix(res,
395  cur_dim_feature_space, num_vectors);
396 
397  m = ((CSimpleFeatures<float64_t>*) features)->get_feature_matrix(
398  num_features, num_vectors);
399  ASSERT(num_features==cur_dim_feature_space);
400 
401  return SGMatrix<float64_t>(res,num_vectors,cur_dim_feature_space);
402  } else {
403  return SGMatrix<float64_t>();
404  }
405 }
406 
408 {
409 
410 }

SHOGUN Machine Learning Toolbox - Documentation