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>