30 using namespace shogun;
32 #ifndef DOXYGEN_SHOULD_SKIP_THIS
33 struct DISTANCE_THREAD_PARAM
46 int32_t lhs_vectors_number;
48 int32_t rhs_vectors_number;
161 SG_INFO(
"precomputing distance matrix (%ix%i)\n", num_left, num_right) ;
163 ASSERT(num_left==num_right);
165 int32_t num=num_left;
170 for (int32_t i=0; i<num; i++)
173 for (int32_t j=0; j<=i; j++)
189 int32_t &num_vec1, int32_t &num_vec2,
float32_t* target)
198 SG_ERROR(
"distance matrix does not fit into target\n");
202 int64_t total_num=num_vec1*num_vec2;
205 SG_DEBUG(
"returning distance matrix of size %dx%d\n", num_vec1, num_vec2);
212 if ( (f1 == f2) && (num_vec1 == num_vec2) )
214 for (int32_t i=0; i<num_vec1; i++)
216 for (int32_t j=i; j<num_vec1; j++)
220 result[i+j*num_vec1]=v;
221 result[j+i*num_vec1]=v;
235 for (int32_t i=0; i<num_vec1; i++)
237 for (int32_t j=0; j<num_vec2; j++)
239 result[i+j*num_vec1]=
distance(i,j) ;
252 SG_ERROR(
"no features assigned to distance\n");
258 int32_t &lhs_vectors_number, int32_t &rhs_vectors_number,
float64_t* target)
265 if (!lhs_features || !rhs_features)
266 SG_ERROR(
"No features assigned to the distance.\n");
271 SG_ERROR(
"Distance matrix does not fit into the given target.\n");
276 int64_t total_distances_number = lhs_vectors_number*rhs_vectors_number;
278 SG_DEBUG(
"Calculating distance matrix of size %dx%d.\n", lhs_vectors_number, rhs_vectors_number);
282 distance_matrix = target;
287 bool symmetric = (lhs_features==rhs_features) || (lhs_vectors_number==rhs_vectors_number);
289 bool chunk_by_lhs = (lhs_vectors_number >= rhs_vectors_number);
295 pthread_t* threads =
SG_MALLOC(pthread_t, num_threads);
296 DISTANCE_THREAD_PARAM* parameters =
SG_MALLOC(DISTANCE_THREAD_PARAM,num_threads);
298 pthread_attr_init(&attr);
299 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
301 for (int32_t t=0; t<num_threads; t++)
303 parameters[t].idx_start = t;
304 parameters[t].idx_stop = chunk_by_lhs ? lhs_vectors_number : rhs_vectors_number;
305 parameters[t].idx_step = num_threads;
306 parameters[t].distance_matrix = distance_matrix;
307 parameters[t].symmetric = symmetric;
308 parameters[t].lhs_vectors_number = lhs_vectors_number;
309 parameters[t].rhs_vectors_number = rhs_vectors_number;
310 parameters[t].chunk_by_lhs = chunk_by_lhs;
311 parameters[t].distance =
this;
315 for (int32_t t=0; t<num_threads; t++)
317 pthread_join(threads[t], NULL);
320 pthread_attr_destroy(&attr);
325 DISTANCE_THREAD_PARAM single_thread_param;
326 single_thread_param.idx_start = 0;
327 single_thread_param.idx_stop = chunk_by_lhs ? lhs_vectors_number : rhs_vectors_number;
328 single_thread_param.idx_step = 1;
329 single_thread_param.distance_matrix = distance_matrix;
330 single_thread_param.symmetric = symmetric;
331 single_thread_param.lhs_vectors_number = lhs_vectors_number;
332 single_thread_param.rhs_vectors_number = rhs_vectors_number;
333 single_thread_param.chunk_by_lhs = chunk_by_lhs;
334 single_thread_param.distance =
this;
339 return distance_matrix;
342 void CDistance::init()
350 "Feature vectors to occur on left hand side.");
352 "Feature vectors to occur on right hand side.");
357 DISTANCE_THREAD_PARAM* parameters = (DISTANCE_THREAD_PARAM*)p;
358 float64_t* distance_matrix = parameters->distance_matrix;
360 int32_t idx_start = parameters->idx_start;
361 int32_t idx_stop = parameters->idx_stop;
362 int32_t idx_step = parameters->idx_step;
363 int32_t lhs_vectors_number = parameters->lhs_vectors_number;
364 int32_t rhs_vectors_number = parameters->rhs_vectors_number;
365 bool symmetric = parameters->symmetric;
366 bool chunk_by_lhs = parameters->chunk_by_lhs;
370 for (int32_t i=idx_start; i<idx_stop; i+=idx_step)
372 for (int32_t j=i; j<rhs_vectors_number; j++)
375 distance_matrix[i*rhs_vectors_number+j] = ij_distance;
376 distance_matrix[j*rhs_vectors_number+i] = ij_distance;
384 for (int32_t i=idx_start; i<idx_stop; i+=idx_step)
386 for (int32_t j=0; j<rhs_vectors_number; j++)
388 distance_matrix[j*lhs_vectors_number+i] = distance->
compute(i,j);
394 for (int32_t j=idx_start; j<idx_stop; j+=idx_step)
396 for (int32_t i=0; i<lhs_vectors_number; i++)
398 distance_matrix[j*lhs_vectors_number+i] = distance->
compute(i,j);