Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "classifier/DistanceMachine.h"
00012
00013 using namespace shogun;
00014
00015 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00016 struct D_THREAD_PARAM
00017 {
00018 CDistance* d;
00019 float64_t* r;
00020 int32_t idx_r_start;
00021 int32_t idx_start;
00022 int32_t idx_stop;
00023 int32_t idx_comp;
00024 };
00025 #endif // DOXYGEN_SHOULD_SKIP_THIS
00026
00027 CDistanceMachine::CDistanceMachine()
00028 : CClassifier(), distance(NULL)
00029 {
00030 }
00031
00032 CDistanceMachine::~CDistanceMachine()
00033 {
00034 SG_UNREF(distance);
00035 }
00036
00037 void CDistanceMachine::distances_lhs(float64_t* result,int32_t idx_a1,int32_t idx_a2,int32_t idx_b)
00038 {
00039 int32_t num_threads=parallel->get_num_threads();
00040 ASSERT(num_threads>0);
00041
00042 ASSERT(result);
00043
00044 if (num_threads < 2)
00045 {
00046 D_THREAD_PARAM param;
00047 param.d=distance;
00048 param.r=result;
00049 param.idx_r_start=idx_a1;
00050 param.idx_start=idx_a1;
00051 param.idx_stop=idx_a2+1;
00052 param.idx_comp=idx_b;
00053
00054 run_distance_thread_lhs((void*) ¶m);
00055 }
00056 #ifndef WIN32
00057 else
00058 {
00059 pthread_t* threads = new pthread_t[num_threads-1];
00060 D_THREAD_PARAM* params = new D_THREAD_PARAM[num_threads];
00061 int32_t num_vec=idx_a2-idx_a1+1;
00062 int32_t step= num_vec/num_threads;
00063 int32_t t;
00064
00065 pthread_attr_t attr;
00066 pthread_attr_init(&attr);
00067 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00068
00069 for (t=0; t<num_threads-1; t++)
00070 {
00071 params[t].d = distance;
00072 params[t].r = result;
00073 params[t].idx_r_start=t*step;
00074 params[t].idx_start = (t*step)+idx_a1;
00075 params[t].idx_stop = ((t+1)*step)+idx_a1;
00076 params[t].idx_comp=idx_b;
00077
00078 pthread_create(&threads[t], &attr, CDistanceMachine::run_distance_thread_lhs, (void*)¶ms[t]);
00079 }
00080 params[t].d = distance;
00081 params[t].r = result;
00082 params[t].idx_r_start=t*step;
00083 params[t].idx_start = (t*step)+idx_a1;
00084 params[t].idx_stop = idx_a2+1;
00085 params[t].idx_comp=idx_b;
00086
00087 run_distance_thread_lhs(¶ms[t]);
00088
00089 for (t=0; t<num_threads-1; t++)
00090 pthread_join(threads[t], NULL);
00091
00092 pthread_attr_destroy(&attr);
00093 delete[] params;
00094 delete[] threads;
00095 }
00096 #endif
00097 }
00098
00099 void CDistanceMachine::distances_rhs(float64_t* result,int32_t idx_b1,int32_t idx_b2,int32_t idx_a)
00100 {
00101 int32_t num_threads=parallel->get_num_threads();
00102 ASSERT(num_threads>0);
00103
00104 ASSERT(result);
00105
00106 if (num_threads < 2)
00107 {
00108 D_THREAD_PARAM param;
00109 param.d=distance;
00110 param.r=result;
00111 param.idx_r_start=idx_b1;
00112 param.idx_start=idx_b1;
00113 param.idx_stop=idx_b2+1;
00114 param.idx_comp=idx_a;
00115
00116 run_distance_thread_rhs((void*) ¶m);
00117 }
00118 #ifndef WIN32
00119 else
00120 {
00121 pthread_t* threads = new pthread_t[num_threads-1];
00122 D_THREAD_PARAM* params = new D_THREAD_PARAM[num_threads];
00123 int32_t num_vec=idx_b2-idx_b1+1;
00124 int32_t step= num_vec/num_threads;
00125 int32_t t;
00126
00127 pthread_attr_t attr;
00128 pthread_attr_init(&attr);
00129 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00130
00131 for (t=0; t<num_threads-1; t++)
00132 {
00133 params[t].d = distance;
00134 params[t].r = result;
00135 params[t].idx_r_start=t*step;
00136 params[t].idx_start = (t*step)+idx_b1;
00137 params[t].idx_stop = ((t+1)*step)+idx_b1;
00138 params[t].idx_comp=idx_a;
00139
00140 pthread_create(&threads[t], &attr, CDistanceMachine::run_distance_thread_rhs, (void*)¶ms[t]);
00141 }
00142 params[t].d = distance;
00143 params[t].r = result;
00144 params[t].idx_r_start=t*step;
00145 params[t].idx_start = (t*step)+idx_b1;
00146 params[t].idx_stop = idx_b2+1;
00147 params[t].idx_comp=idx_a;
00148
00149 run_distance_thread_rhs(¶ms[t]);
00150
00151 for (t=0; t<num_threads-1; t++)
00152 pthread_join(threads[t], NULL);
00153
00154 pthread_attr_destroy(&attr);
00155 delete[] params;
00156 delete[] threads;
00157 }
00158 #endif
00159 }
00160
00161 void* CDistanceMachine::run_distance_thread_lhs(void* p)
00162 {
00163 D_THREAD_PARAM* params= (D_THREAD_PARAM*) p;
00164 CDistance* distance=params->d;
00165 float64_t* res=params->r;
00166 int32_t idx_res_start=params->idx_r_start;
00167 int32_t idx_act=params->idx_start;
00168 int32_t idx_stop=params->idx_stop;
00169 int32_t idx_c=params->idx_comp;
00170
00171 for (int32_t i=idx_res_start; idx_act<idx_stop; i++,idx_act++)
00172 res[i] =distance->distance(idx_act,idx_c);
00173
00174 return NULL;
00175 }
00176
00177 void* CDistanceMachine::run_distance_thread_rhs(void* p)
00178 {
00179 D_THREAD_PARAM* params= (D_THREAD_PARAM*) p;
00180 CDistance* distance=params->d;
00181 float64_t* res=params->r;
00182 int32_t idx_res_start=params->idx_r_start;
00183 int32_t idx_act=params->idx_start;
00184 int32_t idx_stop=params->idx_stop;
00185 int32_t idx_c=params->idx_comp;
00186
00187 for (int32_t i=idx_res_start; idx_act<idx_stop; i++,idx_act++)
00188 res[i] =distance->distance(idx_c,idx_act);
00189
00190 return NULL;
00191 }