Procházet zdrojové kódy

calclib: optimize nmedian

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@70686 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz před 8 roky
rodič
revize
10574bc7c3
1 změnil soubory, kde provedl 33 přidání a 18 odebrání
  1. 33 18
      lib/calc/xnmedian.c

+ 33 - 18
lib/calc/xnmedian.c

@@ -68,8 +68,8 @@ int f_nmedian(int argc, const int *argt, void **args)
 	    CELL *res = args[0];
 	    CELL **argv = (CELL **) &args[1];
 	    CELL *a = array;
-	    CELL *a1;
-	    CELL *a2;
+	    CELL a1;
+	    CELL *resc;
 
 	    for (i = 0; i < columns; i++) {
 		int n = 0;
@@ -80,13 +80,18 @@ int f_nmedian(int argc, const int *argt, void **args)
 		    a[n++] = argv[j][i];
 		}
 
+		resc = &res[i];
+
 		if (!n)
-		    SET_NULL_C(&res[i]);
+		    SET_NULL_C(resc);
 		else {
 		    qsort(a, n, sizeof(CELL), icmp);
-		    a1 = &a[(n - 1) / 2];
-		    a2 = &a[n / 2];
-		    res[i] = (*a1 + *a2) / 2;
+		    *resc = a[n / 2];
+		    if ((n & 1) == 0) {
+			a1 = a[(n - 1) / 2];
+			if (*resc != a1)
+			    *resc = (*resc + a1) / 2;
+		    }
 		}
 	    }
 
@@ -97,8 +102,8 @@ int f_nmedian(int argc, const int *argt, void **args)
 	    FCELL *res = args[0];
 	    FCELL **argv = (FCELL **) &args[1];
 	    FCELL *a = array;
-	    FCELL *a1;
-	    FCELL *a2;
+	    FCELL a1;
+	    FCELL *resc;
 
 	    for (i = 0; i < columns; i++) {
 		int n = 0;
@@ -109,13 +114,18 @@ int f_nmedian(int argc, const int *argt, void **args)
 		    a[n++] = argv[j][i];
 		}
 
+		resc = &res[i];
+
 		if (!n)
-		    SET_NULL_F(&res[i]);
+		    SET_NULL_F(resc);
 		else {
 		    qsort(a, n, sizeof(FCELL), fcmp);
-		    a1 = &a[(n - 1) / 2];
-		    a2 = &a[n / 2];
-		    res[i] = (*a1 + *a2) / 2;
+		    *resc = a[n / 2];
+		    if ((n & 1) == 0) {
+			a1 = a[(n - 1) / 2];
+			if (*resc != a1)
+			    *resc = (*resc + a1) / 2;
+		    }
 		}
 	    }
 
@@ -126,8 +136,8 @@ int f_nmedian(int argc, const int *argt, void **args)
 	    DCELL *res = args[0];
 	    DCELL **argv = (DCELL **) &args[1];
 	    DCELL *a = array;
-	    DCELL *a1;
-	    DCELL *a2;
+	    DCELL a1;
+	    DCELL *resc;
 
 	    for (i = 0; i < columns; i++) {
 		int n = 0;
@@ -138,13 +148,18 @@ int f_nmedian(int argc, const int *argt, void **args)
 		    a[n++] = argv[j][i];
 		}
 
+		resc = &res[i];
+
 		if (!n)
-		    SET_NULL_D(&res[i]);
+		    SET_NULL_D(resc);
 		else {
 		    qsort(a, n, sizeof(DCELL), dcmp);
-		    a1 = &a[(n - 1) / 2];
-		    a2 = &a[n / 2];
-		    res[i] = (*a1 + *a2) / 2;
+		    *resc = a[n / 2];
+		    if ((n & 1) == 0) {
+			a1 = a[(n - 1) / 2];
+			if (*resc != a1)
+			    *resc = (*resc + a1) / 2;
+		    }
 		}
 	    }