DotFeatures.cpp

Go to the documentation of this file.
00001 /*
00002  * This program is free software; you can redistribute it and/or modify
00003  * it under the terms of the GNU General Public License as published by
00004  * the Free Software Foundation; either version 3 of the License, or
00005  * (at your option) any later version.
00006  *
00007  * Written (W) 2009 Soeren Sonnenburg
00008  * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society
00009  */
00010 
00011 #include "features/DotFeatures.h"
00012 #include "lib/io.h"
00013 #include "lib/Signal.h"
00014 #include "base/Parallel.h"
00015 
00016 #ifndef WIN32
00017 #include <pthread.h>
00018 #endif
00019 
00020 using namespace shogun;
00021 
00022 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00023 struct DF_THREAD_PARAM
00024 {
00025     CDotFeatures* df;
00026     float64_t* output;
00027     int32_t start;
00028     int32_t stop;
00029     float64_t* alphas;
00030     float64_t* vec;
00031     int32_t dim;
00032     float64_t bias;
00033     bool progress;
00034 };
00035 #endif // DOXYGEN_SHOULD_SKIP_THIS
00036 
00037 void CDotFeatures::dense_dot_range(float64_t* output, int32_t start, int32_t stop, float64_t* alphas, float64_t* vec, int32_t dim, float64_t b)
00038 {
00039     ASSERT(output);
00040     ASSERT(start>=0);
00041     ASSERT(start<stop);
00042     ASSERT(stop<=get_num_vectors());
00043 
00044     int32_t num_vectors=stop-start;
00045     ASSERT(num_vectors>0);
00046 
00047     int32_t num_threads=parallel->get_num_threads();
00048     ASSERT(num_threads>0);
00049 
00050     CSignal::clear_cancel();
00051 
00052 #ifndef WIN32
00053     if (num_threads < 2)
00054     {
00055 #endif
00056         DF_THREAD_PARAM params;
00057         params.df=this;
00058         params.output=output;
00059         params.start=start;
00060         params.stop=stop;
00061         params.alphas=alphas;
00062         params.vec=vec;
00063         params.dim=dim;
00064         params.bias=b;
00065         params.progress=false; //true;
00066         dense_dot_range_helper((void*) &params);
00067 #ifndef WIN32
00068     }
00069     else
00070     {
00071         pthread_t* threads = new pthread_t[num_threads-1];
00072         DF_THREAD_PARAM* params = new DF_THREAD_PARAM[num_threads];
00073         int32_t step= num_vectors/num_threads;
00074 
00075         int32_t t;
00076 
00077         for (t=0; t<num_threads-1; t++)
00078         {
00079             params[t].df = this;
00080             params[t].output = output;
00081             params[t].start = start+t*step;
00082             params[t].stop = start+(t+1)*step;
00083             params[t].alphas=alphas;
00084             params[t].vec=vec;
00085             params[t].dim=dim;
00086             params[t].bias=b;
00087             params[t].progress = false;
00088             pthread_create(&threads[t], NULL,
00089                     CDotFeatures::dense_dot_range_helper, (void*)&params[t]);
00090         }
00091 
00092         params[t].df = this;
00093         params[t].output = output;
00094         params[t].start = start+t*step;
00095         params[t].stop = stop;
00096         params[t].alphas=alphas;
00097         params[t].vec=vec;
00098         params[t].dim=dim;
00099         params[t].bias=b;
00100         params[t].progress = false; //true;
00101         dense_dot_range_helper((void*) &params[t]);
00102 
00103         for (t=0; t<num_threads-1; t++)
00104             pthread_join(threads[t], NULL);
00105 
00106         delete[] params;
00107         delete[] threads;
00108     }
00109 #endif
00110 
00111 #ifndef WIN32
00112         if ( CSignal::cancel_computations() )
00113             SG_INFO( "prematurely stopped.           \n");
00114 #endif
00115 }
00116 
00117 void* CDotFeatures::dense_dot_range_helper(void* p)
00118 {
00119     DF_THREAD_PARAM* par=(DF_THREAD_PARAM*) p;
00120     CDotFeatures* df=par->df;
00121     float64_t* output=par->output;
00122     int32_t start=par->start;
00123     int32_t stop=par->stop;
00124     float64_t* alphas=par->alphas;
00125     float64_t* vec=par->vec;
00126     int32_t dim=par->dim;
00127     float64_t bias=par->bias;
00128     bool progress=par->progress;
00129 
00130     if (alphas)
00131     {
00132 #ifdef WIN32
00133         for (int32_t i=start; i<stop i++)
00134 #else
00135         for (int32_t i=start; i<stop &&
00136                 !CSignal::cancel_computations(); i++)
00137 #endif
00138         {
00139             output[i]=alphas[i]*df->dense_dot(i, vec, dim)+bias;
00140             if (progress)
00141                 df->display_progress(start, stop, i);
00142         }
00143     }
00144     else
00145     {
00146         for (int32_t i=start; i<stop; i++)
00147         {
00148             output[i]=df->dense_dot(i, vec, dim)+bias;
00149             if (progress)
00150                 df->display_progress(start, stop, i);
00151         }
00152     }
00153 
00154     return NULL;
00155 }
00156 
00157 void CDotFeatures::get_feature_matrix(float64_t** dst, int32_t* num_feat, int32_t* num_vec)
00158 {
00159     int64_t offs=0;
00160     int32_t num=get_num_vectors();
00161     int32_t dim=get_dim_feature_space();
00162     ASSERT(num>0);
00163     ASSERT(dim>0);
00164 
00165     int64_t sz=((uint64_t) num)* dim;
00166 
00167     *num_feat=dim;
00168     *num_vec=num;
00169     *dst=new float64_t[sz];
00170     memset(*dst, 0, sz*sizeof(float64_t));
00171 
00172     for (int32_t i=0; i<num; i++)
00173     {
00174         add_to_dense_vec(1.0, i, &((*dst)[offs]), dim);
00175         offs+=dim;
00176     }
00177 }

SHOGUN Machine Learning Toolbox - Documentation