[GRASS-SVN] r61353 - grass/trunk/raster/r.mapcalc

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Jul 22 16:51:13 PDT 2014


Author: glynn
Date: 2014-07-22 16:51:12 -0700 (Tue, 22 Jul 2014)
New Revision: 61353

Modified:
   grass/trunk/raster/r.mapcalc/evaluate.c
   grass/trunk/raster/r.mapcalc/globals.h
   grass/trunk/raster/r.mapcalc/main.c
   grass/trunk/raster/r.mapcalc/map.c
   grass/trunk/raster/r.mapcalc/r.mapcalc.html
   grass/trunk/raster/r.mapcalc/r3.mapcalc.html
   grass/trunk/raster/r.mapcalc/xrand.c
Log:
Replace GRASS_RND_SEED with seed= option and -s flag
Use lib/gis PRNG
Store seed in history


Modified: grass/trunk/raster/r.mapcalc/evaluate.c
===================================================================
--- grass/trunk/raster/r.mapcalc/evaluate.c	2014-07-22 23:49:30 UTC (rev 61352)
+++ grass/trunk/raster/r.mapcalc/evaluate.c	2014-07-22 23:51:12 UTC (rev 61353)
@@ -254,26 +254,6 @@
     }
 }
 
-static void setup_rand(void)
-{
-    /* Read PRNG seed from environment variable if available */
-    /* GRASS_RND_SEED */
-    const char *random_seed = getenv("GRASS_RND_SEED");
-    long seed_value;
-
-    if (!random_seed)
-	return;
-
-    seed_value = atol(random_seed);
-    G_debug(3, "Read random seed from environment: %ld", seed_value);
-
-#if defined(HAVE_DRAND48)
-    srand48(seed_value);
-#else
-    srand((unsigned int)seed_value);
-#endif
-}
-
 void execute(expr_list * ee)
 {
     int verbose = isatty(2);
@@ -281,7 +261,6 @@
     int count, n;
 
     setup_region();
-    setup_rand();
 
     exprs = ee;
     G_add_error_handler(error_handler, NULL);

Modified: grass/trunk/raster/r.mapcalc/globals.h
===================================================================
--- grass/trunk/raster/r.mapcalc/globals.h	2014-07-22 23:49:30 UTC (rev 61352)
+++ grass/trunk/raster/r.mapcalc/globals.h	2014-07-22 23:51:12 UTC (rev 61353)
@@ -6,6 +6,8 @@
 extern volatile int floating_point_exception_occurred;
 extern int overflow_occurred;
 extern int overwrite_flag;
+extern long seed_value;
+extern long seeded;
 
 extern int current_depth, current_row;
 extern int depths, rows, columns;

Modified: grass/trunk/raster/r.mapcalc/main.c
===================================================================
--- grass/trunk/raster/r.mapcalc/main.c	2014-07-22 23:49:30 UTC (rev 61352)
+++ grass/trunk/raster/r.mapcalc/main.c	2014-07-22 23:51:12 UTC (rev 61353)
@@ -31,6 +31,9 @@
 volatile int floating_point_exception;
 volatile int floating_point_exception_occurred;
 
+long seed_value;
+long seeded;
+
 /****************************************************************************/
 
 static expr_list *result;
@@ -102,7 +105,8 @@
 int main(int argc, char **argv)
 {
     struct GModule *module;
-    struct Option *expr, *file;
+    struct Option *expr, *file, *seed;
+    struct Flag *random;
     int all_ok;
 
     G_gisinit(argv[0]);
@@ -126,6 +130,16 @@
     file->description = _("File containing expression(s) to evaluate");
     file->guisection = _("Expression");
 
+    seed = G_define_option();
+    seed->key = "seed";
+    seed->type = TYPE_INTEGER;
+    seed->required = NO;
+    seed->description = _("Seed for rand() function");
+
+    random = G_define_flag();
+    random->key = 's';
+    random->description = _("Generate random seed (result is non-deterministic)");
+
     if (argc == 1)
     {
 	char **p = G_malloc(3 * sizeof(char *));
@@ -145,6 +159,10 @@
 	G_fatal_error(_("%s= and %s= are mutually exclusive"),
 			expr->key, file->key);
 
+    if (seed->answer && random->answer)
+	G_fatal_error(_("%s= and -%c are mutually exclusive"),
+		      seed->key, random->key);
+
     if (expr->answer)
 	result = parse_string(expr->answer);
     else if (file->answer)
@@ -155,6 +173,19 @@
     if (!result)
 	G_fatal_error(_("parse error"));
 
+    if (seed->answer) {
+	seed_value = atol(seed->answer);
+	G_srand48(seed_value);
+	seeded = 1;
+	G_debug(3, "Read random seed from seed=: %ld", seed_value);
+    }
+
+    if (random->answer) {
+	seed_value = G_srand48_auto();
+	seeded = 1;
+	G_debug(3, "Generated random seed (-s): %ld", seed_value);
+    }
+
     pre_exec();
     execute(result);
     post_exec();

Modified: grass/trunk/raster/r.mapcalc/map.c
===================================================================
--- grass/trunk/raster/r.mapcalc/map.c	2014-07-22 23:49:30 UTC (rev 61352)
+++ grass/trunk/raster/r.mapcalc/map.c	2014-07-22 23:51:12 UTC (rev 61353)
@@ -740,6 +740,12 @@
 	len -= n;
     }
 
+    if (seeded) {
+	char buf[RECORD_LEN];
+	sprintf(buf, "random seed = %ld", seed_value);
+	Rast_append_history(&hist, buf);
+    }
+
     Rast_write_history(dst, &hist);
 
     G_free(expr);

Modified: grass/trunk/raster/r.mapcalc/r.mapcalc.html
===================================================================
--- grass/trunk/raster/r.mapcalc/r.mapcalc.html	2014-07-22 23:49:30 UTC (rev 61352)
+++ grass/trunk/raster/r.mapcalc/r.mapcalc.html	2014-07-22 23:51:12 UTC (rev 61353)
@@ -609,8 +609,20 @@
 (map) must be changed.
 
 <h3>Random number generator initialization</h3>
-<p>The environment variable GRASS_RND_SEED is read to initialize the
-random number generator.
+<p>The pseudo-random number generator used by the rand() function can
+be initialised to a specific value using the <em>seed</em> option. 
+This can be used to replicate a previous calculation.
+<p>Alternatively, it can be initialised from the system time and the
+PID using the <em>-r</em> flag. This should result in a different seed
+being used each time.
+<p>In either case, the seed will be written to the map's history, and
+can be seen using <em>r.info</em>.
+<p>If you want other people to be able to verify your results, it's
+preferable to use the <em>seed</em> option to supply a seed which is
+either specified in the script or generated from a determenistic process
+such as a pseudo-random number generator given an explicit seed.
+<p>Note that the rand() function will generate a fatal error if neither
+the <em>seed</em> option nor the <em>-s</em> flag are given.
 
 <h2>EXAMPLES</h2>
 To compute the average of two raster map layers

Modified: grass/trunk/raster/r.mapcalc/r3.mapcalc.html
===================================================================
--- grass/trunk/raster/r.mapcalc/r3.mapcalc.html	2014-07-22 23:49:30 UTC (rev 61352)
+++ grass/trunk/raster/r.mapcalc/r3.mapcalc.html	2014-07-22 23:51:12 UTC (rev 61353)
@@ -470,8 +470,20 @@
 See <em><a href="r.mask.html">r.mask</a></em> for details.
 
 <h3>Random number generator initialization</h3>
-<p>The environment variable GRASS_RND_SEED is read to initialize the
-random number generator.
+<p>The pseudo-random number generator used by the rand() function can
+be initialised to a specific value using the <em>seed</em> option. 
+This can be used to replicate a previous calculation.
+<p>Alternatively, it can be initialised from the system time and the
+PID using the <em>-r</em> flag. This should result in a different seed
+being used each time.
+<p>In either case, the seed will be written to the map's history, and
+can be seen using <em>r.info</em>.
+<p>If you want other people to be able to verify your results, it's
+preferable to use the <em>seed</em> option to supply a seed which is
+either specified in the script or generated from a determenistic process
+such as a pseudo-random number generator given an explicit seed.
+<p>Note that the rand() function will generate a fatal error if neither
+the <em>seed</em> option nor the <em>-s</em> flag are given.
 
 <h2>EXAMPLES</h2>
 To compute the average of two 3D grids

Modified: grass/trunk/raster/r.mapcalc/xrand.c
===================================================================
--- grass/trunk/raster/r.mapcalc/xrand.c	2014-07-22 23:49:30 UTC (rev 61352)
+++ grass/trunk/raster/r.mapcalc/xrand.c	2014-07-22 23:51:12 UTC (rev 61353)
@@ -12,11 +12,6 @@
 rand(lo,hi) random values between a and b
 ****************************************************************/
 
-#if !defined(HAVE_DRAND48)
-#define drand48() ((double)rand()/((double)RAND_MAX + 1))
-#define mrand48() ((long)rand())
-#endif
-
 int f_rand(int argc, const int *argt, void **args)
 {
     int i;
@@ -34,7 +29,7 @@
 	    CELL *arg2 = args[2];
 
 	    for (i = 0; i < columns; i++) {
-		unsigned long x = (unsigned long)mrand48();
+		unsigned long x = (unsigned long)G_mrand48();
 		int lo = arg1[i];
 		int hi = arg2[i];
 
@@ -55,7 +50,7 @@
 	    FCELL *arg2 = args[2];
 
 	    for (i = 0; i < columns; i++) {
-		double x = drand48();
+		double x = G_drand48();
 		FCELL lo = arg1[i];
 		FCELL hi = arg2[i];
 
@@ -76,7 +71,7 @@
 	    DCELL *arg2 = args[2];
 
 	    for (i = 0; i < columns; i++) {
-		double x = drand48();
+		double x = G_drand48();
 		DCELL lo = arg1[i];
 		DCELL hi = arg2[i];
 



More information about the grass-commit mailing list