//---------------------------------------------------------------------- // swapOneCenter // Swaps one center point with a sample point. Optionally we make // sure that the new point is not a duplicate of any of the centers // (including the point being replaced). //---------------------------------------------------------------------- void KMfilterCenters::swapOneCenter( // swap one center bool allowDuplicate) // allow duplicate centers { int rj = kmRanInt(kCtrs); // index of center to replace int dim = getDim(); KMpoint p = kmAllocPt(dim); // alloc replacement point pts->sampleCtr(p); // sample a replacement if (!allowDuplicate) { // duplicates not allowed? bool dupFound; // was a duplicate found? do { // repeat until successful dupFound = false; for (int j = 0; j < kCtrs; j++) { // search for duplicates if (kmEqualPts(dim, p, ctrs[j])) { dupFound = true; pts->sampleCtr(p); // try again break; } } } while (dupFound); } kmCopyPt(dim, p, ctrs[rj]); // copy sampled point if (kmStatLev >= STEP) { // output swap info *kmOut << "\tswapping: "; kmPrintPt(p, getDim(), true); *kmOut << "<-->Center[" << rj << "]\n"; } kmDeallocPt(p); // deallocate point storage invalidate(); // distortions now invalid }
static void initDistGlobals( // initialize distortion globals KMfilterCenters& ctrs) // the centers { initBasicGlobals(ctrs.getDim(), ctrs.getNPts(), ctrs.getDataPts()); kcKCtrs = ctrs.getK(); kcCenters = ctrs.getCtrPts(); // get ptrs to KMcenter arrays kcWeights = ctrs.getWeights(false); kcSums = ctrs.getSums(false); kcSumSqs = ctrs.getSumSqs(false); kcDists = ctrs.getDists(false); kcBoxMidpt = kmAllocPt(kcDim); for (int j = 0; j < kcKCtrs; j++) { // initialize sums kcWeights[j] = 0; kcSumSqs[j] = 0; for (int d = 0; d < kcDim; d++) { kcSums[j][d] = 0; } } }
void kmMultiClus( // multi-sized clusters KMpointArray pa, // point array (modified) int n, // number of points int dim, // dimension int &k, // number of clusters (returned) double base_dev) // base standard deviation { int next = 0; // next point in array int nSamp = 0; // number of points sampled k = 0; // number of clusters generated KMpoint clusCenter = kmAllocPt(dim); // allocate center storage while (nSamp < n) { // until we have sampled enough int remain = n - nSamp; // number remaining to sample int clusSize = 2; // repeatedly double cluster size // with prob 1/2 while ((clusSize < remain) && (kmRan0() < 0.5)) clusSize *= 2; // don't exceed upper limit if (clusSize > remain) clusSize = remain; // generate center uniformly for (int d = 0; d < dim; d++) { clusCenter[d] = (KMcoord) kmRanUnif(-1,1); } // desired std dev for cluster double stdDev = base_dev*sqrt(1.0/clusSize); // generate cluster points for (int i = 0; i < clusSize; i++) { for (int d = 0; d < dim; d++) { pa[next][d] = (KMcoord) (stdDev*kmRanGauss()+clusCenter[d]); } next++; } nSamp += clusSize; // update number sampled k++; // one more cluster } kmDeallocPt(clusCenter); }