[GRASS-SVN] r52178 - grass/trunk/raster/r.mapcalc
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jun 21 02:16:05 PDT 2012
Author: glynn
Date: 2012-06-21 02:16:04 -0700 (Thu, 21 Jun 2012)
New Revision: 52178
Added:
grass/trunk/raster/r.mapcalc/xnmax.c
grass/trunk/raster/r.mapcalc/xnmedian.c
grass/trunk/raster/r.mapcalc/xnmin.c
grass/trunk/raster/r.mapcalc/xnmode.c
Modified:
grass/trunk/raster/r.mapcalc/func_proto.h
grass/trunk/raster/r.mapcalc/function.c
grass/trunk/raster/r.mapcalc/r.mapcalc.html
grass/trunk/raster/r.mapcalc/r3.mapcalc.html
Log:
Add null-ignoring nmin, nmax, nmedian, nmode functions
Modified: grass/trunk/raster/r.mapcalc/func_proto.h
===================================================================
--- grass/trunk/raster/r.mapcalc/func_proto.h 2012-06-21 09:15:17 UTC (rev 52177)
+++ grass/trunk/raster/r.mapcalc/func_proto.h 2012-06-21 09:16:04 UTC (rev 52178)
@@ -78,12 +78,16 @@
extern func_t f_min;
extern func_t f_max;
+extern func_t f_nmin;
+extern func_t f_nmax;
extern args_t c_varop;
extern func_t f_median;
+extern func_t f_nmedian;
extern args_t c_median;
extern func_t f_mode;
+extern func_t f_nmode;
extern args_t c_mode;
extern func_t f_rand;
Modified: grass/trunk/raster/r.mapcalc/function.c
===================================================================
--- grass/trunk/raster/r.mapcalc/function.c 2012-06-21 09:15:17 UTC (rev 52177)
+++ grass/trunk/raster/r.mapcalc/function.c 2012-06-21 09:16:04 UTC (rev 52178)
@@ -68,6 +68,11 @@
{"median", c_varop, f_median},
{"mode", c_varop, f_mode},
+ {"nmax", c_varop, f_nmax},
+ {"nmin", c_varop, f_nmin},
+ {"nmedian", c_varop, f_nmedian},
+ {"nmode", c_varop, f_nmode},
+
{"graph", c_graph, f_graph},
{"rand", c_binop, f_rand},
Modified: grass/trunk/raster/r.mapcalc/r.mapcalc.html
===================================================================
--- grass/trunk/raster/r.mapcalc/r.mapcalc.html 2012-06-21 09:15:17 UTC (rev 52177)
+++ grass/trunk/raster/r.mapcalc/r.mapcalc.html 2012-06-21 09:16:04 UTC (rev 52178)
@@ -311,6 +311,10 @@
median(x,y[,z...]) median value of those listed *
min(x,y[,z...]) smallest value of those listed *
mode(x,y[,z...]) mode value of those listed *
+nmax(x,y[,z...]) largest value of those listed, excluding NULLs *
+nmedian(x,y[,z...]) median value of those listed, excluding NULLs *
+nmin(x,y[,z...]) smallest value of those listed, excluding NULLs *
+nmode(x,y[,z...]) mode value of those listed, excluding NULLs *
not(x) 1 if x is zero, 0 otherwise
pow(x,y) x to the power y *
rand(a,b) random value x : a <= x < b
Modified: grass/trunk/raster/r.mapcalc/r3.mapcalc.html
===================================================================
--- grass/trunk/raster/r.mapcalc/r3.mapcalc.html 2012-06-21 09:15:17 UTC (rev 52177)
+++ grass/trunk/raster/r.mapcalc/r3.mapcalc.html 2012-06-21 09:16:04 UTC (rev 52178)
@@ -215,6 +215,10 @@
median(x,y[,z...]) median value of those listed *
min(x,y[,z...]) smallest value of those listed *
mode(x,y[,z...]) mode value of those listed *
+nmax(x,y[,z...]) largest value of those listed, excluding NULLs *
+nmedian(x,y[,z...]) median value of those listed, excluding NULLs *
+nmin(x,y[,z...]) smallest value of those listed, excluding NULLs *
+nmode(x,y[,z...]) mode value of those listed, excluding NULLs *
not(x) 1 if x is zero, 0 otherwise
pow(x,y) x to the power y *
rand(a,b) random value x : a <= x < b
Added: grass/trunk/raster/r.mapcalc/xnmax.c
===================================================================
--- grass/trunk/raster/r.mapcalc/xnmax.c (rev 0)
+++ grass/trunk/raster/r.mapcalc/xnmax.c 2012-06-21 09:16:04 UTC (rev 52178)
@@ -0,0 +1,100 @@
+
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include "globals.h"
+#include "expression.h"
+#include "func_proto.h"
+
+/****************************************************************
+max(x0,x1,...,xn) returns maximum value
+****************************************************************/
+
+int f_nmax(int argc, const int *argt, void **args)
+{
+ int i, j;
+
+ if (argc < 1)
+ return E_ARG_LO;
+
+ for (i = 1; i <= argc; i++)
+ if (argt[i] != argt[0])
+ return E_ARG_TYPE;
+
+ switch (argt[0]) {
+ case CELL_TYPE:
+ {
+ CELL *res = args[0];
+ CELL **argz = (CELL **) args;
+
+ for (i = 0; i < columns; i++) {
+ int nul = 1;
+ CELL max;
+
+ for (j = 1; j <= argc; j++)
+ if (IS_NULL_C(&argz[j][i]))
+ continue;
+ else if (nul)
+ max = argz[j][i], nul = 0;
+ else if (max < argz[j][i])
+ max = argz[j][i], nul = 0;
+ if (nul)
+ SET_NULL_C(&res[i]);
+ else
+ res[i] = max;
+ }
+ return 0;
+ }
+ case FCELL_TYPE:
+ {
+ FCELL *res = args[0];
+ FCELL **argz = (FCELL **) args;
+
+ for (i = 0; i < columns; i++) {
+ int nul = 1;
+ FCELL max;
+
+ for (j = 1; j <= argc; j++)
+ if (IS_NULL_F(&argz[j][i]))
+ continue;
+ else if (nul)
+ max = argz[j][i], nul = 0;
+ else if (max < argz[j][i])
+ max = argz[j][i], nul = 0;
+ if (nul)
+ SET_NULL_F(&res[i]);
+ else
+ res[i] = max;
+ }
+
+ return 0;
+ }
+ case DCELL_TYPE:
+ {
+ DCELL *res = args[0];
+ DCELL **argz = (DCELL **) args;
+
+ for (i = 0; i < columns; i++) {
+ int nul = 1;
+ DCELL max;
+
+ for (j = 1; j <= argc; j++)
+ if (IS_NULL_D(&argz[j][i]))
+ continue;
+ else if (nul)
+ max = argz[j][i], nul = 0;
+ else if (max < argz[j][i])
+ max = argz[j][i], nul = 0;
+ if (nul)
+ SET_NULL_D(&res[i]);
+ else
+ res[i] = max;
+ }
+
+ return 0;
+ }
+ default:
+ return E_INV_TYPE;
+ }
+}
Added: grass/trunk/raster/r.mapcalc/xnmedian.c
===================================================================
--- grass/trunk/raster/r.mapcalc/xnmedian.c (rev 0)
+++ grass/trunk/raster/r.mapcalc/xnmedian.c 2012-06-21 09:16:04 UTC (rev 52178)
@@ -0,0 +1,155 @@
+
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include <grass/raster.h>
+#include "globals.h"
+#include "expression.h"
+#include "func_proto.h"
+
+/**********************************************************************
+median(x1,x2,..,xn)
+ return median of arguments
+**********************************************************************/
+
+static int icmp(const void *aa, const void *bb)
+{
+ const CELL *a = aa;
+ const CELL *b = bb;
+
+ return *a - *b;
+}
+
+static int fcmp(const void *aa, const void *bb)
+{
+ const FCELL *a = aa;
+ const FCELL *b = bb;
+
+ if (*a < *b)
+ return -1;
+ if (*a > *b)
+ return 1;
+ return 0;
+}
+
+static int dcmp(const void *aa, const void *bb)
+{
+ const DCELL *a = aa;
+ const DCELL *b = bb;
+
+ if (*a < *b)
+ return -1;
+ if (*a > *b)
+ return 1;
+ return 0;
+}
+
+int f_nmedian(int argc, const int *argt, void **args)
+{
+ static void *array;
+ static int alloc;
+ int size = argc * Rast_cell_size(argt[0]);
+ int i, j;
+
+ if (argc < 1)
+ return E_ARG_LO;
+
+ for (i = 1; i <= argc; i++)
+ if (argt[i] != argt[0])
+ return E_ARG_TYPE;
+
+ if (size > alloc) {
+ alloc = size;
+ array = G_realloc(array, size);
+ }
+
+ switch (argt[0]) {
+ case CELL_TYPE:
+ {
+ CELL *res = args[0];
+ CELL **argv = (CELL **) &args[1];
+ CELL *a = array;
+ CELL *a1 = &a[(argc - 1) / 2];
+ CELL *a2 = &a[argc / 2];
+
+ for (i = 0; i < columns; i++) {
+ int nv = 1;
+
+ for (j = 0; j < argc; j++) {
+ if (IS_NULL_C(&argv[j][i]))
+ continue;
+ a[j] = argv[j][i];
+ nv = 0;
+ }
+
+ if (nv)
+ SET_NULL_C(&res[i]);
+ else {
+ qsort(a, argc, sizeof(CELL), icmp);
+ res[i] = (*a1 + *a2) / 2;
+ }
+ }
+
+ return 0;
+ }
+ case FCELL_TYPE:
+ {
+ FCELL *res = args[0];
+ FCELL **argv = (FCELL **) &args[1];
+ FCELL *a = array;
+ FCELL *a1 = &a[(argc - 1) / 2];
+ FCELL *a2 = &a[argc / 2];
+
+ for (i = 0; i < columns; i++) {
+ int nv = 1;
+
+ for (j = 0; j < argc; j++) {
+ if (IS_NULL_F(&argv[j][i]))
+ continue;
+ a[j] = argv[j][i];
+ nv = 0;
+ }
+
+ if (nv)
+ SET_NULL_F(&res[i]);
+ else {
+ qsort(a, argc, sizeof(FCELL), fcmp);
+ res[i] = (*a1 + *a2) / 2;
+ }
+ }
+
+ return 0;
+ }
+ case DCELL_TYPE:
+ {
+ DCELL *res = args[0];
+ DCELL **argv = (DCELL **) &args[1];
+ DCELL *a = array;
+ DCELL *a1 = &a[(argc - 1) / 2];
+ DCELL *a2 = &a[argc / 2];
+
+ for (i = 0; i < columns; i++) {
+ int nv = 1;
+
+ for (j = 0; j < argc; j++) {
+ if (IS_NULL_D(&argv[j][i]))
+ continue;
+ a[j] = argv[j][i];
+ nv = 0;
+ }
+
+ if (nv)
+ SET_NULL_D(&res[i]);
+ else {
+ qsort(a, argc, sizeof(DCELL), dcmp);
+ res[i] = (*a1 + *a2) / 2;
+ }
+ }
+
+ return 0;
+ }
+ default:
+ return E_INV_TYPE;
+ }
+}
Added: grass/trunk/raster/r.mapcalc/xnmin.c
===================================================================
--- grass/trunk/raster/r.mapcalc/xnmin.c (rev 0)
+++ grass/trunk/raster/r.mapcalc/xnmin.c 2012-06-21 09:16:04 UTC (rev 52178)
@@ -0,0 +1,100 @@
+
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include "globals.h"
+#include "expression.h"
+#include "func_proto.h"
+
+/****************************************************************
+min(x0,x1,...,xn) returns minimum value
+****************************************************************/
+
+int f_nmin(int argc, const int *argt, void **args)
+{
+ int i, j;
+
+ if (argc < 1)
+ return E_ARG_LO;
+
+ for (i = 1; i <= argc; i++)
+ if (argt[i] != argt[0])
+ return E_ARG_TYPE;
+
+ switch (argt[0]) {
+ case CELL_TYPE:
+ {
+ CELL *res = args[0];
+ CELL **argz = (CELL **) args;
+
+ for (i = 0; i < columns; i++) {
+ int nul = 1;
+ CELL min;
+
+ for (j = 1; j <= argc; j++)
+ if (IS_NULL_C(&argz[j][i]))
+ continue;
+ else if (nul)
+ min = argz[j][i], nul = 0;
+ else if (min > argz[j][i])
+ min = argz[j][i], nul = 0;
+ if (nul)
+ SET_NULL_C(&res[i]);
+ else
+ res[i] = min;
+ }
+ return 0;
+ }
+ case FCELL_TYPE:
+ {
+ FCELL *res = args[0];
+ FCELL **argz = (FCELL **) args;
+
+ for (i = 0; i < columns; i++) {
+ int nul = 1;
+ FCELL min;
+
+ for (j = 1; j <= argc; j++)
+ if (IS_NULL_F(&argz[j][i]))
+ continue;
+ else if (nul)
+ min = argz[j][i], nul = 0;
+ else if (min > argz[j][i])
+ min = argz[j][i], nul = 0;
+ if (nul)
+ SET_NULL_F(&res[i]);
+ else
+ res[i] = min;
+ }
+
+ return 0;
+ }
+ case DCELL_TYPE:
+ {
+ DCELL *res = args[0];
+ DCELL **argz = (DCELL **) args;
+
+ for (i = 0; i < columns; i++) {
+ int nul = 1;
+ DCELL min;
+
+ for (j = 1; j <= argc; j++)
+ if (IS_NULL_D(&argz[j][i]))
+ continue;
+ else if (nul)
+ min = argz[j][i], nul = 0;
+ else if (min > argz[j][i])
+ min = argz[j][i], nul = 0;
+ if (nul)
+ SET_NULL_D(&res[i]);
+ else
+ res[i] = min;
+ }
+
+ return 0;
+ }
+ default:
+ return E_INV_TYPE;
+ }
+}
Added: grass/trunk/raster/r.mapcalc/xnmode.c
===================================================================
--- grass/trunk/raster/r.mapcalc/xnmode.c (rev 0)
+++ grass/trunk/raster/r.mapcalc/xnmode.c 2012-06-21 09:16:04 UTC (rev 52178)
@@ -0,0 +1,144 @@
+
+#include <stdlib.h>
+
+#include <grass/gis.h>
+#include <grass/raster.h>
+#include "globals.h"
+#include "expression.h"
+#include "func_proto.h"
+
+/**********************************************************************
+mode(x1,x2,..,xn)
+ return mode of arguments
+**********************************************************************/
+
+static int dcmp(const void *aa, const void *bb)
+{
+ const double *a = aa;
+ const double *b = bb;
+
+ if (*a < *b)
+ return -1;
+ if (*a > *b)
+ return 1;
+ return 0;
+}
+
+static double mode(double *value, int argc)
+{
+ double mode_v;
+ int mode_n = 0;
+ int i;
+
+ qsort(value, argc, sizeof(double), dcmp);
+
+ for (i = 0; i < argc;) {
+ int n = 1;
+ double v = value[i];
+
+ for (i++; i < argc; i++) {
+ if (value[i] != v)
+ break;
+ n++;
+ }
+
+ if (n < mode_n)
+ continue;
+
+ mode_v = v;
+ mode_n = n;
+ }
+
+ return mode_v;
+}
+
+int f_nmode(int argc, const int *argt, void **args)
+{
+ static double *value;
+ static int value_size;
+ int size = argc * sizeof(double);
+ int i, j;
+
+ if (argc < 1)
+ return E_ARG_LO;
+
+ for (i = 1; i <= argc; i++)
+ if (argt[i] != argt[0])
+ return E_ARG_TYPE;
+
+ if (size > value_size) {
+ value_size = size;
+ value = G_realloc(value, value_size);
+ }
+
+ switch (argt[argc]) {
+ case CELL_TYPE:
+ {
+ CELL *res = args[0];
+ CELL **argv = (CELL **) & args[1];
+
+ for (i = 0; i < columns; i++) {
+ int nv = 1;
+
+ for (j = 0; j < argc; j++) {
+ if (IS_NULL_C(&argv[j][i]))
+ continue;
+ value[j] = (double)argv[j][i];
+ nv = 0;
+ }
+
+ if (nv)
+ SET_NULL_C(&res[i]);
+ else
+ res[i] = (CELL) mode(value, argc);
+ }
+ return 0;
+ }
+ case FCELL_TYPE:
+ {
+ FCELL *res = args[0];
+ FCELL **argv = (FCELL **) & args[1];
+
+ for (i = 0; i < columns; i++) {
+ int nv = 1;
+
+ for (j = 0; j < argc; j++) {
+ if (IS_NULL_F(&argv[j][i]))
+ continue;
+ value[j] = (double)argv[j][i];
+ nv = 0;
+ }
+
+ if (nv)
+ SET_NULL_F(&res[i]);
+ else
+ res[i] = (FCELL) mode(value, argc);
+ }
+ return 0;
+ }
+ case DCELL_TYPE:
+ {
+ DCELL *res = args[0];
+ DCELL **argv = (DCELL **) & args[1];
+
+ for (i = 0; i < columns; i++) {
+ int nv = 1;
+
+ for (j = 0; j < argc; j++) {
+ if (IS_NULL_D(&argv[j][i]))
+ continue;
+ value[j] = (double)argv[j][i];
+ nv = 0;
+ }
+
+ if (nv)
+ SET_NULL_D(&res[i]);
+ else
+ res[i] = (DCELL) mode(value, argc);
+ }
+ return 0;
+ }
+ default:
+ return E_INV_TYPE;
+ }
+}
More information about the grass-commit
mailing list