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;
191 SG_INFO(
"precomputing distance matrix (%ix%i)\n", num_left, num_right) ;
193 ASSERT(num_left==num_right);
195 int32_t num=num_left;
200 for (int32_t i=0; i<num; i++)
203 for (int32_t j=0; j<=i; j++)
219 int32_t &num_vec1, int32_t &num_vec2,
float32_t* target)
228 SG_ERROR(
"distance matrix does not fit into target\n");
232 int64_t total_num=num_vec1*num_vec2;
235 SG_DEBUG(
"returning distance matrix of size %dx%d\n", num_vec1, num_vec2);
242 if ( (f1 == f2) && (num_vec1 == num_vec2) && (f1!=NULL && f2!=NULL) )
244 for (int32_t i=0; i<num_vec1; i++)
246 for (int32_t j=i; j<num_vec1; j++)
250 result[i+j*num_vec1]=v;
251 result[j+i*num_vec1]=v;
265 for (int32_t i=0; i<num_vec1; i++)
267 for (int32_t j=0; j<num_vec2; j++)
269 result[i+j*num_vec1]=
distance(i,j) ;
282 SG_ERROR(
"no features assigned to distance\n");
288 int32_t &lhs_vectors_number, int32_t &rhs_vectors_number,
float64_t* target)
296 SG_ERROR(
"No features assigned to the distance.\n");
301 SG_ERROR(
"Distance matrix does not fit into the given target.\n");
306 int64_t total_distances_number = lhs_vectors_number*rhs_vectors_number;
308 SG_DEBUG(
"Calculating distance matrix of size %dx%d.\n", lhs_vectors_number, rhs_vectors_number);
312 distance_matrix = target;
317 bool symmetric = (lhs_features==rhs_features) || (lhs_vectors_number==rhs_vectors_number);
319 bool chunk_by_lhs = (lhs_vectors_number >= rhs_vectors_number);
325 pthread_t* threads =
SG_MALLOC(pthread_t, num_threads);
326 DISTANCE_THREAD_PARAM* parameters =
SG_MALLOC(DISTANCE_THREAD_PARAM,num_threads);
328 pthread_attr_init(&attr);
329 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
331 for (int32_t t=0; t<num_threads; t++)
333 parameters[t].idx_start = t;
334 parameters[t].idx_stop = chunk_by_lhs ? lhs_vectors_number : rhs_vectors_number;
335 parameters[t].idx_step = num_threads;
336 parameters[t].distance_matrix = distance_matrix;
337 parameters[t].symmetric = symmetric;
338 parameters[t].lhs_vectors_number = lhs_vectors_number;
339 parameters[t].rhs_vectors_number = rhs_vectors_number;
340 parameters[t].chunk_by_lhs = chunk_by_lhs;
341 parameters[t].distance =
this;
345 for (int32_t t=0; t<num_threads; t++)
347 pthread_join(threads[t], NULL);
350 pthread_attr_destroy(&attr);
355 DISTANCE_THREAD_PARAM single_thread_param;
356 single_thread_param.idx_start = 0;
357 single_thread_param.idx_stop = chunk_by_lhs ? lhs_vectors_number : rhs_vectors_number;
358 single_thread_param.idx_step = 1;
359 single_thread_param.distance_matrix = distance_matrix;
360 single_thread_param.symmetric = symmetric;
361 single_thread_param.lhs_vectors_number = lhs_vectors_number;
362 single_thread_param.rhs_vectors_number = rhs_vectors_number;
363 single_thread_param.chunk_by_lhs = chunk_by_lhs;
364 single_thread_param.distance =
this;
369 return distance_matrix;
372 void CDistance::init()
382 "Feature vectors to occur on left hand side.");
384 "Feature vectors to occur on right hand side.");
389 DISTANCE_THREAD_PARAM* parameters = (DISTANCE_THREAD_PARAM*)p;
390 float64_t* distance_matrix = parameters->distance_matrix;
392 int32_t idx_start = parameters->idx_start;
393 int32_t idx_stop = parameters->idx_stop;
394 int32_t idx_step = parameters->idx_step;
395 int32_t lhs_vectors_number = parameters->lhs_vectors_number;
396 int32_t rhs_vectors_number = parameters->rhs_vectors_number;
397 bool symmetric = parameters->symmetric;
398 bool chunk_by_lhs = parameters->chunk_by_lhs;
402 for (int32_t i=idx_start; i<idx_stop; i+=idx_step)
404 for (int32_t j=i; j<rhs_vectors_number; j++)
407 distance_matrix[i*rhs_vectors_number+j] = ij_distance;
408 distance_matrix[j*rhs_vectors_number+i] = ij_distance;
416 for (int32_t i=idx_start; i<idx_stop; i+=idx_step)
418 for (int32_t j=0; j<rhs_vectors_number; j++)
420 distance_matrix[j*lhs_vectors_number+i] = distance->
compute(i,j);
426 for (int32_t j=idx_start; j<idx_stop; j+=idx_step)
428 for (int32_t i=0; i<lhs_vectors_number; i++)
430 distance_matrix[j*lhs_vectors_number+i] = distance->
compute(i,j);