summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2015-02-13 16:18:10 +0100
committerLars-Dominik Braun <lars@6xq.net>2015-05-02 21:36:45 +0200
commitb9d887fc3cd3ae26c678bf35bc90c4f1d6b03888 (patch)
treeccbe25664282dd7915c55e73e25772b8801e9088
parenta46f55e0a2c9362b7b549ead851043c7b9e2791d (diff)
downloadpucket-b9d887fc3cd3ae26c678bf35bc90c4f1d6b03888.tar.gz
pucket-b9d887fc3cd3ae26c678bf35bc90c4f1d6b03888.tar.bz2
pucket-b9d887fc3cd3ae26c678bf35bc90c4f1d6b03888.zip
Unify prng use
Finally drop all isaac references, do not use system rng any more. Drop rng state from flam3_frame – it was not used anyway.
-rw-r--r--docstring.c1
-rw-r--r--flam3-animate.c7
-rw-r--r--flam3-genome.c72
-rw-r--r--flam3-render.c6
-rw-r--r--flam3.c408
-rw-r--r--flam3.h32
-rw-r--r--interpolation.c7
-rw-r--r--interpolation.h2
-rw-r--r--palettes.c27
-rw-r--r--parser.c15
-rw-r--r--parser.h4
-rw-r--r--private.h2
-rw-r--r--random.c63
-rw-r--r--random.h20
-rw-r--r--rect.c12
-rw-r--r--variations.c68
-rw-r--r--wscript2
-rw-r--r--xorshift.c44
-rw-r--r--xorshift.h14
19 files changed, 373 insertions, 433 deletions
diff --git a/docstring.c b/docstring.c
index b86a44d..d0b3920 100644
--- a/docstring.c
+++ b/docstring.c
@@ -64,7 +64,6 @@ static char *the_docstring1 =
"qs 1 quality scale, multiply quality of all frames by this\n"
"ss 1 size scale, multiply size (in pixels) of all frames by this\n"
"pixel_aspect 1.0 aspect ratio of pixels (width over height), eg 0.90909 for NTSC\n"
-"seed random integer seed for random numbers, defaults to time+pid\n"
"nthreads 0 number of threads to use for render. default auto-detects.\n"
"verbose 0 if non-zero then print progress meter on stderr\n"
"bits 33 also 32 or 64: sets bit-width of internal buffers (33 means 32-bit floating-point)\n"
diff --git a/flam3-animate.c b/flam3-animate.c
index eb9eb50..bdd5dfd 100644
--- a/flam3-animate.c
+++ b/flam3-animate.c
@@ -50,6 +50,7 @@ int main(int argc, char **argv) {
flam3_frame f;
flam3_img_comments fpc;
stat_struct stats,stats2;
+ randctx rc;
char badval_string[64];
char numiter_string[64];
@@ -62,9 +63,7 @@ int main(int argc, char **argv) {
exit(0);
}
- /* Init random number generators */
- flam3_init_frame(&f);
- flam3_srandom();
+ rand_seed(&rc);
/* Set the number of threads */
if (num_threads==0) {
@@ -111,7 +110,7 @@ int main(int argc, char **argv) {
exit(1);
}
- cps = flam3_parse_from_file(in, inf, flam3_defaults_on, &ncps);
+ cps = flam3_parse_from_file(in, inf, flam3_defaults_on, &ncps, &rc);
if (inf)
fclose(in);
if (NULL == cps) {
diff --git a/flam3-genome.c b/flam3-genome.c
index af2f8f6..a525a93 100644
--- a/flam3-genome.c
+++ b/flam3-genome.c
@@ -17,7 +17,6 @@
*/
#include "private.h"
-#include "isaacs.h"
#include "config.h"
int verbose;
@@ -60,7 +59,7 @@ void test_cp(flam3_genome *cp) {
cp->estimator_curve = 0.6;
}
-flam3_genome *string_to_cp(char *s, int *n) {
+flam3_genome *string_to_cp(char *s, int *n, randctx * const rc) {
flam3_genome *cp;
FILE *fp;
@@ -69,7 +68,7 @@ flam3_genome *string_to_cp(char *s, int *n) {
perror(s);
exit(1);
}
- cp = flam3_parse_from_file(fp, s, flam3_defaults_on, n);
+ cp = flam3_parse_from_file(fp, s, flam3_defaults_on, n, rc);
if (NULL == cp) {
fprintf(stderr, "could not read genome from %s.\n", s);
exit(1);
@@ -370,7 +369,7 @@ void truncate_variations(flam3_genome *g, int max_vars, char *action) {
}
static double golden_bit(randctx *rc) {
- return flam3_random_isaac_bit(rc)?0.38196:0.61804;
+ return rand_bool(rc)?0.38196:0.61804;
}
int
@@ -418,6 +417,7 @@ main(argc, argv)
int num_threads = 1;
flam3_genome *cp;
int ncp;
+ randctx rc;
int ivars[max_specified_vars];
int novars[max_specified_vars];
@@ -452,9 +452,7 @@ main(argc, argv)
exit(0);
}
- /* Init random number generators */
- flam3_init_frame(&f);
- flam3_srandom();
+ rand_seed(&rc);
//f.temporal_filter_radius = 0.0;
f.bits = bits;
@@ -579,7 +577,7 @@ main(argc, argv)
if (getenv("template")) {
char *tf = getenv("template");
- templ = string_to_cp(tf, &ncp);
+ templ = string_to_cp(tf, &ncp, &rc);
if (1 < ncp) {
fprintf(stderr, "more than one control point in template, "
"ignoring all but first.\n");
@@ -594,7 +592,7 @@ main(argc, argv)
if (clone_all) {
- cp = string_to_cp(clone_all, &ncp);
+ cp = string_to_cp(clone_all, &ncp, &rc);
printf("<clone_all version=\"FLAM3-%s\">\n", flam3_version());
for (i = 0; i < ncp; i++) {
@@ -612,7 +610,7 @@ main(argc, argv)
int first_frame,last_frame;
int ftime,iscp;
double stagger = argf("stagger", 0.0);
- cp = string_to_cp(animate, &ncp);
+ cp = string_to_cp(animate, &ncp, &rc);
for (i = 0; i < ncp; i++) {
@@ -678,7 +676,7 @@ main(argc, argv)
exit(1);
}
- cp = string_to_cp(sequence, &ncp);
+ cp = string_to_cp(sequence, &ncp, &rc);
if (enclosed) printf("<sequence version=\"FLAM3-%s\">\n", flam3_version());
spread = 1.0/nframes;
@@ -742,7 +740,7 @@ main(argc, argv)
blend = frame/(double)nframes;
spread = 1.0/nframes;
- cp = string_to_cp(fname, &ncp);
+ cp = string_to_cp(fname, &ncp, &rc);
if (enclosed) printf("<pick version=\"FLAM3-%s\">\n", flam3_version());
if (rotate) {
@@ -775,7 +773,7 @@ main(argc, argv)
if (strip) {
- cp = string_to_cp(strip, &ncp);
+ cp = string_to_cp(strip, &ncp, &rc);
if (enclosed) printf("<pick version=\"FLAM3-%s\">\n", flam3_version());
@@ -821,14 +819,14 @@ main(argc, argv)
if (clone) {
- parent0 = string_to_cp(clone, &parent0_n);
+ parent0 = string_to_cp(clone, &parent0_n, &rc);
/* Action is 'clone' with trunc_vars concat */
sprintf(action,"clone");
if (getenv("clone_action"))
sprintf(action,"clone %s", getenv("clone_action"));
- flam3_copy(&selp0, &(parent0[random()%parent0_n]));
+ flam3_copy(&selp0, &(parent0[rand_mod(&rc,parent0_n)]));
flam3_copy(&cp_save, &selp0);
aselp0 = &selp0;
aselp1 = NULL;
@@ -851,8 +849,8 @@ main(argc, argv)
if (mutate) {
int mutmeth;
- parent0 = string_to_cp(mutate, &parent0_n);
- flam3_copy(&selp0, &(parent0[(xorshift_step(&f.rc))%parent0_n]));
+ parent0 = string_to_cp(mutate, &parent0_n, &rc);
+ flam3_copy(&selp0, &(parent0[rand_mod(&rc, parent0_n)]));
flam3_copy(&cp_orig, &selp0);
aselp0 = &selp0;
aselp1 = NULL;
@@ -878,7 +876,7 @@ main(argc, argv)
mutmeth = MUTATE_NOT_SPECIFIED;
}
- flam3_mutate(&cp_orig, mutmeth, ivars, num_ivars, sym, speed, &f.rc, action);
+ flam3_mutate(&cp_orig, mutmeth, ivars, num_ivars, sym, speed, &rc, action);
/* Scan string returned for 'mutate color' */
if ( strstr(action,"mutate color") )
@@ -894,11 +892,11 @@ main(argc, argv)
int i0, i1;
int crossmeth;
- parent0 = string_to_cp(cross0, &parent0_n);
- parent1 = string_to_cp(cross1, &parent1_n);
+ parent0 = string_to_cp(cross0, &parent0_n, &rc);
+ parent1 = string_to_cp(cross1, &parent1_n, &rc);
- i0 = (xorshift_step(&f.rc))%parent0_n;
- i1 = (xorshift_step(&f.rc))%parent1_n;
+ i0 = rand_mod(&rc, parent0_n);
+ i1 = rand_mod(&rc, parent1_n);
flam3_copy(&selp0, &(parent0[i0]));
flam3_copy(&selp1, &(parent1[i1]));
@@ -919,7 +917,7 @@ main(argc, argv)
crossmeth = CROSS_NOT_SPECIFIED;
}
- flam3_cross(&parent0[i0], &parent1[i1], &cp_orig, crossmeth, &f.rc, action);
+ flam3_cross(&parent0[i0], &parent1[i1], &cp_orig, crossmeth, &rc, action);
if (parent0[i0].flame_name[0] || parent1[i1].flame_name[0]) {
snprintf(cp_orig.flame_name, flam3_name_len, "%d of %s x %s",
@@ -929,7 +927,7 @@ main(argc, argv)
} else {
sprintf(action,"random");
random_mode=1;
- flam3_random(&cp_orig, ivars, num_ivars, sym, 0);
+ flam3_random(&cp_orig, ivars, num_ivars, sym, 0, &rc);
aselp0 = NULL;
@@ -937,26 +935,26 @@ main(argc, argv)
}
/* Adjust bounding box half the time */
- if (flam3_random_bit(&f.rc) || random_mode) {
+ if (rand_bool(&rc) || random_mode) {
double bmin[2], bmax[2];
- flam3_estimate_bounding_box(&cp_orig, 0.01, 100000, bmin, bmax, &f.rc);
- if (flam3_random_isaac_01(&f.rc) < 0.3) {
+ flam3_estimate_bounding_box(&cp_orig, 0.01, 100000, bmin, bmax, &rc);
+ if (rand_d01(&rc) < 0.3) {
cp_orig.center[0] = (bmin[0] + bmax[0]) / 2.0;
cp_orig.center[1] = (bmin[1] + bmax[1]) / 2.0;
add_to_action(action," recentered");
} else {
double mix0, mix1;
- if (flam3_random_isaac_bit(&f.rc)) {
- mix0 = golden_bit(&f.rc) + flam3_random_isaac_11(&f.rc)/5;
- mix1 = golden_bit(&f.rc);
+ if (rand_bool(&rc)) {
+ mix0 = golden_bit(&rc) + rand_d11(&rc)/5;
+ mix1 = golden_bit(&rc);
add_to_action(action," reframed0");
- } else if (flam3_random_isaac_bit(&f.rc)) {
- mix0 = golden_bit(&f.rc);
- mix1 = golden_bit(&f.rc) + flam3_random_isaac_11(&f.rc)/5;
+ } else if (rand_bool(&rc)) {
+ mix0 = golden_bit(&rc);
+ mix1 = golden_bit(&rc) + rand_d11(&rc)/5;
add_to_action(action," reframed1");
} else {
- mix0 = golden_bit(&f.rc) + flam3_random_isaac_11(&f.rc)/5;
- mix1 = golden_bit(&f.rc) + flam3_random_isaac_11(&f.rc)/5;
+ mix0 = golden_bit(&rc) + rand_d11(&rc)/5;
+ mix1 = golden_bit(&rc) + rand_d11(&rc)/5;
add_to_action(action," reframed2");
}
cp_orig.center[0] = mix0 * bmin[0] + (1-mix0)*bmax[0];
@@ -969,11 +967,11 @@ main(argc, argv)
truncate_variations(&cp_orig, 5, action);
- if (!did_color && random()&1) {
+ if (!did_color && rand_bool(&rc)) {
if (debug)
fprintf(stderr,"improving colors...\n");
- flam3_improve_colors(&cp_orig, 100, 0, 10);
+ flam3_improve_colors(&cp_orig, 100, 0, 10, &rc);
//strcat(action," improved colors");
add_to_action(action," improved colors");
}
diff --git a/flam3-render.c b/flam3-render.c
index 8f1084d..fccec1d 100644
--- a/flam3-render.c
+++ b/flam3-render.c
@@ -60,6 +60,7 @@ int main(int argc, char **argv) {
char numiter_string[64];
char badval_string[64];
char rtime_string[64];
+ randctx rc;
if (1 != argc) {
docstring();
@@ -67,8 +68,7 @@ int main(int argc, char **argv) {
}
/* Init random number generators */
- flam3_init_frame(&f);
- flam3_srandom();
+ rand_seed(&rc);
/* Set the number of threads */
if (num_threads==0) {
@@ -107,7 +107,7 @@ int main(int argc, char **argv) {
exit(1);
}
- cps = flam3_parse_from_file(in, inf, flam3_defaults_on, &ncps);
+ cps = flam3_parse_from_file(in, inf, flam3_defaults_on, &ncps, &rc);
if (NULL == cps) {
fprintf(stderr,"error reading genomes from file\n");
exit(1);
diff --git a/flam3.c b/flam3.c
index 35ee6b4..a23131f 100644
--- a/flam3.c
+++ b/flam3.c
@@ -24,7 +24,7 @@
#include "parser.h"
#include "filters.h"
#include "palettes.h"
-#include "xorshift.h"
+#include "random.h"
#include <limits.h>
#include <locale.h>
#include <math.h>
@@ -46,9 +46,6 @@ char *flam3_version() {
#define CHOOSE_XFORM_GRAIN 16384
#define CHOOSE_XFORM_GRAIN_M1 16383
-#define random_distrib(v) ((v)[random()%vlen(v)])
-
-
unsigned short *flam3_create_xform_distrib(flam3_genome *cp) {
/* Xform distrib is created in this function */
@@ -202,9 +199,9 @@ int flam3_iterate(flam3_genome *cp, int n, int fuse, const double4 in, double4 *
// fn = xform_distrib[ lastxf*CHOOSE_XFORM_GRAIN + (((unsigned)irand(rc)) % CHOOSE_XFORM_GRAIN)];
if (cp->chaos_enable)
- fn = xform_distrib[ lastxf*CHOOSE_XFORM_GRAIN + (xorshift_step(rc) & CHOOSE_XFORM_GRAIN_M1)];
+ fn = xform_distrib[ lastxf*CHOOSE_XFORM_GRAIN + (rand_u64(rc) & CHOOSE_XFORM_GRAIN_M1)];
else
- fn = xform_distrib[ xorshift_step(rc) & CHOOSE_XFORM_GRAIN_M1 ];
+ fn = xform_distrib[ rand_u64(rc) & CHOOSE_XFORM_GRAIN_M1 ];
if (apply_xform(cp, fn, p, &q, rc)>0) {
consec ++;
@@ -225,7 +222,7 @@ int flam3_iterate(flam3_genome *cp, int n, int fuse, const double4 in, double4 *
if (cp->final_xform_enable == 1) {
if (cp->xform[cp->final_xform_index].opacity==1 ||
- flam3_random_isaac_01(rc)<cp->xform[cp->final_xform_index].opacity) {
+ rand_d01(rc)<cp->xform[cp->final_xform_index].opacity) {
apply_xform(cp, cp->final_xform_index, p, &q, rc);
/* Keep the opacity from the original xform */
q = (double4) { q[0], q[1], q[2], p[3] };
@@ -1238,7 +1235,7 @@ def:
return (nthreads);
}
-flam3_genome *flam3_parse_xml2(char *xmldata, char *xmlfilename, int default_flag, int *ncps) {
+flam3_genome *flam3_parse_xml2(char *xmldata, char *xmlfilename, int default_flag, int *ncps, randctx * const rc) {
xmlDocPtr doc; /* Parsed XML document tree */
xmlNode *rootnode;
@@ -1279,7 +1276,7 @@ flam3_genome *flam3_parse_xml2(char *xmldata, char *xmlfilename, int default_fla
bn = basename(xmlfilename);
/* Have to use &loc_all_cp since the memory gets allocated in scan_for_flame_nodes */
- scan_for_flame_nodes(rootnode, bn, default_flag,&loc_all_cp,&loc_all_ncps);
+ scan_for_flame_nodes(rootnode, bn, default_flag,&loc_all_cp,&loc_all_ncps, rc);
// restore locale
if (locale != NULL) {
@@ -1339,7 +1336,7 @@ flam3_genome *flam3_parse_xml2(char *xmldata, char *xmlfilename, int default_fla
return loc_all_cp;
}
-flam3_genome * flam3_parse_from_file(FILE *f, char *fname, int default_flag, int *ncps) {
+flam3_genome * flam3_parse_from_file(FILE *f, char *fname, int default_flag, int *ncps, randctx * const rc) {
int i, c, slen = 5000;
char *s, *snew;
flam3_genome *ret;
@@ -1368,9 +1365,9 @@ flam3_genome * flam3_parse_from_file(FILE *f, char *fname, int default_flag, int
/* Parse the XML string */
if (fname)
- ret = flam3_parse_xml2(s, fname, default_flag, ncps);
+ ret = flam3_parse_xml2(s, fname, default_flag, ncps, rc);
else
- ret = flam3_parse_xml2(s, "stdin", default_flag, ncps);
+ ret = flam3_parse_xml2(s, "stdin", default_flag, ncps, rc);
free(s);
@@ -2266,48 +2263,6 @@ void flam3_print_xform(FILE *f, flam3_xform *x, int final_flag, int numstd, doub
fprintf(f, "/>\n");
}
-
-/* returns a uniform variable from 0 to 1 */
-double flam3_random01() {
- return (random() & 0xfffffff) / (double) 0xfffffff;
-}
-
-double flam3_random11() {
- return ((random() & 0xfffffff) - 0x7ffffff) / (double) 0x7ffffff;
-}
-
-/* This function must be called prior to rendering a frame */
-void flam3_init_frame(flam3_frame *f) {
- xorshift_seed (&f->rc);
-}
-
-/* returns uniform variable from ISAAC rng */
-double flam3_random_isaac_01(randctx *ct) {
- return ((uint32_t) xorshift_step (ct) & 0xfffffff) / (double) 0xfffffff;
-}
-
-double flam3_random_isaac_11(randctx *ct) {
- return (((uint32_t) xorshift_step(ct) & 0xfffffff) - 0x7ffffff) / (double) 0x7ffffff;
-}
-
-int flam3_random_bit() {
- /* might not be threadsafe */
- static int n = 0;
- static int l;
- if (0 == n) {
- l = random();
- n = 20;
- } else {
- l = l >> 1;
- n--;
- }
- return l & 1;
-}
-
-int flam3_random_isaac_bit(randctx *ct) {
- return xorshift_step(ct) & 1;
-}
-
static double round6(double x) {
x *= 1e6;
if (x < 0) x -= 1.0;
@@ -2320,7 +2275,7 @@ static double round6(double x) {
sym=-1 means bilateral (reflection)
sym=-2 or less means rotational and reflective
*/
-void flam3_add_symmetry(flam3_genome *cp, int sym) {
+void flam3_add_symmetry(flam3_genome *cp, int sym, randctx * const rc) {
int i, j, k;
double a;
int result = 0;
@@ -2334,12 +2289,12 @@ void flam3_add_symmetry(flam3_genome *cp, int sym) {
3, 3,
4, 4,
};
- if (random()&1) {
- sym = random_distrib(sym_distrib);
- } else if (random()&31) {
- sym = (random()%13)-6;
+ if (rand_bool(rc)) {
+ sym = rand_distrib(rc, sym_distrib);
+ } else if (rand_mod(rc, 32)) {
+ sym = rand_mod(rc, 13)-6;
} else {
- sym = (random()%51)-25;
+ sym = rand_mod(rc, 51)-25;
}
}
@@ -2428,7 +2383,7 @@ void flam3_cross(flam3_genome *cp0, flam3_genome *cp1, flam3_genome *out, int cr
if (cross_mode == CROSS_NOT_SPECIFIED) {
- double s = flam3_random_isaac_01(rc);
+ double s = rand_d01(rc);
if (s < 0.1)
cross_mode = CROSS_UNION;
@@ -2475,7 +2430,7 @@ void flam3_cross(flam3_genome *cp0, flam3_genome *cp1, flam3_genome *out, int cr
/* linearly interpolate somewhere between the two */
flam3_genome parents[2];
- double t = flam3_random_isaac_01(rc);
+ double t = rand_d01(rc);
memset(parents, 0, 2*sizeof(flam3_genome));
@@ -2510,7 +2465,7 @@ void flam3_cross(flam3_genome *cp0, flam3_genome *cp1, flam3_genome *out, int cr
trystr[0] = 0;
got0 = got1 = 0;
- rb = flam3_random_isaac_bit(rc);
+ rb = rand_bool(rc);
sprintf(ministr,"%d:",rb);
strcat(trystr,ministr);
@@ -2525,7 +2480,7 @@ void flam3_cross(flam3_genome *cp0, flam3_genome *cp1, flam3_genome *out, int cr
/* Only replace non-final xforms */
for (i = 0; i < out->num_xforms - out->final_xform_enable; i++) {
- rb = flam3_random_isaac_bit(rc);
+ rb = rand_bool(rc);
/* Replace xform if bit is 1 */
if (rb==1) {
@@ -2578,10 +2533,10 @@ void flam3_cross(flam3_genome *cp0, flam3_genome *cp1, flam3_genome *out, int cr
}
/* Potentially genetically cross the two colormaps together */
- if (flam3_random_isaac_01(rc) < 0.4) {
+ if (rand_d01(rc) < 0.4) {
/* Select the starting parent */
- int startParent=flam3_random_isaac_bit(rc);
+ int startParent=rand_bool(rc);
int ci;
add_to_action(action," cmap_cross");
@@ -2590,7 +2545,7 @@ void flam3_cross(flam3_genome *cp0, flam3_genome *cp1, flam3_genome *out, int cr
/* Loop over the entries, switching to the other parent 1% of the time */
for (ci=0;ci<256;ci++) {
- if (flam3_random_isaac_01(rc)<.01) {
+ if (rand_d01(rc)<.01) {
startParent = 1-startParent;
sprintf(ministr," %d",ci);
add_to_action(action,ministr);
@@ -2612,7 +2567,7 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
/* If mutate_mode = -1, choose a random mutation mode */
if (mutate_mode == MUTATE_NOT_SPECIFIED) {
- randselect = flam3_random_isaac_01(rc);
+ randselect = rand_d01(rc);
if (randselect < 0.1)
mutate_mode = MUTATE_ALL_VARIATIONS;
@@ -2640,7 +2595,7 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
do {
/* Create a random flame, and use the variations */
/* to replace those in the original */
- flam3_random(&mutation, ivars, ivars_n, sym, cp->num_xforms);
+ flam3_random(&mutation, ivars, ivars_n, sym, cp->num_xforms, rc);
for (i = 0; i < cp->num_xforms; i++) {
for (j = 0; j < flam3_nvariations; j++) {
if (cp->xform[i].var[j] != mutation.xform[i].var[j]) {
@@ -2662,10 +2617,10 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
int modxf;
/* Generate a 2-xform random */
- flam3_random(&mutation, ivars, ivars_n, sym, 2);
+ flam3_random(&mutation, ivars, ivars_n, sym, 2, rc);
/* Which xform do we mutate? */
- modxf = (xorshift_step(rc)) % cp->num_xforms;
+ modxf = rand_mod(rc, cp->num_xforms);
add_to_action(action,"mutate xform ");
sprintf(ministr,"%d coefs",modxf);
@@ -2684,12 +2639,12 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
} else if (mutate_mode == MUTATE_ADD_SYMMETRY) {
add_to_action(action,"mutate symmetry");
- flam3_add_symmetry(cp, 0);
+ flam3_add_symmetry(cp, 0, rc);
} else if (mutate_mode == MUTATE_POST_XFORMS) {
- int b = 1 + (xorshift_step(rc))%6;
- int same = (xorshift_step(rc))&3; /* 25% chance of using the same post for all of them */
+ int b = 1 + rand_mod(rc, 6);
+ int same = rand_mod(rc, 4); /* 25% chance of using the same post for all of them */
sprintf(ministr,"(%d%s)",b,(same>0) ? " same" : "");
add_to_action(action,"mutate post xforms ");
@@ -2707,7 +2662,7 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
if (b&1) { /* 50% chance */
- double f = M_PI * flam3_random_isaac_11(rc);
+ double f = M_PI * rand_d11(rc);
double t[2][2];
t[0][0] = (cp->xform[i].c[0][0] * cos(f) + cp->xform[i].c[0][1] * -sin(f));
@@ -2736,16 +2691,16 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
if (b&2) { /* 33% chance */
- double f = 0.2 + flam3_random_isaac_01(rc);
- double g = 0.2 + flam3_random_isaac_01(rc);
+ double f = 0.2 + rand_d01(rc);
+ double g = 0.2 + rand_d01(rc);
- if (flam3_random_isaac_bit(rc))
+ if (rand_bool(rc))
f = 1.0 / f;
- if (flam3_random_isaac_bit(rc))
+ if (rand_bool(rc))
g = f;
else {
- if (flam3_random_isaac_bit(rc))
+ if (rand_bool(rc))
g = 1.0 / g;
}
@@ -2761,8 +2716,8 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
if (b&4) { /* 16% chance */
- double f = flam3_random_isaac_11(rc);
- double g = flam3_random_isaac_11(rc);
+ double f = rand_d11(rc);
+ double g = rand_d11(rc);
cp->xform[i].c[2][0] -= f;
cp->xform[i].c[2][1] -= g;
@@ -2773,21 +2728,21 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
}
} else if (mutate_mode == MUTATE_COLOR_PALETTE) {
- double s = flam3_random_isaac_01(rc);
+ double s = rand_d01(rc);
if (s < 0.4) { /* randomize xform color coords */
- flam3_improve_colors(cp, 100, 0, 10);
+ flam3_improve_colors(cp, 100, 0, 10, rc);
add_to_action(action,"mutate color coords");
} else if (s < 0.8) { /* randomize xform color coords and palette */
- flam3_improve_colors(cp, 25, 1, 10);
+ flam3_improve_colors(cp, 25, 1, 10, rc);
add_to_action(action,"mutate color all");
} else { /* randomize palette only */
- cp->palette_index = flam3_get_palette(flam3_palette_random, cp->palette, cp->hue_rotation);
+ cp->palette_index = flam3_get_palette(flam3_palette_random, cp->palette, cp->hue_rotation, rc);
/* if our palette retrieval fails, skip the mutation */
if (cp->palette_index >= 0)
add_to_action(action,"mutate color palette");
@@ -2797,7 +2752,7 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
}
} else if (mutate_mode == MUTATE_DELETE_XFORM) {
- int nx = (xorshift_step(rc))%cp->num_xforms;
+ int nx = rand_mod(rc, cp->num_xforms);
sprintf(ministr,"%d",nx);
add_to_action(action,"mutate delete xform ");
add_to_action(action,ministr);
@@ -2809,7 +2764,7 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
int x;
add_to_action(action,"mutate all coefs");
- flam3_random(&mutation, ivars, ivars_n, sym, cp->num_xforms);
+ flam3_random(&mutation, ivars, ivars_n, sym, cp->num_xforms, rc);
/* change all the coefs by a fraction of the random */
for (x = 0; x < cp->num_xforms; x++) {
@@ -2827,15 +2782,7 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
}
-static int random_var() {
- return random() % flam3_nvariations;
-}
-
-static int random_varn(int n) {
- return random() % n;
-}
-
-void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_xforms) {
+void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_xforms, randctx * const rc) {
int i, j, nxforms, var, samed, multid, samepost, postid, addfinal=0;
int finum = -1;
@@ -2855,8 +2802,8 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
clear_cp(cp,flam3_defaults_on);
- cp->hue_rotation = (random()&7) ? 0.0 : flam3_random01();
- cp->palette_index = flam3_get_palette(flam3_palette_random, cp->palette, cp->hue_rotation);
+ cp->hue_rotation = rand_mod(rc, 8) ? 0.0 : rand_d01(rc);
+ cp->palette_index = flam3_get_palette(flam3_palette_random, cp->palette, cp->hue_rotation, rc);
if (cp->palette_index < 0)
fprintf(stderr,"error getting palette from xml file, setting to all white\n");
cp->time = 0.0;
@@ -2868,10 +2815,10 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
nxforms = spec_xforms;
flam3_add_xforms(cp,nxforms,0,0);
} else {
- nxforms = random_distrib(xform_distrib);
+ nxforms = rand_distrib(rc, xform_distrib);
flam3_add_xforms(cp,nxforms,0,0);
/* Add a final xform 15% of the time */
- addfinal = flam3_random01() < 0.15;
+ addfinal = rand_d01(rc) < 0.15;
if (addfinal) {
flam3_add_xforms(cp,1,0,1);
nxforms = nxforms + addfinal;
@@ -2882,8 +2829,8 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
/* If first input variation is 'flam3_variation_random' */
/* choose one to use or decide to use multiple */
if (flam3_variation_random == ivars[0]) {
- if (flam3_random_bit()) {
- var = random_varn(mvar);
+ if (rand_bool(rc)) {
+ var = rand_mod(rc, mvar);
} else {
var = flam3_variation_random;
}
@@ -2891,10 +2838,10 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
var = flam3_variation_random_fromspecified;
}
- samed = flam3_random_bit();
- multid = flam3_random_bit();
- postid = flam3_random01() < 0.6;
- samepost = flam3_random_bit();
+ samed = rand_bool(rc);
+ multid = rand_bool(rc);
+ postid = rand_d01(rc) < 0.6;
+ samepost = rand_bool(rc);
/* Loop over xforms */
for (i = 0; i < nxforms; i++) {
@@ -2905,7 +2852,7 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
cp->xform[i].animate = 1.0;
for (j = 0; j < 3; j++) {
for (k = 0; k < 2; k++) {
- cp->xform[i].c[j][k] = flam3_random11();
+ cp->xform[i].c[j][k] = rand_d11(rc);
cp->xform[i].post[j][k] = (double)(k==j);
}
}
@@ -2917,7 +2864,7 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
for (j = 0; j < 3; j++)
for (k = 0; k < 2; k++) {
if (samepost || (i==0))
- cp->xform[i].post[j][k] = flam3_random11();
+ cp->xform[i].post[j][k] = rand_d11(rc);
else
cp->xform[i].post[j][k] = cp->xform[0].post[j][k];
}
@@ -2936,7 +2883,7 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
} else if (multid && flam3_variation_random == var) {
/* Choose a random var for this xform */
- cp->xform[i].var[random_varn(mvar)] = 1.0;
+ cp->xform[i].var[rand_mod(rc, mvar)] = 1.0;
} else {
@@ -2954,7 +2901,7 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
/* but less than flam3_nvariations.Probability leans */
/* towards fewer variations. */
n = 2;
- while ((flam3_random_bit()) && (n<mvar))
+ while ((rand_bool(rc)) && (n<mvar))
n++;
/* Randomly choose n variations, and change their weights. */
@@ -2962,9 +2909,9 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
/* the probability that multiple vars are used. */
for (j = 0; j < n; j++) {
if (flam3_variation_random_fromspecified != var)
- cp->xform[i].var[random_varn(mvar)] = flam3_random01();
+ cp->xform[i].var[rand_mod(rc, mvar)] = rand_d01(rc);
else
- cp->xform[i].var[ivars[random_varn(ivars_n)]] = flam3_random01();
+ cp->xform[i].var[ivars[rand_mod(rc, ivars_n)]] = rand_d01(rc);
}
/* Normalize weights to 1.0 total. */
@@ -2972,7 +2919,7 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
for (j = 0; j < flam3_nvariations; j++)
sum += cp->xform[i].var[j];
if (sum == 0.0)
- cp->xform[i].var[random_var()] = 1.0;
+ cp->xform[i].var[rand_mod(rc, flam3_nvariations)] = 1.0;
else {
for (j = 0; j < flam3_nvariations; j++)
cp->xform[i].var[j] /= sum;
@@ -2982,16 +2929,16 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
} else {
/* Handle final xform randomness. */
n = 1;
- if (flam3_random_bit()) n++;
+ if (rand_bool(rc)) n++;
/* Randomly choose n variations, and change their weights. */
/* A var can be selected more than once, further reducing */
/* the probability that multiple vars are used. */
for (j = 0; j < n; j++) {
if (flam3_variation_random_fromspecified != var)
- cp->xform[i].var[random_varn(mvar)] = flam3_random01();
+ cp->xform[i].var[rand_mod(rc, mvar)] = rand_d01(rc);
else
- cp->xform[i].var[ivars[random_varn(ivars_n)]] = flam3_random01();
+ cp->xform[i].var[ivars[rand_mod(rc, ivars_n)]] = rand_d01(rc);
}
/* Normalize weights to 1.0 total. */
@@ -2999,7 +2946,7 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
for (j = 0; j < flam3_nvariations; j++)
sum += cp->xform[i].var[j];
if (sum == 0.0)
- cp->xform[i].var[random_var()] = 1.0;
+ cp->xform[i].var[rand_mod(rc, flam3_nvariations)] = 1.0;
else {
for (j = 0; j < flam3_nvariations; j++)
cp->xform[i].var[j] /= sum;
@@ -3009,42 +2956,42 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
/* Generate random params for parametric variations, if selected. */
if (cp->xform[i].var[VAR_BLOB] > 0) {
/* Create random params for blob */
- cp->xform[i].blob_low = 0.2 + 0.5 * flam3_random01();
- cp->xform[i].blob_high = 0.8 + 0.4 * flam3_random01();
- cp->xform[i].blob_waves = (int)(2 + 5 * flam3_random01());
+ cp->xform[i].blob_low = 0.2 + 0.5 * rand_d01(rc);
+ cp->xform[i].blob_high = 0.8 + 0.4 * rand_d01(rc);
+ cp->xform[i].blob_waves = (int)(2 + 5 * rand_d01(rc));
}
if (cp->xform[i].var[VAR_PDJ] > 0) {
/* Create random params for PDJ */
- cp->xform[i].pdj_a = 3.0 * flam3_random11();
- cp->xform[i].pdj_b = 3.0 * flam3_random11();
- cp->xform[i].pdj_c = 3.0 * flam3_random11();
- cp->xform[i].pdj_d = 3.0 * flam3_random11();
+ cp->xform[i].pdj_a = 3.0 * rand_d11(rc);
+ cp->xform[i].pdj_b = 3.0 * rand_d11(rc);
+ cp->xform[i].pdj_c = 3.0 * rand_d11(rc);
+ cp->xform[i].pdj_d = 3.0 * rand_d11(rc);
}
if (cp->xform[i].var[VAR_FAN2] > 0) {
/* Create random params for fan2 */
- cp->xform[i].fan2_x = flam3_random11();
- cp->xform[i].fan2_y = flam3_random11();
+ cp->xform[i].fan2_x = rand_d11(rc);
+ cp->xform[i].fan2_y = rand_d11(rc);
}
if (cp->xform[i].var[VAR_RINGS2] > 0) {
/* Create random params for rings2 */
- cp->xform[i].rings2_val = 2*flam3_random01();
+ cp->xform[i].rings2_val = 2*rand_d01(rc);
}
if (cp->xform[i].var[VAR_PERSPECTIVE] > 0) {
/* Create random params for perspective */
- cp->xform[i].perspective_angle = flam3_random01();
- cp->xform[i].perspective_dist = 2*flam3_random01() + 1.0;
+ cp->xform[i].perspective_angle = rand_d01(rc);
+ cp->xform[i].perspective_dist = 2*rand_d01(rc) + 1.0;
}
if (cp->xform[i].var[VAR_JULIAN] > 0) {
/* Create random params for julian */
- cp->xform[i].julian_power = (int)(5*flam3_random01() + 2);
+ cp->xform[i].julian_power = (int)(5*rand_d01(rc) + 2);
cp->xform[i].julian_dist = 1.0;
}
@@ -3052,7 +2999,7 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
if (cp->xform[i].var[VAR_JULIASCOPE] > 0) {
/* Create random params for juliaScope */
- cp->xform[i].juliascope_power = (int)(5*flam3_random01() + 2);
+ cp->xform[i].juliascope_power = (int)(5*rand_d01(rc) + 2);
cp->xform[i].juliascope_dist = 1.0;
}
@@ -3060,234 +3007,234 @@ void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_x
if (cp->xform[i].var[VAR_RADIAL_BLUR] > 0) {
/* Create random params for radialBlur */
- cp->xform[i].radial_blur_angle = (2 * flam3_random01() - 1);
+ cp->xform[i].radial_blur_angle = (2 * rand_d01(rc) - 1);
}
if (cp->xform[i].var[VAR_PIE] > 0) {
/* Create random params for pie */
- cp->xform[i].pie_slices = (int) 10.0*flam3_random01();
- cp->xform[i].pie_thickness = flam3_random01();
- cp->xform[i].pie_rotation = 2.0 * M_PI * flam3_random11();
+ cp->xform[i].pie_slices = (int) 10.0*rand_d01(rc);
+ cp->xform[i].pie_thickness = rand_d01(rc);
+ cp->xform[i].pie_rotation = 2.0 * M_PI * rand_d11(rc);
}
if (cp->xform[i].var[VAR_NGON] > 0) {
/* Create random params for ngon */
- cp->xform[i].ngon_sides = (int) flam3_random01()* 10 + 3;
- cp->xform[i].ngon_power = 3*flam3_random01() + 1;
- cp->xform[i].ngon_circle = 3*flam3_random01();
- cp->xform[i].ngon_corners = 2*flam3_random01()*cp->xform[i].ngon_circle;
+ cp->xform[i].ngon_sides = (int) rand_d01(rc)* 10 + 3;
+ cp->xform[i].ngon_power = 3*rand_d01(rc) + 1;
+ cp->xform[i].ngon_circle = 3*rand_d01(rc);
+ cp->xform[i].ngon_corners = 2*rand_d01(rc)*cp->xform[i].ngon_circle;
}
if (cp->xform[i].var[VAR_CURL] > 0) {
/* Create random params for curl */
- cp->xform[i].curl_c1 = flam3_random01();
- cp->xform[i].curl_c2 = flam3_random01();
+ cp->xform[i].curl_c1 = rand_d01(rc);
+ cp->xform[i].curl_c2 = rand_d01(rc);
}
if (cp->xform[i].var[VAR_RECTANGLES] > 0) {
/* Create random params for rectangles */
- cp->xform[i].rectangles_x = flam3_random01();
- cp->xform[i].rectangles_y = flam3_random01();
+ cp->xform[i].rectangles_x = rand_d01(rc);
+ cp->xform[i].rectangles_y = rand_d01(rc);
}
if (cp->xform[i].var[VAR_DISC2] > 0) {
/* Create random params for disc2 */
- cp->xform[i].disc2_rot = 0.5 * flam3_random01();
- cp->xform[i].disc2_twist = 0.5 * flam3_random01();
+ cp->xform[i].disc2_rot = 0.5 * rand_d01(rc);
+ cp->xform[i].disc2_twist = 0.5 * rand_d01(rc);
}
if (cp->xform[i].var[VAR_SUPER_SHAPE] > 0) {
/* Create random params for supershape */
- cp->xform[i].super_shape_rnd = flam3_random01();
- cp->xform[i].super_shape_m = (int) flam3_random01()*6;
- cp->xform[i].super_shape_n1 = flam3_random01()*40;
- cp->xform[i].super_shape_n2 = flam3_random01()*20;
+ cp->xform[i].super_shape_rnd = rand_d01(rc);
+ cp->xform[i].super_shape_m = (int) rand_d01(rc)*6;
+ cp->xform[i].super_shape_n1 = rand_d01(rc)*40;
+ cp->xform[i].super_shape_n2 = rand_d01(rc)*20;
cp->xform[i].super_shape_n3 = cp->xform[i].super_shape_n2;
cp->xform[i].super_shape_holes = 0.0;
}
if (cp->xform[i].var[VAR_FLOWER] > 0) {
/* Create random params for flower */
- cp->xform[i].flower_petals = 4 * flam3_random01();
- cp->xform[i].flower_holes = flam3_random01();
+ cp->xform[i].flower_petals = 4 * rand_d01(rc);
+ cp->xform[i].flower_holes = rand_d01(rc);
}
if (cp->xform[i].var[VAR_CONIC] > 0) {
/* Create random params for conic */
- cp->xform[i].conic_eccentricity = flam3_random01();
- cp->xform[i].conic_holes = flam3_random01();
+ cp->xform[i].conic_eccentricity = rand_d01(rc);
+ cp->xform[i].conic_holes = rand_d01(rc);
}
if (cp->xform[i].var[VAR_PARABOLA] > 0) {
/* Create random params for parabola */
- cp->xform[i].parabola_height = 0.5 + flam3_random01();
- cp->xform[i].parabola_width = 0.5 + flam3_random01();
+ cp->xform[i].parabola_height = 0.5 + rand_d01(rc);
+ cp->xform[i].parabola_width = 0.5 + rand_d01(rc);
}
if (cp->xform[i].var[VAR_BENT2] > 0) {
/* Create random params for bent2 */
- cp->xform[i].bent2_x = 3*(-0.5 + flam3_random01());
- cp->xform[i].bent2_y = 3*(-0.5 + flam3_random01());
+ cp->xform[i].bent2_x = 3*(-0.5 + rand_d01(rc));
+ cp->xform[i].bent2_y = 3*(-0.5 + rand_d01(rc));
}
if (cp->xform[i].var[VAR_BIPOLAR] > 0) {
/* Create random params for bipolar */
- cp->xform[i].bipolar_shift = 2.0 * flam3_random01() - 1;
+ cp->xform[i].bipolar_shift = 2.0 * rand_d01(rc) - 1;
}
if (cp->xform[i].var[VAR_CELL] > 0) {
/* Create random params for cell */
- cp->xform[i].cell_size = 2.0 * flam3_random01() + 0.5;
+ cp->xform[i].cell_size = 2.0 * rand_d01(rc) + 0.5;
}
if (cp->xform[i].var[VAR_CPOW] > 0) {
/* Create random params for cpow */
- cp->xform[i].cpow_r = 3.0 * flam3_random01();
- cp->xform[i].cpow_i = flam3_random01() - 0.5;
- cp->xform[i].cpow_power = (int)(5.0 * flam3_random01());
+ cp->xform[i].cpow_r = 3.0 * rand_d01(rc);
+ cp->xform[i].cpow_i = rand_d01(rc) - 0.5;
+ cp->xform[i].cpow_power = (int)(5.0 * rand_d01(rc));
}
if (cp->xform[i].var[VAR_CURVE] > 0) {
/* Create random params for curve */
- cp->xform[i].curve_xamp = 5 * (flam3_random01()-.5);
- cp->xform[i].curve_yamp = 4 * (flam3_random01()-.5);
- cp->xform[i].curve_xlength = 2 * (flam3_random01()+.5);
- cp->xform[i].curve_ylength = 2 * (flam3_random01()+.5);
+ cp->xform[i].curve_xamp = 5 * (rand_d01(rc)-.5);
+ cp->xform[i].curve_yamp = 4 * (rand_d01(rc)-.5);
+ cp->xform[i].curve_xlength = 2 * (rand_d01(rc)+.5);
+ cp->xform[i].curve_ylength = 2 * (rand_d01(rc)+.5);
}
if (cp->xform[i].var[VAR_ESCHER] > 0) {
/* Create random params for escher */
- cp->xform[i].escher_beta = M_PI * flam3_random11();
+ cp->xform[i].escher_beta = M_PI * rand_d11(rc);
}
if (cp->xform[i].var[VAR_LAZYSUSAN] > 0) {
/* Create random params for lazysusan */
- cp->xform[i].lazysusan_x = 2.0*flam3_random11();
- cp->xform[i].lazysusan_y = 2.0*flam3_random11();
- cp->xform[i].lazysusan_spin = M_PI*flam3_random11();
- cp->xform[i].lazysusan_space = 2.0*flam3_random11();
- cp->xform[i].lazysusan_twist = 2.0*flam3_random11();
+ cp->xform[i].lazysusan_x = 2.0*rand_d11(rc);
+ cp->xform[i].lazysusan_y = 2.0*rand_d11(rc);
+ cp->xform[i].lazysusan_spin = M_PI*rand_d11(rc);
+ cp->xform[i].lazysusan_space = 2.0*rand_d11(rc);
+ cp->xform[i].lazysusan_twist = 2.0*rand_d11(rc);
}
if (cp->xform[i].var[VAR_MODULUS] > 0) {
/* Create random params for modulus */
- cp->xform[i].modulus_x = flam3_random11();
- cp->xform[i].modulus_y = flam3_random11();
+ cp->xform[i].modulus_x = rand_d11(rc);
+ cp->xform[i].modulus_y = rand_d11(rc);
}
if (cp->xform[i].var[VAR_OSCILLOSCOPE] > 0) {
/* Create random params for oscope */
- cp->xform[i].oscope_separation = 1.0 + flam3_random11();
- cp->xform[i].oscope_frequency = M_PI * flam3_random11();
- cp->xform[i].oscope_amplitude = 1.0 + 2 * flam3_random01();
- cp->xform[i].oscope_damping = flam3_random01();
+ cp->xform[i].oscope_separation = 1.0 + rand_d11(rc);
+ cp->xform[i].oscope_frequency = M_PI * rand_d11(rc);
+ cp->xform[i].oscope_amplitude = 1.0 + 2 * rand_d01(rc);
+ cp->xform[i].oscope_damping = rand_d01(rc);
}
if (cp->xform[i].var[VAR_POPCORN2] > 0) {
/* Create random params for popcorn2 */
- cp->xform[i].popcorn2_x = 0.2 * flam3_random01();
- cp->xform[i].popcorn2_y = 0.2 * flam3_random01();
- cp->xform[i].popcorn2_c = 5 * flam3_random01();
+ cp->xform[i].popcorn2_x = 0.2 * rand_d01(rc);
+ cp->xform[i].popcorn2_y = 0.2 * rand_d01(rc);
+ cp->xform[i].popcorn2_c = 5 * rand_d01(rc);
}
if (cp->xform[i].var[VAR_SEPARATION] > 0) {
/* Create random params for separation */
- cp->xform[i].separation_x = 1 + flam3_random11();
- cp->xform[i].separation_y = 1 + flam3_random11();
- cp->xform[i].separation_xinside = flam3_random11();
- cp->xform[i].separation_yinside = flam3_random11();
+ cp->xform[i].separation_x = 1 + rand_d11(rc);
+ cp->xform[i].separation_y = 1 + rand_d11(rc);
+ cp->xform[i].separation_xinside = rand_d11(rc);
+ cp->xform[i].separation_yinside = rand_d11(rc);
}
if (cp->xform[i].var[VAR_SPLIT] > 0) {
/* Create random params for split */
- cp->xform[i].split_xsize = flam3_random11();
- cp->xform[i].split_ysize = flam3_random11();
+ cp->xform[i].split_xsize = rand_d11(rc);
+ cp->xform[i].split_ysize = rand_d11(rc);
}
if (cp->xform[i].var[VAR_SPLITS] > 0) {
/* Create random params for splits */
- cp->xform[i].splits_x = flam3_random11();
- cp->xform[i].splits_y = flam3_random11();
+ cp->xform[i].splits_x = rand_d11(rc);
+ cp->xform[i].splits_y = rand_d11(rc);
}
if (cp->xform[i].var[VAR_STRIPES] > 0) {
/* Create random params for stripes */
- cp->xform[i].stripes_space = flam3_random01();
- cp->xform[i].stripes_warp = 5*flam3_random01();
+ cp->xform[i].stripes_space = rand_d01(rc);
+ cp->xform[i].stripes_warp = 5*rand_d01(rc);
}
if (cp->xform[i].var[VAR_WEDGE] > 0) {
/* Create random params for wedge */
- cp->xform[i].wedge_angle = M_PI*flam3_random01();
- cp->xform[i].wedge_hole = 0.5*flam3_random11();
- cp->xform[i].wedge_count = floor(5*flam3_random01())+1;
- cp->xform[i].wedge_swirl = flam3_random01();
+ cp->xform[i].wedge_angle = M_PI*rand_d01(rc);
+ cp->xform[i].wedge_hole = 0.5*rand_d11(rc);
+ cp->xform[i].wedge_count = floor(5*rand_d01(rc))+1;
+ cp->xform[i].wedge_swirl = rand_d01(rc);
}
if (cp->xform[i].var[VAR_WEDGE_JULIA] > 0) {
/* Create random params for wedge_julia */
- cp->xform[i].wedge_julia_power = (int)(5*flam3_random01() + 2);
+ cp->xform[i].wedge_julia_power = (int)(5*rand_d01(rc) + 2);
cp->xform[i].wedge_julia_dist = 1.0;
- cp->xform[i].wedge_julia_count = (int)(3*flam3_random01() + 1);
- cp->xform[i].wedge_julia_angle = M_PI * flam3_random01();
+ cp->xform[i].wedge_julia_count = (int)(3*rand_d01(rc) + 1);
+ cp->xform[i].wedge_julia_angle = M_PI * rand_d01(rc);
}
if (cp->xform[i].var[VAR_WEDGE_SPH] > 0) {
/* Create random params for wedge_sph */
- cp->xform[i].wedge_sph_angle = M_PI*flam3_random01();
- cp->xform[i].wedge_sph_hole = 0.5*flam3_random11();
- cp->xform[i].wedge_sph_count = floor(5*flam3_random01())+1;
- cp->xform[i].wedge_sph_swirl = flam3_random01();
+ cp->xform[i].wedge_sph_angle = M_PI*rand_d01(rc);
+ cp->xform[i].wedge_sph_hole = 0.5*rand_d11(rc);
+ cp->xform[i].wedge_sph_count = floor(5*rand_d01(rc))+1;
+ cp->xform[i].wedge_sph_swirl = rand_d01(rc);
}
if (cp->xform[i].var[VAR_WHORL] > 0) {
/* Create random params for whorl */
- cp->xform[i].whorl_inside = flam3_random01();
- cp->xform[i].whorl_outside = flam3_random01();
+ cp->xform[i].whorl_inside = rand_d01(rc);
+ cp->xform[i].whorl_outside = rand_d01(rc);
}
if (cp->xform[i].var[VAR_WAVES2] > 0) {
/* Create random params for waves2 */
- cp->xform[i].waves2_scalex = 0.5 + flam3_random01();
- cp->xform[i].waves2_scaley = 0.5 + flam3_random01();
- cp->xform[i].waves2_freqx = 4 * flam3_random01();
- cp->xform[i].waves2_freqy = 4 * flam3_random01();
+ cp->xform[i].waves2_scalex = 0.5 + rand_d01(rc);
+ cp->xform[i].waves2_scaley = 0.5 + rand_d01(rc);
+ cp->xform[i].waves2_freqx = 4 * rand_d01(rc);
+ cp->xform[i].waves2_freqy = 4 * rand_d01(rc);
}
if (cp->xform[i].var[VAR_AUGER] > 0) {
/* Create random params for auger */
cp->xform[i].auger_sym = 0;
- cp->xform[i].auger_weight = 0.5 + flam3_random01()/2.0;
- cp->xform[i].auger_freq = floor(5*flam3_random01())+1;
- cp->xform[i].auger_scale = flam3_random01();
+ cp->xform[i].auger_weight = 0.5 + rand_d01(rc)/2.0;
+ cp->xform[i].auger_freq = floor(5*rand_d01(rc))+1;
+ cp->xform[i].auger_scale = rand_d01(rc);
}
if (cp->xform[i].var[VAR_FLUX] > 0) {
/* Create random params for flux */
- cp->xform[i].flux_spread = 0.5 + flam3_random01()/2.0;
+ cp->xform[i].flux_spread = 0.5 + rand_d01(rc)/2.0;
}
if (cp->xform[i].var[VAR_MOBIUS] > 0) {
/* Create random params for mobius */
- cp->xform[i].mobius_re_a = flam3_random11();
- cp->xform[i].mobius_im_a = flam3_random11();
- cp->xform[i].mobius_re_b = flam3_random11();
- cp->xform[i].mobius_im_b = flam3_random11();
- cp->xform[i].mobius_re_c = flam3_random11();
- cp->xform[i].mobius_im_c = flam3_random11();
- cp->xform[i].mobius_re_d = flam3_random11();
- cp->xform[i].mobius_im_d = flam3_random11();
+ cp->xform[i].mobius_re_a = rand_d11(rc);
+ cp->xform[i].mobius_im_a = rand_d11(rc);
+ cp->xform[i].mobius_re_b = rand_d11(rc);
+ cp->xform[i].mobius_im_b = rand_d11(rc);
+ cp->xform[i].mobius_re_c = rand_d11(rc);
+ cp->xform[i].mobius_im_c = rand_d11(rc);
+ cp->xform[i].mobius_re_d = rand_d11(rc);
+ cp->xform[i].mobius_im_d = rand_d11(rc);
}
}
/* Randomly add symmetry (but not if we've already added a final xform) */
- if (sym || (!(random()%4) && !addfinal))
- flam3_add_symmetry(cp, sym);
+ if (sym || (!rand_mod(rc, 4) && !addfinal))
+ flam3_add_symmetry(cp, sym, rc);
else
cp->symmetry = 0;
@@ -3329,7 +3276,7 @@ int flam3_estimate_bounding_box(flam3_genome *cp, double eps, int nsamples,
if (nsamples <= 0) nsamples = 10000;
points = (double4 *) malloc(sizeof(double4) * nsamples);
- const double4 start = (double4) { flam3_random_isaac_11(rc), flam3_random_isaac_11(rc), 0.0, 0.0 };
+ const double4 start = (double4) { rand_d11(rc), rand_d11(rc), 0.0, 0.0 };
if (prepare_precalc_flags(cp))
return(-1);
@@ -3429,16 +3376,3 @@ int flam3_render(flam3_frame *spec, void *out,
return(retval);
}
-
-void flam3_srandom() {
- unsigned int seed;
- char *s = getenv("seed");
-
- if (s)
- seed = atoi(s);
- else
- seed = time(0) + getpid();
-
- srandom(seed);
-}
-
diff --git a/flam3.h b/flam3.h
index ca7e830..b841956 100644
--- a/flam3.h
+++ b/flam3.h
@@ -22,7 +22,6 @@
#include <stdio.h>
#include <libxml/parser.h>
-#include "xorshift.h"
char *flam3_version();
@@ -45,7 +44,9 @@ typedef struct {
typedef flam3_palette_entry flam3_palette[256];
-int flam3_get_palette(int palette_index, flam3_palette p, double hue_rotation);
+#include "random.h"
+
+int flam3_get_palette(int n, flam3_palette c, double hue_rotation, randctx * const rc);
#define flam3_variation_random (-1)
#define flam3_variation_random_fromspecified (-2)
@@ -531,7 +532,6 @@ void flam3_copyx(flam3_genome *dest, flam3_genome *src, int num_std, int num_fin
void flam3_copy_params(flam3_xform *dest, flam3_xform *src, int varn);
void flam3_delete_motion_elements(flam3_xform *xf);
-int flam3_xform_preview(flam3_genome *cp, int xi, double range, int numvals, int depth, double *result, randctx *rc);
unsigned short* flam3_create_xform_distrib(flam3_genome *cp);
int flam3_create_chaos_distrib(flam3_genome *cp, int xi, unsigned short *xform_distrib);
int flam3_check_unity_chaos(flam3_genome *cp);
@@ -559,7 +559,7 @@ char *flam3_print_to_string(flam3_genome *cp);
/* ivars_n is the number of values in ivars to select from. */
/* sym is either a symmetry group or 0 meaning random or no symmetry */
/* spec_xforms specifies the number of xforms to use, setting to 0 makes the number random. */
-void flam3_random(flam3_genome *g, int *ivars, int ivars_n, int sym, int spec_xforms);
+void flam3_random(flam3_genome *cp, int *ivars, int ivars_n, int sym, int spec_xforms, randctx * const rc);
void add_to_action(char *action, char *addtoaction);
@@ -567,12 +567,12 @@ void flam3_mutate(flam3_genome *cp, int mutate_mode, int *ivars, int ivars_n, in
void flam3_cross(flam3_genome *cp0, flam3_genome *cp1, flam3_genome *out, int cross_mode, randctx *rc, char *action);
/* return NULL in case of error */
-flam3_genome *flam3_parse_xml2(char *s, char *fn, int default_flag, int *ncps);
-flam3_genome *flam3_parse_from_file(FILE *f, char *fn, int default_flag, int *ncps);
+flam3_genome *flam3_parse_xml2(char *s, char *fn, int default_flag, int *ncps, randctx * const);
+flam3_genome *flam3_parse_from_file(FILE *f, char *fn, int default_flag, int *ncps, randctx * const);
-void flam3_add_symmetry(flam3_genome *g, int sym);
+void flam3_add_symmetry(flam3_genome *cp, int sym, randctx * const rc);
-void flam3_improve_colors(flam3_genome *g, int ntries, int change_palette, int color_resolution);
+void flam3_improve_colors(flam3_genome *g, int ntries, int change_palette, int color_resolution, randctx * const);
int flam3_colorhist(flam3_genome *cp, int num_batches, randctx *rc, double *hist);
int flam3_estimate_bounding_box(flam3_genome *g, double eps, int nsamples,
double *bmin, double *bmax, randctx *rc);
@@ -597,7 +597,6 @@ typedef struct {
double time;
int (*progress)(void *, double, int, double);
void *progress_parameter;
- randctx rc;
int nthreads;
int sub_batch_size;
} flam3_frame;
@@ -614,23 +613,8 @@ int flam3_render(flam3_frame *f, void *out, int field, int nchan, int transp, st
void rotate_by(double *p, double *center, double by);
-double flam3_random01();
-double flam3_random11();
-int flam3_random_bit();
-
-/* ISAAC random numbers */
-double flam3_random_isaac_01(randctx *);
-double flam3_random_isaac_11(randctx *);
-int flam3_random_isaac_bit(randctx *);
-
void flam3_init_frame(flam3_frame *f);
-/* External memory helpers */
-void *flam3_malloc(size_t size);
-void flam3_free(void *ptr);
-
-void flam3_srandom();
-
flam3_genome *sheep_loop(flam3_genome *cp, double blend);
flam3_genome *sheep_edge(flam3_genome *cp, double blend, int seqflag, double stagger);
diff --git a/interpolation.c b/interpolation.c
index 4bef70f..09c3a7a 100644
--- a/interpolation.c
+++ b/interpolation.c
@@ -142,15 +142,16 @@ int compare_xforms(const void *av, const void *bv) {
}
void interpolate_cmap(flam3_palette cmap, double blend,
- int index0, double hue0, int index1, double hue1) {
+ int index0, double hue0, int index1, double hue1,
+ randctx * const rc) {
flam3_palette p0,p1;
int i, j, rcode;
- rcode = flam3_get_palette(index0, p0, hue0);
+ rcode = flam3_get_palette(index0, p0, hue0, rc);
if (rcode<0)
fprintf(stderr,"unable to retrieve palette %d, setting to white\n", index0);
- rcode = flam3_get_palette(index1, p1, hue1);
+ rcode = flam3_get_palette(index1, p1, hue1, rc);
if (rcode<0)
fprintf(stderr,"unable to retrieve palette %d, setting to white\n", index1);
diff --git a/interpolation.h b/interpolation.h
index da3dfd1..8ed81cb 100644
--- a/interpolation.h
+++ b/interpolation.h
@@ -45,7 +45,7 @@ void mult_matrix(double s1[2][2], double s2[2][2], double d[2][2]);
int compare_xforms(const void *av, const void *bv);
void interpolate_cmap(flam3_palette cmap, double blend,
- int index0, double hue0, int index1, double hue1);
+ int index0, double hue0, int index1, double hue1, randctx * const);
void interp_and_convert_back(double *c, int ncps, int xfi, double cxang[4][2],
double cxmag[4][2], double cxtrn[4][2],double store_array[3][2]);
void convert_linear_to_polar(flam3_genome *cp, int ncps, int xfi, int cflag,
diff --git a/palettes.c b/palettes.c
index 213ba13..adcc242 100644
--- a/palettes.c
+++ b/palettes.c
@@ -138,7 +138,7 @@ static int init_palettes(char *filename) {
return(1);
}
-int flam3_get_palette(int n, flam3_palette c, double hue_rotation) {
+int flam3_get_palette(int n, flam3_palette c, double hue_rotation, randctx * const rc) {
int cmap_len = 256;
int idx, i, j, rcode;
@@ -159,7 +159,7 @@ int flam3_get_palette(int n, flam3_palette c, double hue_rotation) {
}
if (flam3_palette_random == n)
- n = the_palettes[random()%npalettes].number;
+ n = the_palettes[rand_mod(rc, npalettes)].number;
for (idx = 0; idx < npalettes; idx++) {
@@ -348,10 +348,10 @@ void flam3_calc_newrgb(double *cbuf, double ls, double highpow, double *newrgb)
}
}
-static int random_xform(flam3_genome *g, int excluded) {
+static int random_xform(flam3_genome *g, int excluded, randctx * const rc) {
int ntries = 0;
while (ntries++ < 100) {
- int i = random() % g->num_xforms;
+ int i = rand_mod(rc, g->num_xforms);
if (g->xform[i].density > 0.0 && i != excluded)
return i;
}
@@ -392,7 +392,6 @@ static double try_colors(flam3_genome *g, int color_resolution) {
g->ntemporal_samples = 1;
// f.temporal_filter_radius = 0.0;
- flam3_init_frame(&f);
f.bits = 33;
f.bytes_per_channel=1;
f.verbose = 0;
@@ -455,25 +454,25 @@ static double try_colors(flam3_genome *g, int color_resolution) {
return (double) (hits / res3);
}
-static void change_colors(flam3_genome *g, int change_palette) {
+static void change_colors(flam3_genome *g, int change_palette, randctx * const rc) {
int i;
int x0, x1;
if (change_palette) {
g->hue_rotation = 0.0;
- g->palette_index = flam3_get_palette(flam3_palette_random, g->palette, 0.0);
+ g->palette_index = flam3_get_palette(flam3_palette_random, g->palette, 0.0, rc);
if (g->palette_index < 0)
fprintf(stderr,"error retrieving random palette, setting to all white\n");
}
for (i = 0; i < g->num_xforms; i++) {
- g->xform[i].color = flam3_random01();
+ g->xform[i].color = rand_d01(rc);
}
- x0 = random_xform(g, -1);
- x1 = random_xform(g, x0);
- if (x0 >= 0 && (random()&1)) g->xform[x0].color = 0.0;
- if (x1 >= 0 && (random()&1)) g->xform[x1].color = 1.0;
+ x0 = random_xform(g, -1, rc);
+ x1 = random_xform(g, x0, rc);
+ if (x0 >= 0 && rand_bool(rc)) g->xform[x0].color = 0.0;
+ if (x1 >= 0 && rand_bool(rc)) g->xform[x1].color = 1.0;
}
-void flam3_improve_colors(flam3_genome *g, int ntries, int change_palette, int color_resolution) {
+void flam3_improve_colors(flam3_genome *g, int ntries, int change_palette, int color_resolution, randctx * const rc) {
int i;
double best, b;
flam3_genome best_genome;
@@ -488,7 +487,7 @@ void flam3_improve_colors(flam3_genome *g, int ntries, int change_palette, int c
flam3_copy(&best_genome,g);
for (i = 0; i < ntries; i++) {
- change_colors(g, change_palette);
+ change_colors(g, change_palette, rc);
b = try_colors(g, color_resolution);
if (b < 0) {
fprintf(stderr,"error in try_colors, aborting tries\n");
diff --git a/parser.c b/parser.c
index 03f9bd0..b1882b9 100644
--- a/parser.c
+++ b/parser.c
@@ -213,7 +213,7 @@ int flam3_interp_missing_colors(flam3_genome *cp) {
}
-void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag, flam3_genome **all_cps, int *all_ncps) {
+void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag, flam3_genome **all_cps, int *all_ncps, randctx * const rc) {
xmlNode *this_node = NULL;
flam3_genome loc_current_cp;
@@ -233,7 +233,7 @@ void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag
/* This is a flame element. Parse it. */
clear_cp(&loc_current_cp, default_flag);
- pfe_success = parse_flame_element(this_node,&loc_current_cp);
+ pfe_success = parse_flame_element(this_node,&loc_current_cp, rc);
if (pfe_success>0) {
fprintf(stderr,"error parsing flame element\n");
@@ -255,7 +255,7 @@ void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag
if (loc_current_cp.palette_index != -1) {
col_success = flam3_get_palette(loc_current_cp.palette_index, loc_current_cp.palette,
- loc_current_cp.hue_rotation);
+ loc_current_cp.hue_rotation, rc);
if (col_success < 0)
fprintf(stderr,"error retrieving palette %d, setting to all white\n",loc_current_cp.palette_index);
}
@@ -271,7 +271,7 @@ void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag
} else {
/* Check all of the children of this element */
- scan_for_flame_nodes(this_node->children, parent_file, default_flag, all_cps, all_ncps);
+ scan_for_flame_nodes(this_node->children, parent_file, default_flag, all_cps, all_ncps, rc);
}
}
@@ -281,7 +281,8 @@ void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag
}
-int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp) {
+int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp,
+ randctx * const rc) {
flam3_genome *cp = loc_current_cp;
xmlNode *chld_node, *motion_node;
xmlNodePtr edit_node;
@@ -653,7 +654,7 @@ int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp) {
}
if (old_format>0)
- interpolate_cmap(cp->palette, blend, index0, hue0, index1, hue1);
+ interpolate_cmap(cp->palette, blend, index0, hue0, index1, hue1, rc);
else {
char *pal_str;
@@ -699,7 +700,7 @@ int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp) {
}
bef = cp->num_xforms;
- flam3_add_symmetry(cp,kind);
+ flam3_add_symmetry(cp,kind, rc);
aft = cp->num_xforms;
num_std_xforms += (aft-bef);
diff --git a/parser.h b/parser.h
index 73d2c68..c54c6ab 100644
--- a/parser.h
+++ b/parser.h
@@ -26,8 +26,8 @@ double flam3_atof(char *nstr);
int var2n(const char *s);
int flam3_parse_hexformat_colors(char *colstr, flam3_genome *cp, int numcolors, int chan);
-void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag, flam3_genome **all_cp, int *all_ncps);
-int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp);
+void scan_for_flame_nodes(xmlNode *cur_node, char *parent_file, int default_flag, flam3_genome **all_cp, int *all_ncps, randctx * const);
+int parse_flame_element(xmlNode *flame_node, flam3_genome *loc_current_cp, randctx * const);
int parse_xform_xml(xmlNode *chld_node,flam3_xform *this_xform, int *num_xaos,
flam3_chaos_entry **xaos, int numstd, int motionxf);
void flam3_edit_print(FILE *f, xmlNodePtr editNode, int tabs, int formatting);
diff --git a/private.h b/private.h
index 466104b..62cdb71 100644
--- a/private.h
+++ b/private.h
@@ -80,7 +80,7 @@ typedef struct {
typedef struct {
double4 *iter_storage; /* Storage for iteration coordinates */
- randctx rc; /* Thread-unique ISAAC seed */
+ randctx rc; /* Thread-unique rng context */
flam3_genome cp; /* Full copy of genome for use by the thread */
int first_thread;
int timer_initialize;
diff --git a/random.c b/random.c
new file mode 100644
index 0000000..f0a06c2
--- /dev/null
+++ b/random.c
@@ -0,0 +1,63 @@
+/* Psoudo-random number generator
+ *
+ * Uses xorshift1024 from “An experimental exploration of Marsaglia’s xorshift
+ * generators, scrambled”, Sebastiano Vigna
+ */
+
+#include "random.h"
+
+uint64_t rand_u64 (randctx * const st) {
+ uint64_t s0 = st->s[ st->p ];
+ uint64_t s1 = st->s[ st->p = ( st->p + 1 ) & (XORSHIFT_S-1) ];
+ s1 ^= s1 << 31; // a
+ s1 ^= s1 >> 11; // b
+ s0 ^= s0 >> 30; // c
+ return ( st->s[ st->p ] = s0 ^ s1 ) * 1181783497276652981LL;
+}
+
+/* Generate random double in [0,1]
+ */
+double rand_d01 (randctx * const st) {
+ return (double) rand_u64 (st) / (double) UINT64_MAX;
+}
+
+/* Generate random double in [-1,1]
+ */
+double rand_d11 (randctx * const st) {
+ return rand_d01 (st) * 2.0 - 1.0;
+}
+
+/* Random boolean value in {0,1}
+ */
+int rand_bool (randctx * const st) {
+ return rand_u64 (st) & 1;
+}
+
+/* Generate random uint64_t with Intel’s rdrand instruction
+ */
+static uint64_t rand64 () {
+ unsigned long long rand;
+ while (!__builtin_ia32_rdrand64_step (&rand));
+ return rand;
+}
+
+/* Seed rng with rdrand
+ */
+void rand_seed (randctx * const st) {
+ /* seed with high-quality randomness */
+ for (unsigned char i = 0; i < XORSHIFT_S; i++) {
+ st->s[i] = rand64 ();
+ }
+}
+
+#if 0
+uint64_t xorshift_step (randctx * const st) {
+ uint64_t x = st->s[0];
+ x ^= x >> 12; // a
+ x ^= x << 25; // b
+ x ^= x >> 27; // c
+ st->s[0] = x;
+ return x * 2685821657736338717LL;
+}
+#endif
+
diff --git a/random.h b/random.h
new file mode 100644
index 0000000..4e0b8c9
--- /dev/null
+++ b/random.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <stdint.h>
+
+#define XORSHIFT_S 16
+
+typedef struct {
+ uint64_t s[XORSHIFT_S];
+ int p;
+} randctx;
+
+void rand_seed (randctx * const st);
+uint64_t rand_u64 (randctx * const st);
+double rand_d01 (randctx * const st);
+double rand_d11 (randctx * const st);
+int rand_bool (randctx * const st);
+
+#define rand_distrib(st,v) ((v)[rand_u64(st)%vlen(v)])
+#define rand_mod(st,max) (rand_u64(st)%(max))
+
diff --git a/rect.c b/rect.c
index 7044998..a9bda80 100644
--- a/rect.c
+++ b/rect.c
@@ -357,10 +357,10 @@ static void iter_thread(void *fth) {
/* Seed iterations */
const double4 start = (double4) {
- flam3_random_isaac_11(&(fthp->rc)),
- flam3_random_isaac_11(&(fthp->rc)),
- flam3_random_isaac_01(&(fthp->rc)),
- flam3_random_isaac_01(&(fthp->rc)),
+ rand_d11(&(fthp->rc)),
+ rand_d11(&(fthp->rc)),
+ rand_d01(&(fthp->rc)),
+ rand_d01(&(fthp->rc)),
};
/* Execute iterations */
@@ -792,8 +792,8 @@ static int render_rectangle(flam3_frame *spec, void *out,
for (thi = 0; thi < spec->nthreads; thi++) {
int rk;
- /* Create a new isaac state for this thread */
- xorshift_seed (&(fth[thi].rc));
+ /* Create a new state for this thread */
+ rand_seed (&fth[thi].rc);
if (0==thi) {
diff --git a/variations.c b/variations.c
index 6d443ce..7c9d8c3 100644
--- a/variations.c
+++ b/variations.c
@@ -33,7 +33,7 @@ typedef struct {
flam3_xform *xform; /* For the important values */
- /* Pointer to the isaac RNG state */
+ /* Pointer to the RNG state */
randctx *rc;
} flam3_iter_helper;
@@ -358,7 +358,7 @@ static double2 var13_julia (const double2 in, const flam3_iter_helper * const f,
double a = 0.5 * f->precalc_atan;
double sa,ca;
- if (flam3_random_isaac_bit(f->rc)) //(flam3_random_bit())
+ if (rand_bool(f->rc))
a += M_PI;
r = weight * sqrt(f->precalc_sqrt);
@@ -674,10 +674,10 @@ static double2 var31_noise (const double2 in, const flam3_iter_helper * const f,
double tmpr, sinr, cosr, r;
- tmpr = flam3_random_isaac_01(f->rc) * 2 * M_PI;
+ tmpr = rand_d01(f->rc) * 2 * M_PI;
sincos(tmpr,&sinr,&cosr);
- r = weight * flam3_random_isaac_01(f->rc);
+ r = weight * rand_d01(f->rc);
return in * r * (double2) { cosr, sinr };
}
@@ -685,7 +685,7 @@ static double2 var31_noise (const double2 in, const flam3_iter_helper * const f,
static double2 var32_juliaN_generic (const double2 in, const flam3_iter_helper * const f, double weight) {
/* juliaN (03/06) */
- int t_rnd = trunc((f->xform->julian_rN)*flam3_random_isaac_01(f->rc));
+ int t_rnd = trunc((f->xform->julian_rN)*rand_d01(f->rc));
double tmpr = (f->precalc_atanyx + 2 * M_PI * t_rnd) / f->xform->julian_power;
@@ -699,7 +699,7 @@ static double2 var32_juliaN_generic (const double2 in, const flam3_iter_helper *
static double2 var33_juliaScope_generic (const double2 in, const flam3_iter_helper * const f, double weight) {
/* juliaScope (03/06) */
- int t_rnd = trunc((f->xform->juliascope_rN) * flam3_random_isaac_01(f->rc));
+ int t_rnd = trunc((f->xform->juliascope_rN) * rand_d01(f->rc));
double tmpr, r;
double sina, cosa;
@@ -721,10 +721,10 @@ static double2 var34_blur (const double2 in, const flam3_iter_helper * const f,
double tmpr, sinr, cosr, r;
- tmpr = flam3_random_isaac_01(f->rc) * 2 * M_PI;
+ tmpr = rand_d01(f->rc) * 2 * M_PI;
sincos(tmpr,&sinr,&cosr);
- r = weight * flam3_random_isaac_01(f->rc);
+ r = weight * rand_d01(f->rc);
return r * (double2) { cosr, sinr };
}
@@ -734,11 +734,11 @@ static double2 var35_gaussian (const double2 in, const flam3_iter_helper * const
double ang, r, sina, cosa;
- ang = flam3_random_isaac_01(f->rc) * 2 * M_PI;
+ ang = rand_d01(f->rc) * 2 * M_PI;
sincos(ang,&sina,&cosa);
- r = weight * ( flam3_random_isaac_01(f->rc) + flam3_random_isaac_01(f->rc)
- + flam3_random_isaac_01(f->rc) + flam3_random_isaac_01(f->rc) - 2.0 );
+ r = weight * ( rand_d01(f->rc) + rand_d01(f->rc)
+ + rand_d01(f->rc) + rand_d01(f->rc) - 2.0 );
return r * (double2) { cosa, sina };
}
@@ -750,8 +750,8 @@ static double2 var36_radial_blur (const double2 in, const flam3_iter_helper * co
double rndG, ra, rz, tmpa, sa, ca;
/* Get pseudo-gaussian */
- rndG = weight * (flam3_random_isaac_01(f->rc) + flam3_random_isaac_01(f->rc)
- + flam3_random_isaac_01(f->rc) + flam3_random_isaac_01(f->rc) - 2.0);
+ rndG = weight * (rand_d01(f->rc) + rand_d01(f->rc)
+ + rand_d01(f->rc) + rand_d01(f->rc) - 2.0);
/* Calculate angle & zoom */
ra = f->precalc_sqrt;
@@ -768,10 +768,10 @@ static double2 var37_pie(const double2 in, const flam3_iter_helper * const f, do
double a, r, sa, ca;
int sl;
- sl = (int) (flam3_random_isaac_01(f->rc) * f->xform->pie_slices + 0.5);
+ sl = (int) (rand_d01(f->rc) * f->xform->pie_slices + 0.5);
a = f->xform->pie_rotation +
- 2.0 * M_PI * (sl + flam3_random_isaac_01(f->rc) * f->xform->pie_thickness) / f->xform->pie_slices;
- r = weight * flam3_random_isaac_01(f->rc);
+ 2.0 * M_PI * (sl + rand_d01(f->rc) * f->xform->pie_thickness) / f->xform->pie_slices;
+ r = weight * rand_d01(f->rc);
sincos(a,&sa,&ca);
return r * (double2) { ca, sa };
@@ -836,7 +836,7 @@ static double2 var41_arch(const double2 in, const flam3_iter_helper * const f, d
* it may change or even be removed in future versions of flam3.
*/
- double ang = flam3_random_isaac_01(f->rc) * weight * M_PI;
+ double ang = rand_d01(f->rc) * weight * M_PI;
double sinr,cosr;
sincos(ang,&sinr,&cosr);
@@ -869,8 +869,8 @@ static double2 var43_square(const double2 in, const flam3_iter_helper * const f,
*/
return weight * ((double2) {
- flam3_random_isaac_01(f->rc),
- flam3_random_isaac_01(f->rc),
+ rand_d01(f->rc),
+ rand_d01(f->rc),
} - 0.5);
}
@@ -896,7 +896,7 @@ static double2 var44_rays(const double2 in, const flam3_iter_helper * const f, d
* it may change or even be removed in future versions of flam3.
*/
- double ang = weight * flam3_random_isaac_01(f->rc) * M_PI;
+ double ang = weight * rand_d01(f->rc) * M_PI;
double r = weight / (f->precalc_sumsq + EPS);
double tanr = weight * tan(ang) * r;
@@ -925,7 +925,7 @@ static double2 var45_blade(const double2 in, const flam3_iter_helper * const f,
* it may change or even be removed in future versions of flam3.
*/
- double r = flam3_random_isaac_01(f->rc) * weight * f->precalc_sqrt;
+ double r = rand_d01(f->rc) * weight * f->precalc_sqrt;
double sinr,cosr;
sincos(r,&sinr,&cosr);
@@ -972,7 +972,7 @@ static double2 var47_twintrian(const double2 in, const flam3_iter_helper * const
* it may change or even be removed in future versions of flam3.
*/
- double r = flam3_random_isaac_01(f->rc) * weight * f->precalc_sqrt;
+ double r = rand_d01(f->rc) * weight * f->precalc_sqrt;
double sinr,cosr,diff;
sincos(r,&sinr,&cosr);
@@ -1064,7 +1064,7 @@ static double2 var50_supershape(const double2 in, const flam3_iter_helper * cons
myrnd = f->xform->super_shape_rnd;
- r = weight * ( (myrnd*flam3_random_isaac_01(f->rc) + (1.0-myrnd)*f->precalc_sqrt) - f->xform->super_shape_holes)
+ r = weight * ( (myrnd*rand_d01(f->rc) + (1.0-myrnd)*f->precalc_sqrt) - f->xform->super_shape_holes)
* pow(t1+t2,f->xform->super_shape_pneg1_n1) / f->precalc_sqrt;
return r * in;
@@ -1078,7 +1078,7 @@ static double2 var51_flower(const double2 in, const flam3_iter_helper * const f,
FPy^ := FPy^ + vvar*r*sin(theta);*/
double theta = f->precalc_atanyx;
- double r = weight * (flam3_random_isaac_01(f->rc) - f->xform->flower_holes) *
+ double r = weight * (rand_d01(f->rc) - f->xform->flower_holes) *
cos(f->xform->flower_petals*theta) / f->precalc_sqrt;
return r * in;
@@ -1092,7 +1092,7 @@ static double2 var52_conic(const double2 in, const flam3_iter_helper * const f,
FPy^ := FPy^ + vvar*r*sin(theta); */
double ct = in[0] / f->precalc_sqrt;
- double r = weight * (flam3_random_isaac_01(f->rc) - f->xform->conic_holes) *
+ double r = weight * (rand_d01(f->rc) - f->xform->conic_holes) *
f->xform->conic_eccentricity / (1 + f->xform->conic_eccentricity*ct) / f->precalc_sqrt;
return r * in;
@@ -1110,8 +1110,8 @@ static double2 var53_parabola(const double2 in, const flam3_iter_helper * const
sincos(r,&sr,&cr);
return weight * (double2) {
- f->xform->parabola_height * sr*sr * flam3_random_isaac_01(f->rc),
- f->xform->parabola_width * cr * flam3_random_isaac_01(f->rc),
+ f->xform->parabola_height * sr*sr * rand_d01(f->rc),
+ f->xform->parabola_width * cr * rand_d01(f->rc),
};
}
@@ -1154,7 +1154,7 @@ static double2 var56_boarders (const double2 in, const flam3_iter_helper * const
double2 round = (double2) { rint(in[0]), rint(in[1]) };
double2 offset = in - round;
- if (flam3_random_isaac_01(f->rc) >= 0.75) {
+ if (rand_d01(f->rc) >= 0.75) {
return weight*(offset*0.5 + round);
} else {
@@ -1232,7 +1232,7 @@ static double2 var59_cpow (const double2 in, const flam3_iter_helper * const f,
double va = 2.0 * M_PI / f->xform->cpow_power;
double vc = f->xform->cpow_r / f->xform->cpow_power;
double vd = f->xform->cpow_i / f->xform->cpow_power;
- double ang = vc*a + vd*lnr + va*floor(f->xform->cpow_power*flam3_random_isaac_01(f->rc));
+ double ang = vc*a + vd*lnr + va*floor(f->xform->cpow_power*rand_d01(f->rc));
double sa,ca;
double m = weight * exp(vc * lnr - vd * a);
@@ -1414,9 +1414,9 @@ static double2 var67_pre_blur (const double2 in, const flam3_iter_helper * const
/* pre-xform: PreBlur (Apo 2.08) */
/* Get pseudo-gaussian */
- double rndG = weight * (flam3_random_isaac_01(f->rc) + flam3_random_isaac_01(f->rc)
- + flam3_random_isaac_01(f->rc) + flam3_random_isaac_01(f->rc) - 2.0);
- double rndA = flam3_random_isaac_01(f->rc) * 2.0 * M_PI;
+ double rndG = weight * (rand_d01(f->rc) + rand_d01(f->rc)
+ + rand_d01(f->rc) + rand_d01(f->rc) - 2.0);
+ double rndA = rand_d01(f->rc) * 2.0 * M_PI;
double sinA,cosA;
sincos(rndA,&sinA,&cosA);
@@ -1597,7 +1597,7 @@ static double2 var78_wedge_julia (const double2 in, const flam3_iter_helper * co
/* wedge_julia from apo plugin pack */
double r = weight * pow(f->precalc_sumsq, f->xform->wedgeJulia_cn);
- int t_rnd = (int)((f->xform->wedgeJulia_rN)*flam3_random_isaac_01(f->rc));
+ int t_rnd = (int)((f->xform->wedgeJulia_rN)*rand_d01(f->rc));
double a = (f->precalc_atanyx + 2 * M_PI * t_rnd) / f->xform->wedge_julia_power;
double c = floor( (f->xform->wedge_julia_count * a + M_PI)*M_1_PI*0.5 );
double sa,ca;
@@ -2304,7 +2304,7 @@ int apply_xform(flam3_genome *cp, int fn, const double4 p, double4 *q_ret, randc
/* Check for badvalues and return randoms if bad */
if (badvalue(q01[0]) || badvalue(q01[1])) {
- *q_ret = (double4) { flam3_random_isaac_11(rc), flam3_random_isaac_11(rc), q23[0], q23[1] };
+ *q_ret = (double4) { rand_d11(rc), rand_d11(rc), q23[0], q23[1] };
return(1);
} else {
*q_ret = (double4) { q01[0], q01[1], q23[0], q23[1] };
diff --git a/wscript b/wscript
index 91e636f..a03c295 100644
--- a/wscript
+++ b/wscript
@@ -19,7 +19,7 @@ def configure(conf):
conf.write_config_header ('config.h')
def build(bld):
- bld.stlib (features='c cstlib', source='flam3.c filters.c parser.c variations.c interpolation.c palettes.c png.c xorshift.c docstring.c', target='libflam3', use='xml2 png pthread', includes='.')
+ bld.stlib (features='c cstlib', source='flam3.c filters.c parser.c variations.c interpolation.c palettes.c png.c random.c docstring.c', target='libflam3', use='xml2 png pthread', includes='.')
bld.program (features='c cprogram', source='flam3-render.c', target='flam3-render', use='libflam3 xml2 png amdlibm pthread', includes='.')
bld.program (features='c cprogram', source='flam3-genome.c', target='flam3-genome', use='libflam3 xml2 png amdlibm pthread', includes='.')
bld.program (features='c cprogram', source='flam3-animate.c', target='flam3-animate', use='libflam3 xml2 png amdlibm pthread', includes='.')
diff --git a/xorshift.c b/xorshift.c
deleted file mode 100644
index 9291b90..0000000
--- a/xorshift.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* “An experimental exploration of Marsaglia’s xorshift generators,
- * scrambled”, Sebastiano Vigna */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-
-#include "xorshift.h"
-
-uint64_t xorshift_step (randctx * const st) {
- uint64_t s0 = st->s[ st->p ];
- uint64_t s1 = st->s[ st->p = ( st->p + 1 ) & (XORSHIFT_S-1) ];
- s1 ^= s1 << 31; // a
- s1 ^= s1 >> 11; // b
- s0 ^= s0 >> 30; // c
- return ( st->s[ st->p ] = s0 ^ s1 ) * 1181783497276652981LL;
-}
-
-static uint64_t rand64 () {
- unsigned long long rand;
- while (!__builtin_ia32_rdrand64_step (&rand));
- return rand;
-}
-
-void xorshift_seed (randctx * const st) {
- /* seed with high-quality randomness */
- for (unsigned char i = 0; i < XORSHIFT_S; i++) {
- st->s[i] = rand64 ();
- }
-}
-
-#if 0
-uint64_t xorshift_step (randctx * const st) {
- uint64_t x = st->s[0];
- x ^= x >> 12; // a
- x ^= x << 25; // b
- x ^= x >> 27; // c
- st->s[0] = x;
- return x * 2685821657736338717LL;
-}
-#endif
-
diff --git a/xorshift.h b/xorshift.h
deleted file mode 100644
index 64c3ea2..0000000
--- a/xorshift.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-#define XORSHIFT_S 16
-
-typedef struct {
- uint64_t s[XORSHIFT_S];
- int p;
-} randctx;
-
-uint64_t xorshift_step (randctx * const st);
-void xorshift_seed (randctx * const st);
-