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 "base/Parallel.h"
00014
00015 #ifndef WIN32
00016 #include <pthread.h>
00017 #endif
00018
00019 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00020 struct DF_THREAD_PARAM
00021 {
00022 CDotFeatures* df;
00023 float64_t* output;
00024 int32_t start;
00025 int32_t stop;
00026 float64_t* alphas;
00027 float64_t* vec;
00028 int32_t dim;
00029 float64_t bias;
00030 bool progress;
00031 };
00032 #endif // DOXYGEN_SHOULD_SKIP_THIS
00033
00034 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)
00035 {
00036 ASSERT(output);
00037 ASSERT(start>=0);
00038 ASSERT(start<stop);
00039 ASSERT(stop<=get_num_vectors());
00040
00041 int32_t num_vectors=stop-start;
00042 ASSERT(num_vectors>0);
00043
00044 int32_t num_threads=parallel->get_num_threads();
00045 ASSERT(num_threads>0);
00046
00047 #ifndef WIN32
00048 if (num_threads < 2)
00049 {
00050 #endif
00051 DF_THREAD_PARAM params;
00052 params.df=this;
00053 params.output=output;
00054 params.start=start;
00055 params.stop=stop;
00056 params.alphas=alphas;
00057 params.vec=vec;
00058 params.dim=dim;
00059 params.bias=b;
00060 params.progress=false;
00061 dense_dot_range_helper((void*) ¶ms);
00062 #ifndef WIN32
00063 }
00064 else
00065 {
00066 pthread_t* threads = new pthread_t[num_threads-1];
00067 DF_THREAD_PARAM* params = new DF_THREAD_PARAM[num_threads];
00068 int32_t step= num_vectors/num_threads;
00069
00070 int32_t t;
00071
00072 for (t=0; t<num_threads-1; t++)
00073 {
00074 params[t].df = this;
00075 params[t].output = output;
00076 params[t].start = start+t*step;
00077 params[t].stop = start+(t+1)*step;
00078 params[t].alphas=alphas;
00079 params[t].vec=vec;
00080 params[t].dim=dim;
00081 params[t].bias=b;
00082 params[t].progress = false;
00083 pthread_create(&threads[t], NULL,
00084 CDotFeatures::dense_dot_range_helper, (void*)¶ms[t]);
00085 }
00086
00087 params[t].df = this;
00088 params[t].output = output;
00089 params[t].start = start+t*step;
00090 params[t].stop = stop;
00091 params[t].alphas=alphas;
00092 params[t].vec=vec;
00093 params[t].dim=dim;
00094 params[t].bias=b;
00095 params[t].progress = false;
00096 dense_dot_range_helper((void*) ¶ms[t]);
00097
00098 for (t=0; t<num_threads-1; t++)
00099 pthread_join(threads[t], NULL);
00100
00101 delete[] params;
00102 delete[] threads;
00103 }
00104 #endif
00105 }
00106
00107 void* CDotFeatures::dense_dot_range_helper(void* p)
00108 {
00109 DF_THREAD_PARAM* par=(DF_THREAD_PARAM*) p;
00110 CDotFeatures* df=par->df;
00111 float64_t* output=par->output;
00112 int32_t start=par->start;
00113 int32_t stop=par->stop;
00114 float64_t* alphas=par->alphas;
00115 float64_t* vec=par->vec;
00116 int32_t dim=par->dim;
00117 float64_t bias=par->bias;
00118 bool progress=par->progress;
00119
00120 if (alphas)
00121 {
00122 for (int32_t i=start; i<stop; i++)
00123 {
00124 output[i]=alphas[i]*df->dense_dot(i, vec, dim)+bias;
00125 if (progress)
00126 df->display_progress(start, stop, i);
00127 }
00128 }
00129 else
00130 {
00131 for (int32_t i=start; i<stop; i++)
00132 {
00133 output[i]=df->dense_dot(i, vec, dim)+bias;
00134 if (progress)
00135 df->display_progress(start, stop, i);
00136 }
00137 }
00138
00139 return NULL;
00140 }
00141
00142 void CDotFeatures::get_feature_matrix(float64_t** dst, int32_t* num_feat, int32_t* num_vec)
00143 {
00144 int64_t offs=0;
00145 int32_t num=get_num_vectors();
00146 int32_t dim=get_dim_feature_space();
00147 ASSERT(num>0);
00148 ASSERT(dim>0);
00149
00150 int64_t sz=((uint64_t) num)* dim;
00151
00152 *num_feat=dim;
00153 *num_vec=num;
00154 *dst=new float64_t[sz];
00155 memset(*dst, 0, sz*sizeof(float64_t));
00156
00157 for (int32_t i=0; i<num; i++)
00158 {
00159 add_to_dense_vec(1.0, i, &((*dst)[offs]), dim);
00160 offs+=dim;
00161 }
00162 }