From b9d887fc3cd3ae26c678bf35bc90c4f1d6b03888 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Fri, 13 Feb 2015 16:18:10 +0100 Subject: Unify prng use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Finally drop all isaac references, do not use system rng any more. Drop rng state from flam3_frame – it was not used anyway. --- docstring.c | 1 - flam3-animate.c | 7 +- flam3-genome.c | 72 +++++----- flam3-render.c | 6 +- flam3.c | 408 ++++++++++++++++++++++++-------------------------------- flam3.h | 32 ++--- interpolation.c | 7 +- interpolation.h | 2 +- palettes.c | 27 ++-- parser.c | 15 ++- parser.h | 4 +- private.h | 2 +- random.c | 63 +++++++++ random.h | 20 +++ rect.c | 12 +- variations.c | 68 +++++----- wscript | 2 +- xorshift.c | 44 ------ xorshift.h | 14 -- 19 files changed, 373 insertions(+), 433 deletions(-) create mode 100644 random.c create mode 100644 random.h delete mode 100644 xorshift.c delete mode 100644 xorshift.h 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("\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("\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("\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("\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 #include #include @@ -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)xform[cp->final_xform_index].opacity) { + rand_d01(rc)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()) && (nxform[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 #include -#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 + +#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 -#include -#include -#include -#include - -#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 - -#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); - -- cgit v1.2.3