patch_kmeans2.diff

use parallel_for for kmeans++ initialization if TBB is available - Boris Mansencal, 2011-07-29 05:07 pm

Download (2 kB)

 
modules/core/src/matrix.cpp (working copy)
2196 2196
    return d;
2197 2197
}
2198 2198

  
2199
#ifdef HAVE_TBB 
2200

  
2201
class KMeansPPDistanceComputer
2202
{
2203
  float *tdist2;
2204
  const float *data;
2205
  const float *dist;
2206
  const int dims;
2207
  const int step;
2208
  const int stepci;
2209

  
2210
public:
2211

  
2212
  KMeansPPDistanceComputer(float *_tdist2,
2213
			   const float *_data,
2214
			   const float *_dist,
2215
			   int _dims,
2216
			   int _step,
2217
			   int _stepci)
2218
    : tdist2(_tdist2),
2219
      data(_data),
2220
      dist(_dist),
2221
      dims(_dims),
2222
      step(_step),
2223
      stepci(_stepci)
2224
  {
2225

  
2226
  }
2227

  
2228
  void operator()(const cv::BlockedRange& range) const
2229
  {
2230

  
2231
    const int begin = range.begin();
2232
    const int end = range.end();
2233

  
2234
    for (int i=begin; i<end; ++i) {
2235
      tdist2[i] = std::min(distance(data + step*i, data + stepci, dims), dist[i]);
2236
    }
2237
  }
2238
  
2239
};
2240

  
2241
#endif //HAVE_TBB
2242

  
2243

  
2199 2244
/*
2200 2245
k-means center initialization using the following algorithm:
2201 2246
Arthur & Vassilvitskii (2007) k-means++: The Advantages of Careful Seeding
......
2227 2272

  
2228 2273
        for( j = 0; j < trials; j++ )
2229 2274
        {
2230
            double p = (double)rng*sum0, s = 0;
2275
            double p = (double)rng*sum0;
2231 2276
            for( i = 0; i < N-1; i++ )
2232 2277
                if( (p -= dist[i]) <= 0 )
2233 2278
                    break;
2234 2279
            int ci = i;
2280
	    double s=0;
2281
#ifndef HAVE_TBB 
2235 2282
            for( i = 0; i < N; i++ )
2236 2283
            {
2237 2284
                tdist2[i] = std::min(distance(data + step*i, data + step*ci, dims), dist[i]);
2238 2285
                s += tdist2[i];
2239 2286
            }
2287
#else
2288
	    cv::parallel_for(cv::BlockedRange(0, N),
2289
			     KMeansPPDistanceComputer(tdist2, data, dist, dims, step, step*ci));
2290
	    
2291
            for( i = 0; i < N; i++ )
2292
            {
2293
	      s += tdist2[i];
2294
            }
2295
#endif //HAVE_TBB
2240 2296
            
2241 2297
            if( s < bestSum )
2242 2298
            {