diff extra/NaN/src/histo_mex.cpp @ 5760:0b1b67486b3a octave-forge

support for data weigthening added
author schloegl
date Mon, 15 Jun 2009 08:32:06 +0000
parents c45fb9ded279
children 1dbdb1ab56ba
line wrap: on
line diff
--- a/extra/NaN/src/histo_mex.cpp	Mon Jun 15 05:31:54 2009 +0000
+++ b/extra/NaN/src/histo_mex.cpp	Mon Jun 15 08:32:06 2009 +0000
@@ -181,12 +181,15 @@
 {
 
     	const mwSize	*SZ;	    
-	char flag_rows = 0; 
-	char done = 0; 
-    	mwSize    	j, k, l;		// running indices 
+	char 		flag_rows = 0; 
+	char 		done = 0; 
+    	mwSize    	j, k;		// running indices 
+    	ssize_t		l;
+	const mxArray	*W = NULL; 
+    	double 		*w = NULL; 
 
 	// check for proper number of input and output arguments
-	if ((PInputCount <= 0) || (PInputCount > 2)) {
+	if ((PInputCount <= 0) || (PInputCount > 3)) {
 		mexPrintf("HISTO_MEX computes histogram from vector or column matrices\n\n");
 		mexPrintf("usage:\tHIS = histo_mex(Y)\n\t\tComputes histogram from each column\n");
 		mexPrintf("\t[HIS,tix] = histo_mex(Y,'rows')\n\t\tComputes row-wise histogram, tix is useful for data compression.\n\t\t Y = HIS.X(tix,:); \n\n");
@@ -199,15 +202,38 @@
 
 	// get 1st argument
 	if (mxIsComplex(PInputs[0]))
-		mexErrMsgTxt("First argument must be REAL/DOUBLE.");
+		mexErrMsgTxt("complex argument not supported (yet). ");
+	// TODO: support complex argument!	
 		
-	if ((PInputCount>1) && (mxIsChar(PInputs[1]))) {
+	if (PInputCount==1) 
+		; // histo_mex(X)
+	else if (mxIsChar(PInputs[1])) {
+		// histo_mex(X,'rows')
 		char *t = mxArrayToString(PInputs[1]);
 		flag_rows = !strcmp(t,"rows");
 		mxFree(t); 
+		// histo_mex(X,'rows',W)
+		if ((PInputCount>2) && mxIsDouble(PInputs[2])) 	W = PInputs[2]; 
 	} 
+		// histo_mex(X,W)
+	else if (mxIsDouble(PInputs[1])) {	
+		W = PInputs[1]; 
+	}
+	else 
+		mexErrMsgTxt("Weight vector must be REAL/DOUBLE.");
+
+	if (W != NULL) 	{
+	 	if (mxGetM(PInputs[0])==mxGetM(W) ) 
+	 		w = (double*)mxGetData(W);
+	 	else 
+			mexErrMsgTxt("number of rows in X and W do not match.");
+
+		for (k=0; (k<mxGetM(W)) && (w[k]>=0.0); k++); 
+		if (k<mxGetM(W)) 
+			mexWarnMsgTxt("weight vector contains also non-negative numbers or NaN.");
+	} 			
 		
-	// get size 
+	// get size
     	mwSize ND = mxGetNumberOfDimensions(PInputs[0]);	
     	// NN = mxGetNumberOfElements(PInputs[0]);
     	SZ = mxGetDimensions(PInputs[0]);		
@@ -225,6 +251,7 @@
 	
 	if (flag_rows || (SZ[1]==1)) { 
 
+		///***** SORT each column: initialize sorting algorithm  
 		int (*compar)(const void*, const void*);
 		size_t n; 
 		size_t *idx = NULL;
@@ -257,40 +284,42 @@
 			mexErrMsgTxt("unsupported input type"); 
 		}	
 		Sort.N = flag_rows ? SZ[1] : 1; 
+		qsort(idx,SZ[0],sizeof(*idx),compare);
 
-		qsort(idx,SZ[0],sizeof(*idx),compare);
+		// count number of different elements 	
 		n = SZ[0] ? 1 : 0; 
 		for (size_t k=1; k<SZ[0]; k++) {
 			if (compare(idx+k-1,idx+k)) n++;
 		}
+
 		uint64_t *tix = NULL; 
 		if (POutputCount>1) {
 			POutput[1] = mxCreateNumericMatrix(SZ[0], 1, mxUINT64_CLASS,mxREAL);
 			tix = (uint64_t*)mxGetData(POutput[1]);
 		}	
 
-		mxArray *H = mxCreateNumericMatrix(n, 1, mxUINT64_CLASS,mxREAL);
+		// fill HIS.H and HIS.X 
+		mxArray *H = mxCreateNumericMatrix(n, 1, mxDOUBLE_CLASS,mxREAL);
 		mxArray *X = mxCreateNumericMatrix(n, SZ[1], mxGetClassID(PInputs[0]),mxREAL); 
 		mxSetField(HIS,0,"H",H);
 		mxSetField(HIS,0,"X",X);
-		uint64_t *h = (uint64_t*)mxGetData(H);
+		double  *h = (double*)mxGetData(H);
 		uint8_t *x = (uint8_t*)mxGetData(X);
 		
-		for (j=0; j<SZ[1]; j++) {
-			memcpy(x+j*n*Sort.Size,Sort.Table+(idx[0]+j*Sort.Stride)*Sort.Size,Sort.Size);
-		}
-		h[0] = 1; 
-		l = 0;
-		if (tix) tix[idx[0]] = 1; 
-		for (size_t k=1; k<SZ[0]; k++) {
-			if (compare(&idx[k-1], &idx[k])) {
+		l = -1;
+		if (tix) tix[idx[0]] = 1;
+		for (size_t k=0; k<SZ[0]; k++) {
+			if ((k==0) || compare(&idx[k-1], &idx[k])) {
 				l++;
 				for (j=0; j<SZ[1]; j++) {
 					memcpy(x + (l+j*n)*Sort.Size, Sort.Table+(idx[k] + j*Sort.Stride)*Sort.Size, Sort.Size);
 				}
 			}
-			if (tix) tix[idx[k]] = l+1; 
-			h[l]++;	
+			if (tix) tix[idx[k]] = l+1;
+			if (w != NULL) 
+				h[l]+=w[idx[k]];
+			else 
+				h[l]+=1.0;	
 		}
 		mxFree(idx); 
 		done = 1;