DotFeatures.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
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;
00066 dense_dot_range_helper((void*) ¶ms);
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*)¶ms[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;
00101 dense_dot_range_helper((void*) ¶ms[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 }