Пример #1
0
void kmClusEllipsoids(		// clustered around ellipsoids
	KMpointArray	pa,		// point array (modified)
	int		n,		// number of points
	int		dim,		// dimension
	int		n_col,		// number of colors
	bool		new_clust,	// generate new clusters.
	double		std_dev_small,	// small standard deviation
	double		std_dev_lo,	// low standard deviation for ellipses
	double		std_dev_hi,	// high standard deviation for ellipses
	int		max_dim)	// maximum dimension of the flats
{
    static KMpointArray clusters = NULL;	// cluster centers
    static KMpointArray stdDev = NULL;		// standard deviations

    if (clusters == NULL || new_clust) {	// need new cluster centers
	if (clusters != NULL)			// clusters already exist
	    kmDeallocPts(clusters);		// get rid of them
	if (stdDev != NULL)			// std deviations already exist
	    kmDeallocPts(stdDev);		// get rid of them

	clusters = kmAllocPts(n_col, dim);	// alloc new clusters and devs
	stdDev   = kmAllocPts(n_col, dim);

	for (int i = 0; i < n_col; i++) {	// gen cluster center coords
	    for (int d = 0; d < dim; d++) {
		clusters[i][d] = (KMcoord) kmRanUnif(-1,1);
	    }
	}
	for (int c = 0; c < n_col; c++) {	// generate cluster std dev
	    int n_dim = 1 + kmRanInt(max_dim);	// number of dimensions in flat
	    for (int d = 0; d < dim; d++) {	// generate std dev's
						// prob. of picking next dim
	    	double Prob = ((double) n_dim)/((double) (dim-d));
		if (kmRan0() < Prob) {		// add this one to ellipse
						// generate random std dev
		    stdDev[c][d] = kmRanUnif(std_dev_lo, std_dev_hi);
		    n_dim--;			// one fewer dim to fill
		}
		else {				// don't take this one
		    stdDev[c][d] = std_dev_small;// use small std dev
		}
	    }
	}
    }

    int next = 0;				// next slot to fill
    for (int c = 0; c < n_col; c++) {		// generate clusters
	int pick = (n+c)/n_col;			// number of points to pick
	for (int i = 0; i < pick; i++) {
	    for (int d = 0; d < dim; d++) {
        	pa[next][d] = (KMcoord)
			(stdDev[c][d]*kmRanGauss() + clusters[c][d]);
	    }
	    next++;
	}
    }
}
Пример #2
0
					// assignment operator
KMfilterCenters& KMfilterCenters::operator=(const KMfilterCenters& s) {
    if (this != &s) {			// avoid self copy (x=x)
					// different sizes?
	if (kCtrs != s.kCtrs || getDim() != s.getDim()) {
	    kmDeallocPts(sums);		// deallocate old storage
	    delete [] sumSqs;
	    delete [] weights;
	    delete [] dists;
	    				// allocate new storage
	    sums    = kmAllocPts(s.kCtrs, s.getDim());
	    sumSqs  = new double[s.kCtrs];
	    weights = new int[s.kCtrs];
	    dists   = new double[s.kCtrs];
	}
	KMcenters& base = *this;	
	base.operator=(s);		// copy base class
					// copy array contents
	kmCopyPts(kCtrs, getDim(), s.sums, sums);
	kmCopy(kCtrs, s.sumSqs, sumSqs);
	kmCopy(kCtrs, s.weights, weights);
	kmCopy(kCtrs, s.dists, dists);
	valid   = s.valid;
    }
    currDist = s.currDist;
    dampFactor = s.dampFactor;
    return *this;
}
Пример #3
0
void KMdata::resize(int d, int n) {	// resize point array
    if (d != dim || n != nPts) {		// size change?
	dim = d;
	nPts = n;
	kmDeallocPts(pts);			// deallocate old points
	pts = kmAllocPts(nPts, dim);
    }
    if (kcTree != NULL) {			// kc-tree exists?
	delete kcTree;				// deallocate kc-tree
	kcTree = NULL;
    }
}
Пример #4
0
    					// assignment operator
KMcenters& KMcenters::operator=(const KMcenters& s) {
    if (this != &s) {			// avoid self assignment (x=x)
					// size change?
	if (kCtrs != s.kCtrs || getDim() != s.getDim()) {
	    kmDeallocPts(ctrs);		// reallocate points
	    ctrs = kmAllocPts(s.kCtrs, s.getDim());
	}
	kCtrs = s.kCtrs;
	pts = s.pts;
	kmCopyPts(kCtrs, s.getDim(), s.ctrs, ctrs);
    }
    return *this;
}
Пример #5
0
KMpointArray kmAllocCopyPts(		// allocate and copy point array
    int			n,			// number of points
    int			dim,			// dimension
    const KMpointArray	source)			// source point
{
    KMpointArray dest = kmAllocPts(n, dim);
    for (int j = 0; j < n; j++) {
        for (int i = 0; i < dim; i++) {
	    dest[j][i] = source[j][i];
	}
    }
    return dest;
}
Пример #6
0
void kmClusOrthFlats(		// clustered along orthogonal flats
	KMpointArray	pa,		// point array (modified)
	int		n,		// number of points
	int		dim,		// dimension
	int		n_col,		// number of colors
	bool		new_clust,	// generate new clusters.
	double		std_dev,	// standard deviation within clusters
	int		max_dim)	// maximum dimension of the flats
{
    const double CO_FLAG = 999;			// special flag value
    static KMpointArray control = NULL;	// control vectors

    if (control == NULL || new_clust) {		// need new cluster centers
	if (control != NULL) {			// clusters already exist
	    kmDeallocPts(control);		// get rid of them
	}
	control = kmAllocPts(n_col, dim);

	for (int c = 0; c < n_col; c++) {	// generate clusters
	    int n_dim = 1 + kmRanInt(max_dim);	// number of dimensions in flat
	    for (int d = 0; d < dim; d++) {	// generate side locations
						// prob. of picking next dim
	    	double Prob = ((double) n_dim)/((double) (dim-d));
		if (kmRan0() < Prob) {		// add this one to flat
		    control[c][d] = CO_FLAG;	// flag this entry
		    n_dim--;			// one fewer dim to fill
		}
		else {				// don't take this one
		    control[c][d] = kmRanUnif(-1,1);// random value in [-1,1]
		}
	    }
	}
    }

    int next = 0;				// next slot to fill
    for (int c = 0; c < n_col; c++) {		// generate clusters
	int pick = (n+c)/n_col;			// number of points to pick
	for (int i = 0; i < pick; i++) {
	    for (int d = 0; d < dim; d++) {
		if (control[c][d] == CO_FLAG)	// dimension on flat
        	    pa[next][d] = (KMcoord) kmRanUnif(-1,1);
		else				// dimension off flat
        	    pa[next][d] =
			(KMcoord) (std_dev*kmRanGauss() + control[c][d]);
	    }
	    next++;
	}
    }
}
Пример #7
0
					// standard constructor
KMfilterCenters::KMfilterCenters(int k, KMdata& p, double df)
    : KMcenters(k, p) {
    if (p.getKcTree() == NULL) {	// kc-tree not yet built?
      kmError("Building kc-tree", KMwarn);
      p.buildKcTree();			// build it now
    }
    sums	= kmAllocPts(kCtrs, getDim());
    sumSqs	= new double[kCtrs];
    weights	= new int[kCtrs];
    dists	= new double[kCtrs];
    currDist	= KM_HUGE;
    dampFactor	= df;
	currDBIndex = KM_HUGE;
	currXBIndex = KM_HUGE;
    invalidate();			// distortions are initially invalid
}
Пример #8
0
void kmClusGaussPts(		// clustered-Gaussian distribution
	KMpointArray	pa,		// point array (modified)
	int		n,		// number of points
	int		dim,		// dimension
	int		n_col,		// number of colors
	bool		new_clust,	// generate new clusters.
	double		std_dev,	// standard deviation within clusters
	double*		clus_sep)	// cluster separation (returned)
{
    if (cgClusters == NULL || new_clust) {// need new cluster centers
	if (cgClusters != NULL)		// clusters already exist
	    kmDeallocPts(cgClusters);	// get rid of them
	cgClusters = kmAllocPts(n_col, dim);
					// generate cluster center coords
	for (int i = 0; i < n_col; i++) {
	    for (int d = 0; d < dim; d++) {
		cgClusters[i][d] = (KMcoord) kmRanUnif(-1,1);
	    }
	}
    }

    double minDist = double(dim);	// minimum inter-center sq'd distance
    for (int i = 0; i < n_col; i++) {	// compute minimum separation
	for (int j = i+1; j < n_col; j++) {
	    double dist = kmDist(dim, cgClusters[i], cgClusters[j]);
	    if (dist < minDist) minDist = dist;
	}
    }
					// cluster separation
    if (clus_sep != NULL)
	*clus_sep = sqrt(minDist)/(sqrt(double(dim))*std_dev);

    for (int i = 0; i < n; i++) {
	int c = kmRanInt(n_col);	// generate cluster index
	for (int d = 0; d < dim; d++) {
          pa[i][d] = (KMcoord) (std_dev*kmRanGauss() + cgClusters[c][d]);
	}
    }
}
Пример #9
0
void KMcenters::resize(int k) {		// resize array (if needed)
    if (k == kCtrs) return;
    kCtrs = k;
    kmDeallocPts(ctrs);
    ctrs = kmAllocPts(kCtrs, pts->getDim());
}
Пример #10
0
    					// standard constructor
KMcenters::KMcenters(int k, KMdata& p)
    : kCtrs(k), pts(&p) {
    ctrs = kmAllocPts(kCtrs, p.getDim());
}
Пример #11
0
					// standard constructor
KMdata::KMdata(int d, int n) : dim(d), maxPts(n), nPts(n) {
    pts = kmAllocPts(n, d);
    kcTree = NULL;
}