Skip to content

Commit

Permalink
Modify seed algorithm to use process ID, and use a few randomly selec…
Browse files Browse the repository at this point in the history
…ted prime numbers that sort of look like words.
  • Loading branch information
mwtoews committed Feb 11, 2019
1 parent 19ee783 commit 2d258c0
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 14 deletions.
24 changes: 19 additions & 5 deletions liblwgeom/cunit/cu_algorithm.c
Expand Up @@ -1447,9 +1447,24 @@ static void test_point_density(void)

/* POLYGON */
geom = lwgeom_from_wkt("POLYGON((0 0,1 0,1 1,0 1,0 0))", LW_PARSER_CHECK_NONE);
mpt = lwgeom_to_points(geom, 100, 0); /* seed based on clock */
mpt = lwgeom_to_points(geom, 100, 0); /* Set a zero seed to base it on Unix time and process ID */
CU_ASSERT_EQUAL(mpt->ngeoms,100);

/* Run a second time with a zero seed to get a different multipoint sequence */
mpt2 = lwgeom_to_points(geom, 100, 0);
eq = 0;
for (i = 0; i < 100; i++)
{
pt = (LWPOINT*)mpt->geoms[i];
pt2 = (LWPOINT*)mpt2->geoms[i];
if (lwpoint_get_x(pt) == lwpoint_get_x(pt2) && lwpoint_get_y(pt) == lwpoint_get_y(pt2))
eq++;
}
CU_ASSERT_EQUAL(eq, 0);
lwmpoint_free(mpt);
lwmpoint_free(mpt2);
pt = NULL;
pt2 = NULL;

/* Set seed to get a deterministic sequence */
mpt = lwgeom_to_points(geom, 1000, 12345);
Expand Down Expand Up @@ -1486,14 +1501,13 @@ static void test_point_density(void)


/* Check if the 1000th point is the expected value.
* Note that if the PRNG is not portable, this test may fail
*/
* Note that if the RNG is not portable, this test may fail. */
pt = (LWPOINT*)mpt->geoms[999];
// ewkt = lwgeom_to_ewkt((LWGEOM*)pt);
// printf("%s\n", ewkt);
// lwfree(ewkt);
CU_ASSERT_DOUBLE_EQUAL(lwpoint_get_x(pt), 0.179235638039549, 1e-11);
CU_ASSERT_DOUBLE_EQUAL(lwpoint_get_y(pt), 0.531253711538885, 1e-11);
CU_ASSERT_DOUBLE_EQUAL(lwpoint_get_x(pt), 0.801167838758, 1e-11);
CU_ASSERT_DOUBLE_EQUAL(lwpoint_get_y(pt), 0.345281131175, 1e-11);
lwmpoint_free(mpt);
pt = NULL;

Expand Down
7 changes: 5 additions & 2 deletions liblwgeom/lwgeom_geos.c
Expand Up @@ -1498,7 +1498,10 @@ lwpoly_to_points(const LWPOLY* lwpoly, uint32_t npoints, int32_t seed)
/* Get an empty multi-point ready to return */
mpt = lwmpoint_construct_empty(srid, 0, 0);

/* Init random number generator. Zero means "no seed", so make one up. */
/* Initiate random number generator.
* Repeatable numbers are generated with seed values >= 1.
* When seed is zero and has not previously been set, it is based on
* Unix time (seconds) and process ID. */
lwrandom_set_seed( seed );

/* Now we fill in an array of cells, and then shuffle that array, */
Expand All @@ -1514,7 +1517,7 @@ lwpoly_to_points(const LWPOLY* lwpoly, uint32_t npoints, int32_t seed)
}
}

/* Fisher--Yates shuffle */
/* Fisher-Yates shuffle */
n = sample_height * sample_width;
if (n > 1)
{
Expand Down
21 changes: 15 additions & 6 deletions liblwgeom/lwrandom.c
Expand Up @@ -29,34 +29,43 @@
#include <stddef.h>
#include <time.h>

#ifdef _WIN32
#include <process.h>
#define getpid _getpid
#else
#include <unistd.h>
#endif

static unsigned char _lwrandom_seed_set = 0;
static int32_t _lwrandom_seed[3] = {0x330e, 0xabcd, 0x1234};

/*
* Set seed for a random number generator.
* A zero value uses clock as seed the first time only.
*/
* Repeatable numbers are generated with seed values >= 1.
* When seed is zero and has not previously been set, it is based on
* Unix time (seconds) and process ID. */
void
lwrandom_set_seed(int32_t seed)
{
if (seed == 0)
{
if (_lwrandom_seed_set == 0)
seed = ((unsigned int)time(NULL) * 1996) << 8;
seed = (unsigned int)time(NULL) + (unsigned int)getpid() - 0xbadd;
else
return;
}

_lwrandom_seed[1] = (seed % 2147483562) + 1; /* value between 1 and 2147483562 */
_lwrandom_seed[2] = (((seed + 6) >> 12) % 2147483398) + 1; /* value between 1 and 2147483398 */
/* s1 value between 1 and 2147483562 */
_lwrandom_seed[1] = (((int64_t)seed + 0xfeed) % 2147483562) + 1;
/* s2 value between 1 and 2147483398 */
_lwrandom_seed[2] = ((((int64_t)seed + 0xdefeb) << 5) % 2147483398) + 1;
_lwrandom_seed_set = 1;
}

/* for low-level external debugging */
void
_lwrandom_set_seeds(int32_t s1, int32_t s2)
{
/* _lwrandom_seed[0] not used */
_lwrandom_seed[1] = s1;
_lwrandom_seed[2] = s2;
_lwrandom_seed_set = 1;
Expand Down
2 changes: 1 addition & 1 deletion regress/core/tickets.sql
Expand Up @@ -1120,7 +1120,7 @@ FROM (SELECT 'POLYGON((0 0,1 0,1 1,0 1,0 0))'::geometry AS g) AS f;

-- #4304
SELECT '#4304', ST_Equals(ST_GeneratePoints(g, 1000, 12345), ST_GeneratePoints(g, 1000, 12345)),
ST_Distance(ST_GeometryN(ST_GeneratePoints(g, 1000, 12345), 1000), ST_GeometryFromText('POINT(0.1792356 0.5312537)')) < 1e-7
ST_Distance(ST_GeometryN(ST_GeneratePoints(g, 1000, 12345), 1000), ST_GeometryFromText('POINT(0.801167838758 0.345281131175)')) < 1e-11
FROM (SELECT 'POLYGON((0 0,1 0,1 1,0 1,0 0))'::geometry AS g) AS f;


Expand Down

0 comments on commit 2d258c0

Please sign in to comment.