00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <shogun/preprocessor/RandomFourierGaussPreproc.h>
00013 #include <cmath>
00014
00015 using namespace shogun;
00016
00017 void CRandomFourierGaussPreproc::copy(const CRandomFourierGaussPreproc & feats) {
00018
00019 dim_input_space = feats.dim_input_space;
00020 cur_dim_input_space = feats.cur_dim_input_space;
00021
00022 dim_feature_space = feats.dim_feature_space;
00023 cur_dim_feature_space=feats.cur_dim_feature_space;
00024
00025 kernelwidth=feats.kernelwidth;
00026 cur_kernelwidth=feats.cur_kernelwidth;
00027
00028 if(cur_dim_feature_space>0)
00029 {
00030 if(feats.randomcoeff_additive==NULL)
00031 {
00032 throw ShogunException(
00033 "void CRandomFourierGaussPreproc::copy(...): feats.randomcoeff_additive==NULL && cur_dim_feature_space>0 \n");
00034 }
00035
00036 randomcoeff_additive = SG_MALLOC(float64_t, cur_dim_feature_space);
00037 std::copy(feats.randomcoeff_additive,feats.randomcoeff_additive+cur_dim_feature_space,randomcoeff_additive);
00038 }
00039 else
00040 {
00041 randomcoeff_additive = NULL;
00042 }
00043
00044 if((cur_dim_feature_space>0)&&(cur_dim_input_space>0))
00045 {
00046 if(feats.randomcoeff_multiplicative==NULL)
00047 {
00048 throw ShogunException(
00049 "void CRandomFourierGaussPreproc::copy(...): feats.randomcoeff_multiplicative==NULL && cur_dim_feature_space>0 &&(cur_dim_input_space>0) \n");
00050 }
00051
00052 randomcoeff_multiplicative=SG_MALLOC(float64_t, cur_dim_feature_space*cur_dim_input_space);
00053 std::copy(feats.randomcoeff_multiplicative,feats.randomcoeff_multiplicative+cur_dim_feature_space*cur_dim_input_space,randomcoeff_multiplicative);
00054 }
00055 else
00056 {
00057 randomcoeff_multiplicative = NULL;
00058 }
00059
00060 }
00061
00062 CRandomFourierGaussPreproc::CRandomFourierGaussPreproc() :
00063 CDensePreprocessor<float64_t> () {
00064 dim_feature_space = 1000;
00065 dim_input_space = 0;
00066 cur_dim_input_space = 0;
00067 cur_dim_feature_space=0;
00068
00069 randomcoeff_multiplicative=NULL;
00070 randomcoeff_additive=NULL;
00071
00072 kernelwidth=1;
00073 cur_kernelwidth=kernelwidth;
00074
00075
00076
00077 if(m_parameters)
00078 {
00079 SG_ADD(&dim_input_space, "dim_input_space",
00080 "Dimensionality of the input space.", MS_NOT_AVAILABLE);
00081 SG_ADD(&cur_dim_input_space, "cur_dim_input_space",
00082 "Dimensionality of the input space.", MS_NOT_AVAILABLE);
00083 SG_ADD(&dim_feature_space, "dim_feature_space",
00084 "Dimensionality of the feature space.", MS_NOT_AVAILABLE);
00085 SG_ADD(&cur_dim_feature_space, "cur_dim_feature_space",
00086 "Dimensionality of the feature space.", MS_NOT_AVAILABLE);
00087
00088 SG_ADD(&kernelwidth, "kernelwidth", "Kernel width.", MS_AVAILABLE);
00089 SG_ADD(&cur_kernelwidth, "cur_kernelwidth", "Kernel width.", MS_AVAILABLE);
00090
00091 m_parameters->add_vector(&randomcoeff_additive,&cur_dim_feature_space,"randomcoeff_additive");
00092 m_parameters->add_matrix(&randomcoeff_multiplicative,&cur_dim_feature_space,&cur_dim_input_space,"randomcoeff_multiplicative");
00093 }
00094
00095 }
00096
00097 CRandomFourierGaussPreproc::CRandomFourierGaussPreproc(
00098 const CRandomFourierGaussPreproc & feats) :
00099 CDensePreprocessor<float64_t> () {
00100
00101 randomcoeff_multiplicative=NULL;
00102 randomcoeff_additive=NULL;
00103
00104
00105
00106 if(m_parameters)
00107 {
00108 SG_ADD(&dim_input_space, "dim_input_space",
00109 "Dimensionality of the input space.", MS_NOT_AVAILABLE);
00110 SG_ADD(&cur_dim_input_space, "cur_dim_input_space",
00111 "Dimensionality of the input space.", MS_NOT_AVAILABLE);
00112 SG_ADD(&dim_feature_space, "dim_feature_space",
00113 "Dimensionality of the feature space.", MS_NOT_AVAILABLE);
00114 SG_ADD(&cur_dim_feature_space, "cur_dim_feature_space",
00115 "Dimensionality of the feature space.", MS_NOT_AVAILABLE);
00116
00117 SG_ADD(&kernelwidth, "kernelwidth", "Kernel width.", MS_AVAILABLE);
00118 SG_ADD(&cur_kernelwidth, "cur_kernelwidth", "Kernel width.", MS_AVAILABLE);
00119
00120 m_parameters->add_vector(&randomcoeff_additive,&cur_dim_feature_space,"randomcoeff_additive");
00121 m_parameters->add_matrix(&randomcoeff_multiplicative,&cur_dim_feature_space,&cur_dim_input_space,"randomcoeff_multiplicative");
00122 }
00123
00124 copy(feats);
00125 }
00126
00127 CRandomFourierGaussPreproc::~CRandomFourierGaussPreproc() {
00128
00129 SG_FREE(randomcoeff_multiplicative);
00130 SG_FREE(randomcoeff_additive);
00131
00132 }
00133
00134 EFeatureClass CRandomFourierGaussPreproc::get_feature_class() {
00135 return C_DENSE;
00136 }
00137
00138 EFeatureType CRandomFourierGaussPreproc::get_feature_type() {
00139 return F_DREAL;
00140 }
00141
00142 int32_t CRandomFourierGaussPreproc::get_dim_feature_space() const {
00143 return ((int32_t) dim_feature_space);
00144 }
00145
00146 void CRandomFourierGaussPreproc::set_dim_feature_space(const int32_t dim) {
00147 if (dim <= 0) {
00148 throw ShogunException(
00149 "void CRandomFourierGaussPreproc::set_dim_feature_space(const int32 dim): dim<=0 is not allowed");
00150 }
00151
00152 dim_feature_space = dim;
00153
00154 }
00155
00156 int32_t CRandomFourierGaussPreproc::get_dim_input_space() const {
00157 return ((int32_t) dim_input_space);
00158 }
00159
00160 void CRandomFourierGaussPreproc::set_kernelwidth(const float64_t kernelwidth2 ) {
00161 if (kernelwidth2 <= 0) {
00162 throw ShogunException(
00163 "void CRandomFourierGaussPreproc::set_kernelwidth(const float64_t kernelwidth2 ): kernelwidth2 <= 0 is not allowed");
00164 }
00165 kernelwidth=kernelwidth2;
00166 }
00167
00168 float64_t CRandomFourierGaussPreproc::get_kernelwidth( ) const {
00169 return (kernelwidth);
00170 }
00171
00172 void CRandomFourierGaussPreproc::set_dim_input_space(const int32_t dim) {
00173 if (dim <= 0) {
00174 throw ShogunException(
00175 "void CRandomFourierGaussPreproc::set_dim_input_space(const int32 dim): dim<=0 is not allowed");
00176 }
00177
00178 dim_input_space = dim;
00179
00180 }
00181
00182 bool CRandomFourierGaussPreproc::test_rfinited() const {
00183
00184 if ((dim_feature_space == cur_dim_feature_space)
00185 && (dim_input_space > 0) && (dim_feature_space > 0)) {
00186 if ((dim_input_space == cur_dim_input_space)&&(CMath::abs(kernelwidth-cur_kernelwidth)<1e-5)) {
00187
00188
00189 return true;
00190 } else {
00191 return false;
00192 }
00193 }
00194
00195 return false;
00196 }
00197
00198 bool CRandomFourierGaussPreproc::init_randomcoefficients() {
00199 if (dim_feature_space <= 0) {
00200 throw ShogunException(
00201 "bool CRandomFourierGaussPreproc::init_randomcoefficients(): dim_feature_space<=0 is not allowed\n");
00202 }
00203 if (dim_input_space <= 0) {
00204 throw ShogunException(
00205 "bool CRandomFourierGaussPreproc::init_randomcoefficients(): dim_input_space<=0 is not allowed\n");
00206 }
00207
00208 if (test_rfinited()) {
00209 return false;
00210 }
00211
00212
00213 SG_INFO("initializing randomcoefficients \n") ;
00214
00215 float64_t pi = 3.14159265;
00216
00217
00218 SG_FREE(randomcoeff_multiplicative);
00219 randomcoeff_multiplicative=NULL;
00220 SG_FREE(randomcoeff_additive);
00221 randomcoeff_additive=NULL;
00222
00223
00224 cur_dim_feature_space=dim_feature_space;
00225 randomcoeff_additive=SG_MALLOC(float64_t, cur_dim_feature_space);
00226 cur_dim_input_space = dim_input_space;
00227 randomcoeff_multiplicative=SG_MALLOC(float64_t, cur_dim_feature_space*cur_dim_input_space);
00228
00229 cur_kernelwidth=kernelwidth;
00230
00231 for (int32_t i = 0; i < cur_dim_feature_space; ++i) {
00232 randomcoeff_additive[i] = CMath::random((float64_t) 0.0, 2 * pi);
00233 }
00234
00235 for (int32_t i = 0; i < cur_dim_feature_space; ++i) {
00236 for (int32_t k = 0; k < cur_dim_input_space; ++k) {
00237 float64_t x1,x2;
00238 float64_t s = 2;
00239 while ((s >= 1) ) {
00240
00241 x1 = CMath::random((float64_t) -1.0, (float64_t) 1.0);
00242 x2 = CMath::random((float64_t) -1.0, (float64_t) 1.0);
00243 s=x1*x1+x2*x2;
00244 }
00245
00246
00247 randomcoeff_multiplicative[i*cur_dim_input_space+k] = x1*CMath::sqrt(-2*CMath::log(s)/s )/kernelwidth;
00248 }
00249 }
00250
00251 SG_INFO("finished: initializing randomcoefficients \n") ;
00252
00253 return true;
00254 }
00255
00256 void CRandomFourierGaussPreproc::get_randomcoefficients(
00257 float64_t ** randomcoeff_additive2,
00258 float64_t ** randomcoeff_multiplicative2, int32_t *dim_feature_space2,
00259 int32_t *dim_input_space2, float64_t* kernelwidth2) const {
00260
00261 ASSERT(randomcoeff_additive2);
00262 ASSERT(randomcoeff_multiplicative2);
00263
00264 if (!test_rfinited()) {
00265 *dim_feature_space2 = 0;
00266 *dim_input_space2 = 0;
00267 *kernelwidth2=1;
00268 *randomcoeff_additive2 = NULL;
00269 *randomcoeff_multiplicative2 = NULL;
00270 return;
00271 }
00272
00273 *dim_feature_space2 = cur_dim_feature_space;
00274 *dim_input_space2 = cur_dim_input_space;
00275 *kernelwidth2=cur_kernelwidth;
00276
00277 *randomcoeff_additive2 = SG_MALLOC(float64_t, cur_dim_feature_space);
00278 *randomcoeff_multiplicative2 = SG_MALLOC(float64_t, cur_dim_feature_space*cur_dim_input_space);
00279
00280 std::copy(randomcoeff_additive, randomcoeff_additive+cur_dim_feature_space,
00281 *randomcoeff_additive2);
00282 std::copy(randomcoeff_multiplicative, randomcoeff_multiplicative+cur_dim_feature_space*cur_dim_input_space,
00283 *randomcoeff_multiplicative2);
00284
00285
00286 }
00287
00288 void CRandomFourierGaussPreproc::set_randomcoefficients(
00289 float64_t *randomcoeff_additive2,
00290 float64_t * randomcoeff_multiplicative2,
00291 const int32_t dim_feature_space2, const int32_t dim_input_space2, const float64_t kernelwidth2) {
00292 dim_feature_space = dim_feature_space2;
00293 dim_input_space = dim_input_space2;
00294 kernelwidth=kernelwidth2;
00295
00296 SG_FREE(randomcoeff_multiplicative);
00297 randomcoeff_multiplicative=NULL;
00298 SG_FREE(randomcoeff_additive);
00299 randomcoeff_additive=NULL;
00300
00301 cur_dim_feature_space=dim_feature_space;
00302 cur_dim_input_space = dim_input_space;
00303 cur_kernelwidth=kernelwidth;
00304
00305 if( (dim_feature_space>0) && (dim_input_space>0) )
00306 {
00307 randomcoeff_additive=SG_MALLOC(float64_t, cur_dim_feature_space);
00308 randomcoeff_multiplicative=SG_MALLOC(float64_t, cur_dim_feature_space*cur_dim_input_space);
00309
00310 std::copy(randomcoeff_additive2, randomcoeff_additive2
00311 + dim_feature_space, randomcoeff_additive);
00312 std::copy(randomcoeff_multiplicative2, randomcoeff_multiplicative2
00313 + cur_dim_feature_space*cur_dim_input_space, randomcoeff_multiplicative);
00314 }
00315
00316 }
00317
00318 bool CRandomFourierGaussPreproc::init(CFeatures *f) {
00319 if (f->get_feature_class() != get_feature_class()) {
00320 throw ShogunException(
00321 "CRandomFourierGaussPreproc::init (CFeatures *f) requires CDenseFeatures<float64_t> as features\n");
00322 }
00323 if (f->get_feature_type() != get_feature_type()) {
00324 throw ShogunException(
00325 "CRandomFourierGaussPreproc::init (CFeatures *f) requires CDenseFeatures<float64_t> as features\n");
00326 }
00327 if (dim_feature_space <= 0) {
00328 throw ShogunException(
00329 "CRandomFourierGaussPreproc::init (CFeatures *f): dim_feature_space<=0 is not allowed, use void set_dim_feature_space(const int32 dim) before!\n");
00330 }
00331
00332 SG_INFO("calling CRandomFourierGaussPreproc::init(...)\n");
00333 int32_t num_features =
00334 ((CDenseFeatures<float64_t>*) f)->get_num_features();
00335
00336 if (!test_rfinited()) {
00337 dim_input_space = num_features;
00338 init_randomcoefficients();
00339 ASSERT( test_rfinited());
00340 return true;
00341 } else {
00342 dim_input_space = num_features;
00343
00344 bool inited = init_randomcoefficients();
00345 return inited;
00346 }
00347
00348 }
00349
00350 SGVector<float64_t> CRandomFourierGaussPreproc::apply_to_feature_vector(SGVector<float64_t> vector)
00351 {
00352 if (!test_rfinited()) {
00353 throw ShogunException(
00354 "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");
00355 }
00356
00357 float64_t val = CMath::sqrt(2.0 / cur_dim_feature_space);
00358 float64_t *res = SG_MALLOC(float64_t, cur_dim_feature_space);
00359
00360 for (int32_t od = 0; od < cur_dim_feature_space; ++od) {
00361 res[od] = val * cos(randomcoeff_additive[od] + SGVector<float64_t>::dot(vector.vector,
00362 randomcoeff_multiplicative+od*cur_dim_input_space, cur_dim_input_space));
00363 }
00364
00365 return SGVector<float64_t>(res,cur_dim_feature_space);
00366 }
00367
00368 SGMatrix<float64_t> CRandomFourierGaussPreproc::apply_to_feature_matrix(CFeatures* features)
00369 {
00370 init(features);
00371
00372
00373
00374 int32_t num_vectors = 0;
00375 int32_t num_features = 0;
00376 float64_t* m = ((CDenseFeatures<float64_t>*) features)->get_feature_matrix(
00377 num_features, num_vectors);
00378 SG_INFO("get Feature matrix: %ix%i\n", num_vectors, num_features);
00379
00380 if (num_features!=cur_dim_input_space)
00381 {
00382 throw ShogunException(
00383 "float64_t * CRandomFourierGaussPreproc::apply_to_feature_matrix(CFeatures *f): num_features!=cur_dim_input_space is not allowed\n");
00384 }
00385
00386 if (m)
00387 {
00388 SGMatrix<float64_t> res(cur_dim_feature_space,num_vectors);
00389
00390 float64_t val = CMath::sqrt(2.0 / cur_dim_feature_space);
00391
00392 for (int32_t vec = 0; vec < num_vectors; vec++)
00393 {
00394 for (int32_t od = 0; od < cur_dim_feature_space; ++od)
00395 {
00396 res.matrix[od + vec * cur_dim_feature_space] = val * cos(
00397 randomcoeff_additive[od]
00398 + SGVector<float64_t>::dot(m+vec * num_features,
00399 randomcoeff_multiplicative+od*cur_dim_input_space,
00400 cur_dim_input_space));
00401 }
00402 }
00403 ((CDenseFeatures<float64_t>*) features)->set_feature_matrix(res);
00404
00405 return res;
00406 }
00407 else
00408 return SGMatrix<float64_t>();
00409 }
00410
00411 void CRandomFourierGaussPreproc::cleanup()
00412 {
00413
00414 }