diff dsp/segmentation/cluster_melt.c @ 480:175e51ae78eb

Untabify, indent, tidy
author Chris Cannam <cannam@all-day-breakfast.com>
date Fri, 31 May 2019 10:53:39 +0100
parents 7e8d1f26b098
children de5f557a270f
line wrap: on
line diff
--- a/dsp/segmentation/cluster_melt.c	Fri May 31 10:35:08 2019 +0100
+++ b/dsp/segmentation/cluster_melt.c	Fri May 31 10:53:39 2019 +0100
@@ -21,205 +21,192 @@
 #define DEFAULT_LIMIT 20;
 
 double kldist(double* a, double* b, int n) {
-	/* NB assume that all a[i], b[i] are non-negative
-	because a, b represent probability distributions */
-	double q, d;
-	int i;
-	
-	d = 0;
-	for (i = 0; i < n; i++)
-	{
-		q = (a[i] + b[i]) / 2.0;
-		if (q > 0)
-		{
-			if (a[i] > 0)
-				d += a[i] * log(a[i] / q);
-			if (b[i] > 0)
-				d += b[i] * log(b[i] / q);
-		}
-	}
-	return d;		
-}	
+    /* NB assume that all a[i], b[i] are non-negative
+       because a, b represent probability distributions */
+    double q, d;
+    int i;
+        
+    d = 0;
+    for (i = 0; i < n; i++) {
+        q = (a[i] + b[i]) / 2.0;
+        if (q > 0) {
+            if (a[i] > 0) {
+                d += a[i] * log(a[i] / q);
+            }
+            if (b[i] > 0) {
+                d += b[i] * log(b[i] / q);
+            }
+        }
+    }
+    return d;               
+}       
 
 void cluster_melt(double *h, int m, int n, double *Bsched, int t, int k, int l, int *c) {
-	double lambda, sum, beta, logsumexp, maxlp;
-	int i, j, a, b, b0, b1, limit, /* B, */ it, maxiter, maxiter0, maxiter1;
-	double** cl;	/* reference histograms for each cluster */
-	int** nc;	/* neighbour counts for each histogram */
-	double** lp;	/* soft assignment probs for each histogram */
-	int* oldc;	/* previous hard assignments (to check convergence) */
-	
-	/* NB h is passed as a 1d row major array */
-	
-	/* parameter values */
-	lambda = DEFAULT_LAMBDA;
-	if (l > 0)
-		limit = l;
-	else
-		limit = DEFAULT_LIMIT;		/* use default if no valid neighbourhood limit supplied */
-//	B = 2 * limit + 1;
-	maxiter0 = 20;	/* number of iterations at initial temperature */
-	maxiter1 = 5;	/* number of iterations at subsequent temperatures */
-	
-	/* allocate memory */	
-	cl = (double**) malloc(k*sizeof(double*));
-	for (i= 0; i < k; i++)
-		cl[i] = (double*) malloc(m*sizeof(double));
-	
-	nc = (int**) malloc(n*sizeof(int*));
-	for (i= 0; i < n; i++)
-		nc[i] = (int*) malloc(k*sizeof(int));
-	
-	lp = (double**) malloc(n*sizeof(double*));
-	for (i= 0; i < n; i++)
-		lp[i] = (double*) malloc(k*sizeof(double));
-	
-	oldc = (int*) malloc(n * sizeof(int));
-	
-	/* initialise */
-	for (i = 0; i < k; i++)
-	{
-		sum = 0;
-		for (j = 0; j < m; j++)
-		{
-			cl[i][j] = rand();	/* random initial reference histograms */
-			sum += cl[i][j] * cl[i][j];
-		}
-		sum = sqrt(sum);
-		for (j = 0; j < m; j++)
-		{
-			cl[i][j] /= sum;	/* normalise */
-		}
-	}	
-	//print_array(cl, k, m);
-	
-	for (i = 0; i < n; i++)
-		c[i] = 1;	/* initially assign all histograms to cluster 1 */
-	
-	for (a = 0; a < t; a++)
-	{
-		beta = Bsched[a];
-		
-		if (a == 0)
-			maxiter = maxiter0;
-		else
-			maxiter = maxiter1;
-		
-		for (it = 0; it < maxiter; it++)
-		{
-			//if (it == maxiter - 1)
-			//	mexPrintf("hasn't converged after %d iterations\n", maxiter);
-			
-			for (i = 0; i < n; i++)
-			{
-				/* save current hard assignments */
-				oldc[i] = c[i];
-				
-				/* calculate soft assignment logprobs for each cluster */
-				sum = 0;
-				for (j = 0; j < k; j++)
-				{
-					lp[i][ j] = -beta * kldist(cl[j], &h[i*m], m);
-					
-					/* update matching neighbour counts for this histogram, based on current hard assignments */
-					/* old version:
-					nc[i][j] = 0;	
-					if (i >= limit && i <= n - 1 - limit)
-					{
-							for (b = i - limit; b <= i + limit; b++)
-							{
-								if (c[b] == j+1)
-									nc[i][j]++;
-							}
-							nc[i][j] = B - nc[i][j];
-					}
-					*/
-					b0 = i - limit;
-					if (b0 < 0)
-						b0 = 0;
-					b1 = i + limit;
-					if (b1 >= n)
-						b1 = n - 1;
-					nc[i][j] = b1 - b0 + 1;		/* = B except at edges */
-					for (b = b0; b <= b1; b++)
-						if (c[b] == j+1)
-							nc[i][j]--;
-					
-					sum += exp(lp[i][j]);
-				}
-				
-				/* normalise responsibilities and add duration logprior */
-				logsumexp = log(sum);
-				for (j = 0; j < k; j++)
-					lp[i][j] -= logsumexp + lambda * nc[i][j];				
-			}
-			//print_array(lp, n, k);
-			/*
-			for (i = 0; i < n; i++)
-			{
-				 for (j = 0; j < k; j++)
-					 mexPrintf("%d ", nc[i][j]);
-				 mexPrintf("\n");
-			} 
-			*/
-			
-			
-			/* update the assignments now that we know the duration priors
-			based on the current assignments */
-			for (i = 0; i < n; i++)
-			{
-				maxlp = lp[i][0];
-				c[i] = 1;
-				for (j = 1; j < k; j++)
-					if (lp[i][j] > maxlp)
-					{
-						maxlp = lp[i][j];
-						c[i] = j+1;
-					}
-			}
-				
-			/* break if assignments haven't changed */
-			i = 0;
-			while (i < n && oldc[i] == c[i])
-				i++;
-			if (i == n)
-				break;
-			
-			/* update reference histograms now we know new responsibilities */
-			for (j = 0; j < k; j++)
-			{
-				for (b = 0; b < m; b++)
-				{
-					cl[j][b] = 0;
-					for (i = 0; i < n; i++)
-					{
-						cl[j][b] += exp(lp[i][j]) * h[i*m+b];
-					}	
-				}
-				
-				sum = 0;				
-				for (i = 0; i < n; i++)
-					sum += exp(lp[i][j]);
-				for (b = 0; b < m; b++)
-					cl[j][b] /= sum;	/* normalise */
-			}	
-			
-			//print_array(cl, k, m);
-			//mexPrintf("\n\n");
-		}
-	}
-		
-	/* free memory */
-	for (i = 0; i < k; i++)
-		free(cl[i]);
-	free(cl);
-	for (i = 0; i < n; i++)
-		free(nc[i]);
-	free(nc);
-	for (i = 0; i < n; i++)
-		free(lp[i]);
-	free(lp);
-	free(oldc);	
+    double lambda, sum, beta, logsumexp, maxlp;
+    int i, j, a, b, b0, b1, limit, /* B, */ it, maxiter, maxiter0, maxiter1;
+    double** cl;    /* reference histograms for each cluster */
+    int** nc;       /* neighbour counts for each histogram */
+    double** lp;    /* soft assignment probs for each histogram */
+    int* oldc;      /* previous hard assignments (to check convergence) */
+        
+    /* NB h is passed as a 1d row major array */
+        
+    /* parameter values */
+    lambda = DEFAULT_LAMBDA;
+    if (l > 0) {
+        limit = l;
+    } else {
+        limit = DEFAULT_LIMIT;          /* use default if no valid neighbourhood limit supplied */
+    }
+
+    maxiter0 = 20;  /* number of iterations at initial temperature */
+    maxiter1 = 5;   /* number of iterations at subsequent temperatures */
+        
+    /* allocate memory */   
+    cl = (double**) malloc(k*sizeof(double*));
+    for (i= 0; i < k; i++) {
+        cl[i] = (double*) malloc(m*sizeof(double));
+    }
+        
+    nc = (int**) malloc(n*sizeof(int*));
+    for (i= 0; i < n; i++) {
+        nc[i] = (int*) malloc(k*sizeof(int));
+    }
+        
+    lp = (double**) malloc(n*sizeof(double*));
+    for (i= 0; i < n; i++) {
+        lp[i] = (double*) malloc(k*sizeof(double));
+    }
+        
+    oldc = (int*) malloc(n * sizeof(int));
+        
+    /* initialise */
+    for (i = 0; i < k; i++) {
+        sum = 0;
+        for (j = 0; j < m; j++) {
+            cl[i][j] = rand();      /* random initial reference histograms */
+            sum += cl[i][j] * cl[i][j];
+        }
+        sum = sqrt(sum);
+        for (j = 0; j < m; j++) {
+            cl[i][j] /= sum;        /* normalise */
+        }
+    }       
+        
+    for (i = 0; i < n; i++) {
+        c[i] = 1;       /* initially assign all histograms to cluster 1 */
+    }
+        
+    for (a = 0; a < t; a++) {
+        
+        beta = Bsched[a];
+                
+        if (a == 0) {
+            maxiter = maxiter0;
+        } else {
+            maxiter = maxiter1;
+        }
+                
+        for (it = 0; it < maxiter; it++) {
+
+            //if (it == maxiter - 1)
+            //      mexPrintf("hasn't converged after %d iterations\n", maxiter);
+                        
+            for (i = 0; i < n; i++) {
+
+                /* save current hard assignments */
+                oldc[i] = c[i];
+                                
+                /* calculate soft assignment logprobs for each cluster */
+                sum = 0;
+
+                for (j = 0; j < k; j++) {
+
+                    lp[i][ j] = -beta * kldist(cl[j], &h[i*m], m);
+                                        
+                    /* update matching neighbour counts for this histogram, based on current hard assignments */
+
+                    b0 = i - limit;
+                    if (b0 < 0) {
+                        b0 = 0;
+                    }
+                    b1 = i + limit;
+                    if (b1 >= n) {
+                        b1 = n - 1;
+                    }
+                    nc[i][j] = b1 - b0 + 1;         /* = B except at edges */
+                    for (b = b0; b <= b1; b++) {
+                        if (c[b] == j+1) {
+                            nc[i][j]--;
+                        }
+                    }
+                                        
+                    sum += exp(lp[i][j]);
+                }
+                                
+                /* normalise responsibilities and add duration logprior */
+                logsumexp = log(sum);
+                for (j = 0; j < k; j++) {a
+                    lp[i][j] -= logsumexp + lambda * nc[i][j];
+                }
+            }
+                        
+            /* update the assignments now that we know the duration priors
+               based on the current assignments */
+            for (i = 0; i < n; i++) {
+                maxlp = lp[i][0];
+                c[i] = 1;
+                for (j = 1; j < k; j++) {
+                    if (lp[i][j] > maxlp) {
+                        maxlp = lp[i][j];
+                        c[i] = j+1;
+                    }
+                }
+            }
+                                
+            /* break if assignments haven't changed */
+            i = 0;
+            while (i < n && oldc[i] == c[i]) {
+                i++;
+            }
+            if (i == n) {
+                break;
+            }
+                        
+            /* update reference histograms now we know new responsibilities */
+            for (j = 0; j < k; j++) {
+                for (b = 0; b < m; b++) {
+                    cl[j][b] = 0;
+                    for (i = 0; i < n; i++) {
+                        cl[j][b] += exp(lp[i][j]) * h[i*m+b];
+                    }       
+                }
+                                
+                sum = 0;                                
+                for (i = 0; i < n; i++) {
+                    sum += exp(lp[i][j]);
+                }
+                for (b = 0; b < m; b++) {
+                    cl[j][b] /= sum;        /* normalise */
+                }
+            }       
+        }
+    }
+                
+    /* free memory */
+    for (i = 0; i < k; i++) {
+        free(cl[i]);
+    }
+    free(cl);
+    for (i = 0; i < n; i++) {
+        free(nc[i]);
+    }
+    free(nc);
+    for (i = 0; i < n; i++) {
+        free(lp[i]);
+    }
+    free(lp);
+    free(oldc);     
 }