DistanceMachine.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) 1999-2009 Christian Gehl
00008  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST
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*) &param);
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*)&params[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(&params[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*) &param);
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*)&params[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(&params[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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation