Hi Glynn<br><br>It works perfectly in my (limited) testing, great! I am impressed.<br><br>I am not sure what you mean by "re-factor the common code", but I hope it will be possible to include this graph2() function as a standard as it makes, i.m.h.o. the function more user-friendly.<br>
<br>Cheers,<br><br>Paulo<br><br>p.s. I applied the patch to my GRASS7, can I also apply the patch to GRASS64?<div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Nov 19, 2012 at 4:46 AM, Glynn Clements <span dir="ltr"><<a href="mailto:glynn@gclements.plus.com" target="_blank">glynn@gclements.plus.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><br>
Paulo van Breugel wrote:<br>
<br>
> I am using the graph function in r.mapcalc. The input is the name of the<br>
> map to be converted and a string with XY values, like:<br>
><br>
> "newmap = graph(map, 1, x1,y1, x2,y2,... xi,yi)"<br>
<br>
</div>The second argument ("1") shouldn't be there.<br>
<div class="im"><br>
>  Often, X and Y values are available as separate columns or vectors. In<br>
> such cases, it would be much easier if X and Y values can be given as<br>
> separate vectors, e.g., something like:<br>
><br>
>  "newmap = graph(map, x=x1,x2,x3,x4,...xi, y=y1,y2,y3,y4,...,yi)"<br>
<br>
</div>That exact syntax (i.e. with "x=" and "y=" markers) isn't possible<br>
without fundamentally re-writing r.mapcalc.<br>
<br>
However, it would be possible to implement:<br>
<br>
        newmap = graph(map, x1,x2,x3,x4, y1,y2,y3,y4)<br>
<br>
This would boil down to cloning f_graph() in raster/r.mapcalc/xgraph.c<br>
with<br>
<br>
        #define X(j) (argz[2 + 2 * (j) + 0][i])<br>
        #define Y(j) (argz[2 + 2 * (j) + 1][i])<br>
<br>
changed to:<br>
<br>
        #define X(j) (argz[2 + (j) + 0][i])<br>
        #define Y(j) (argz[2 + (j) + n][i])<br>
<br>
In practice, we'd want to re-factor the common code.<br>
<br>
A (untested) patch to implement a graph2() function with the above<br>
syntax is attached.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Glynn Clements <<a href="mailto:glynn@gclements.plus.com">glynn@gclements.plus.com</a>><br>
<br>
</font></span><br>Index: raster/r.mapcalc/r.mapcalc.html<br>
===================================================================<br>
--- raster/r.mapcalc/r.mapcalc.html     (revision 53894)<br>
+++ raster/r.mapcalc/r.mapcalc.html     (working copy)<br>
@@ -298,6 +298,8 @@<br>
 exp(x,y)                x to the power y                                F<br>
 float(x)                convert x to single-precision floating point    F<br>
 graph(x,x1,y1[x2,y2..]) convert the x to a y based on points in a graph F<br>
+graph2(x,x1[,x2,..],y1[,y2..])<br>
+                        alternative form of graph()                     F<br>
 if                      decision options:                               *<br>
 if(x)                   1 if x not zero, 0 otherwise<br>
 if(x,a)                 a if x not zero, 0 otherwise<br>
Index: raster/r.mapcalc/function.c<br>
===================================================================<br>
--- raster/r.mapcalc/function.c (revision 53894)<br>
+++ raster/r.mapcalc/function.c (working copy)<br>
@@ -74,6 +74,7 @@<br>
     {"nmode", c_varop, f_nmode},<br>
<br>
     {"graph", c_graph, f_graph},<br>
+    {"graph2", c_graph, f_graph2},<br>
<br>
     {"rand", c_binop, f_rand},<br>
<br>
Index: raster/r.mapcalc/xgraph.c<br>
===================================================================<br>
--- raster/r.mapcalc/xgraph.c   (revision 53894)<br>
+++ raster/r.mapcalc/xgraph.c   (working copy)<br>
@@ -90,6 +90,9 @@<br>
<br>
            break;<br>
        }<br>
+#undef X<br>
+#undef Y<br>
+#undef x<br>
<br>
        continue;<br>
<br>
@@ -99,3 +102,79 @@<br>
<br>
     return 0;<br>
 }<br>
+<br>
+int f_graph2(int argc, const int *argt, void **args)<br>
+{<br>
+    DCELL **argz = (DCELL **) args;<br>
+    DCELL *res = argz[0];<br>
+    int n = (argc - 1) / 2;<br>
+    int i, j;<br>
+<br>
+    if (argc < 3)<br>
+       return E_ARG_LO;<br>
+<br>
+    if (argc % 2 == 0)<br>
+       return E_ARG_NUM;<br>
+<br>
+    if (argt[0] != DCELL_TYPE)<br>
+       return E_RES_TYPE;<br>
+<br>
+    for (i = 1; i <= argc; i++)<br>
+       if (argt[i] != DCELL_TYPE)<br>
+           return E_ARG_TYPE;<br>
+<br>
+    for (i = 0; i < columns; i++) {<br>
+#define X(j) (argz[2 + (j) + 0][i])<br>
+#define Y(j) (argz[2 + (j) + n][i])<br>
+#define x (argz[1][i])<br>
+<br>
+       if (IS_NULL_D(&x))<br>
+           goto null;<br>
+<br>
+       for (j = 0; j < n; j++)<br>
+           if (IS_NULL_D(&X(j)))<br>
+               goto null;<br>
+<br>
+       for (j = 0; j < n - 1; j++)<br>
+           if (X(j + 1) <= X(j))<br>
+               goto null;<br>
+<br>
+       if (x <= X(0)) {<br>
+           if (IS_NULL_D(&Y(0)))<br>
+               goto null;<br>
+           res[i] = Y(0);<br>
+           continue;<br>
+       }<br>
+<br>
+       if (x >= X(n - 1)) {<br>
+           if (IS_NULL_D(&Y(n - 1)))<br>
+               goto null;<br>
+           res[i] = Y(n - 1);<br>
+           continue;<br>
+       }<br>
+<br>
+       for (j = 0; j < n - 1; j++) {<br>
+           if (x > X(j + 1))<br>
+               continue;<br>
+<br>
+           if (IS_NULL_D(&Y(j)) || IS_NULL_D(&Y(j + 1)))<br>
+               goto null;<br>
+<br>
+           res[i] =<br>
+               Y(j) + (x - X(j)) * (Y(j + 1) - Y(j)) / (X(j + 1) - X(j));<br>
+<br>
+           break;<br>
+       }<br>
+#undef X<br>
+#undef Y<br>
+#undef x<br>
+<br>
+       continue;<br>
+<br>
+      null:<br>
+       SET_NULL_D(&res[i]);<br>
+    }<br>
+<br>
+    return 0;<br>
+}<br>
+<br>
Index: raster/r.mapcalc/r3.mapcalc.html<br>
===================================================================<br>
--- raster/r.mapcalc/r3.mapcalc.html    (revision 53894)<br>
+++ raster/r.mapcalc/r3.mapcalc.html    (working copy)<br>
@@ -202,6 +202,8 @@<br>
 exp(x,y)                x to the power y                                F<br>
 float(x)                convert x to single-precision floating point    F<br>
 graph(x,x1,y1[x2,y2..]) convert the x to a y based on points in a graph F<br>
+graph2(x,x1[,x2,..],y1[,y2..])<br>
+                        alternative form of graph()                     F<br>
 if                      decision options:                               *<br>
 if(x)                   1 if x not zero, 0 otherwise<br>
 if(x,a)                 a if x not zero, 0 otherwise<br>
Index: raster/r.mapcalc/func_proto.h<br>
===================================================================<br>
--- raster/r.mapcalc/func_proto.h       (revision 53894)<br>
+++ raster/r.mapcalc/func_proto.h       (working copy)<br>
@@ -74,6 +74,7 @@<br>
 extern args_t c_isnull;<br>
<br>
 extern func_t f_graph;<br>
+extern func_t f_graph2;<br>
 extern args_t c_graph;<br>
<br>
 extern func_t f_min;<br>
<br></blockquote></div><br></div>