changeset 5879:4a69daeb86e8 octave-forge

more efficient (smaller) code; improve docu
author schloegl
date Wed, 29 Jul 2009 23:14:03 +0000
parents 8c1dfb4ae32a
children 9465cbb32e5b
files extra/NaN/src/sumskipnan_mex.cpp
diffstat 1 files changed, 95 insertions(+), 131 deletions(-) [+]
line wrap: on
line diff
--- a/extra/NaN/src/sumskipnan_mex.cpp	Tue Jul 28 07:31:00 2009 +0000
+++ b/extra/NaN/src/sumskipnan_mex.cpp	Wed Jul 29 23:14:03 2009 +0000
@@ -19,17 +19,19 @@
 //
 //
 // sumskipnan: sums all non-NaN values
+// usage:
+//	[o,count,SSQ] = sumskipnan_mex(x,DIM,flag,W);
 //
 // Input:
-// - array to sum
-// - dimension to sum
-// - flag (is actually an output argument telling whether some NaN was observed)
-// - weight vector to compute weighted sum 
+// - x data array
+// - DIM (optional) dimension to sum
+// - flag (optional) is actually an output argument telling whether some NaN was observed
+// - W (optional) weight vector to compute weighted sum (default 1)
 //
 // Output:
-// - sums
-// - count of valid elements (optional)
-// - sums of squares (optional)
+// - o (weighted) sum along dimension DIM
+// - count of valid elements
+// - sums of squares
 //
 //
 //    $Id$
@@ -43,9 +45,6 @@
 #include <math.h>
 #include "mex.h"
 
-inline int __sumskipnan2__(double *data, size_t Ni, double *s, double *No, char *flag_anyISNAN);
-inline int __sumskipnan3__(double *data, size_t Ni, double *s, double *s2, double *No, char *flag_anyISNAN);
-
 inline int __sumskipnan2w__(double *data, size_t Ni, double *s, double *No, char *flag_anyISNAN, double *W);
 inline int __sumskipnan3w__(double *data, size_t Ni, double *s, double *s2, double *No, char *flag_anyISNAN, double *W);
 
@@ -154,10 +153,9 @@
 		POutput[2] = mxCreateNumericArray(ND2, SZ2, TYP, mxREAL);
         	LOutputSum2  = mxGetPr(POutput[2]);
     	}
-
 	mxFree(SZ2);
 
-	if (D1*D2*D3 < 1) 
+	if (D1*D2*D3<1) // zero size array
 		; 	// do nothing 
 	else if ((POutputCount <= 1) && !mxIsComplex(PInputs[0])) {
 		// OUTER LOOP: along dimensions > DIM
@@ -167,10 +165,7 @@
 			if (D1==1)  	
 			{
 				double count;
-				if (W) 
-					__sumskipnan2w__(LInput+ix1, D2, LOutputSum+ix0, &count, &flag_isNaN, W);
-				else 	
-					__sumskipnan2__(LInput+ix1, D2, LOutputSum+ix0, &count, &flag_isNaN);
+				__sumskipnan2w__(LInput+ix1, D2, LOutputSum+ix0, &count, &flag_isNaN, W);
  	       		}
 			else for (j=0; j<D2; j++) {
 				// minimize cache misses 
@@ -211,10 +206,7 @@
 			ix1 = ix0*D2;	// index for input 
 			if (D1==1)  	
 			{
-				if (W) 
-					__sumskipnan2w__(LInput+ix1, D2, LOutputSum+ix0, LOutputCount+ix0, &flag_isNaN, W);
-				else 	
-					__sumskipnan2__(LInput+ix1, D2, LOutputSum+ix0, LOutputCount+ix0, &flag_isNaN);
+				__sumskipnan2w__(LInput+ix1, D2, LOutputSum+ix0, LOutputCount+ix0, &flag_isNaN, W);
  	       		}
 			else for (j=0; j<D2; j++) {
 				// minimize cache misses 
@@ -257,11 +249,7 @@
 			ix1 = ix0*D2;	// index for input 
 			if (D1==1)  	
 			{
-				size_t count;
-				if (W) 
-					__sumskipnan3w__(LInput+ix1, D2, LOutputSum+ix0, LOutputSum2+ix0, LOutputCount+ix0, &flag_isNaN, W);
-				else 	
-					__sumskipnan3__(LInput+ix1, D2, LOutputSum+ix0, LOutputSum2+ix0, LOutputCount+ix0, &flag_isNaN);
+				__sumskipnan3w__(LInput+ix1, D2, LOutputSum+ix0, LOutputSum2+ix0, LOutputCount+ix0, &flag_isNaN, W);
  	       		}
 			else for (j=0; j<D2; j++) {
 				// minimize cache misses 
@@ -344,137 +332,113 @@
 
 
 #define stride 1 
-inline int __sumskipnan2__(double *data, size_t Ni, double *s, double *No, char *flag_anyISNAN)
+inline int __sumskipnan2w__(double *data, size_t Ni, double *s, double *No, char *flag_anyISNAN, double *W)
 {
-	register long double sum=0; 
-	register size_t count=0; 
-	register char   flag=0; 
+	long double sum=0; 
+	char   flag=0; 
 	// LOOP  along dimension DIM
 	
 	void *end = data + stride*Ni; 
-	do {
-		register double x = *data;
-        	if (!isnan(x))
-		{
-			count++; 
-			sum += x; 
-		}
+	if (W) {
+		// with weight vector 
+		register long double count = 0.0;
+		do {
+			register double x = *data;
+        		if (!isnan(x))
+			{
+				count += *W; 
+				sum   += *W*x; 
+			}
 #ifndef NO_FLAG
-		else 
-			flag = 1; 
-#endif
+			else 
+				flag = 1; 
+#endif	
 
-		data++;	// stride=1
-	}
-	while (data < end);
+			data++;	// stride=1
+			W++;
+		}
+		while (data < end);
+	        *No = count;
+	} else {
+		// w/o weight vector 
+		register size_t countI = 0;
+		do {
+			register double x = *data;
+        		if (!isnan(x))
+			{
+				countI++; 
+				sum += x; 
+			}
+#ifndef NO_FLAG
+			else 
+				flag = 1; 
+#endif
+			data++;	// stride=1
+		}
+		while (data < end);
+	        *No = (double)countI;
+	}	
 	
 #ifndef NO_FLAG
 	if (flag && (flag_anyISNAN != NULL)) *flag_anyISNAN = 1; 
 #endif
 	*s  = sum;
-        *No = (double)count;
 
 }
 
-inline int __sumskipnan3__(double *data, size_t Ni, double *s, double *s2, double *No, char *flag_anyISNAN)
+
+inline int __sumskipnan3w__(double *data, size_t Ni, double *s, double *s2, double *No, char *flag_anyISNAN, double *W)
 {
-	register long double sum=0; 
-	register long double msq=0; 
-	register size_t count=0; 
-	register char   flag=0; 
+	long double sum=0; 
+	long double msq=0; 
+	char   flag=0;
 	// LOOP  along dimension DIM
 	
 	void *end = data + stride*Ni; 
-	do {
-		register double x = *data;
-        	if (!isnan(x)) {
-			count++; 
-			sum += x; 
-			msq += x*x; 
-		}
+	if (W) {
+		// with weight vector 
+		register long double count = 0.0;
+		do {
+			register double x = *data;
+        		if (!isnan(x)) {
+				count += *W;
+				double t = *W*x; 
+				sum += t; 
+				msq += x*t; 
+			}
 #ifndef NO_FLAG
-		else 
-			flag = 1; 
+			else 
+				flag = 1; 
 #endif
-
-		data++;	// stride=1
+			data++;	// stride=1
+			W++;
+		}
+		while (data < end);
+	        *No = count;
+	} else {	
+		// w/o weight vector 
+		register size_t countI = 0;
+		do {
+			register double x = *data;
+        		if (!isnan(x)) {
+				countI++; 
+				sum += x; 
+				msq += x*x; 
+			}
+#ifndef NO_FLAG
+			else 
+				flag = 1; 
+#endif
+			data++;	// stride=1
+		}
+		while (data < end);
+	        *No = (double)countI;
 	}
-	while (data < end);
-
+	
 #ifndef NO_FLAG
 	if (flag && (flag_anyISNAN != NULL)) *flag_anyISNAN = 1; 
 #endif
 	*s  = sum;
 	*s2 = msq; 
-        *No = (double)count;
 }
 
-#define stride 1 
-inline int __sumskipnan2w__(double *data, size_t Ni, double *s, double *No, char *flag_anyISNAN, double *W)
-{
-	register long double sum=0; 
-	register long double count=0; 
-	register char   flag=0; 
-	// LOOP  along dimension DIM
-	
-	void *end = data + stride*Ni; 
-	do {
-		register double x = *data;
-        	if (!isnan(x))
-		{
-			count += *W; 
-			sum   += *W*x; 
-		}
-#ifndef NO_FLAG
-		else 
-			flag = 1; 
-#endif
-
-		data++;	// stride=1
-		W++;
-	}
-	while (data < end);
-	
-#ifndef NO_FLAG
-	if (flag && (flag_anyISNAN != NULL)) *flag_anyISNAN = 1; 
-#endif
-	*s  = sum;
-        *No = count;
-
-}
-
-inline int __sumskipnan3w__(double *data, size_t Ni, double *s, double *s2, double *No, char *flag_anyISNAN, double *W)
-{
-	register long double sum=0; 
-	register long double msq=0; 
-	register long double count=0; 
-	register char   flag=0; 
-	// LOOP  along dimension DIM
-	
-	void *end = data + stride*Ni; 
-	do {
-		register double x = *data;
-        	if (!isnan(x)) {
-			count += *W;
-			double t = *W*x; 
-			sum += t; 
-			msq += x*t; 
-		}
-#ifndef NO_FLAG
-		else 
-			flag = 1; 
-#endif
-
-		data++;	// stride=1
-		W++;
-	}
-	while (data < end);
-
-#ifndef NO_FLAG
-	if (flag && (flag_anyISNAN != NULL)) *flag_anyISNAN = 1; 
-#endif
-	*s  = sum;
-	*s2 = msq; 
-        *No = count;
-}
-