From 005fb3f163838659dd064795aaa92a98fde42fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Fri, 24 Mar 2023 14:56:09 +0100 Subject: [PATCH 1/8] variable: parse randomseed() function. --- src/variable.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++---- src/variable.h | 2 ++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 6e44a8f5a..f6068f2bd 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -99,7 +99,7 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY, SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2, RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,STRIDE, VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK, - VALUE,ATOMARRAY,TYPEARRAY,INTARRAY}; + VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,RANDOMSEED}; // customize by adding a special function @@ -1673,7 +1673,8 @@ double Variable::evaluate(char *str, Tree **tree) atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(), ramp(x,y),stagger(x,y),logfreq(x,y,z),stride(x,y,z), vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z), - gmask(x),rmask(x),grmask(x,y) + gmask(x),rmask(x),grmask(x,y), + randomseed() ---------------------------------------------------------------------- */ double Variable::collapse_tree(Tree *tree) @@ -2107,6 +2108,17 @@ double Variable::collapse_tree(Tree *tree) return tree->value; } + if (tree->type == RANDOMSEED) { + arg1 = collapse_tree(tree->left); + if (tree->left->type != VALUE || arg1 != 0){ + error->one(FLERR,"The argument of randomseed() must be 0"); + } + + tree->type = VALUE; + tree->value = random_seed(); + return tree->value; + } + // mask functions do not become a single collapsed value if (tree->type == GMASK) return 0.0; @@ -2124,7 +2136,8 @@ double Variable::collapse_tree(Tree *tree) atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(), ramp(x,y),stagger(x,y),logfreq(x,y,z),stride(x,y,z), vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z), - gmask(x),rmask(x),grmask(x,y) + gmask(x),rmask(x),grmask(x,y), + randomseed() ---------------------------------------------------------------------- */ double Variable::eval_tree(Tree *tree, int i) @@ -2368,6 +2381,14 @@ double Variable::eval_tree(Tree *tree, int i) return arg; } + if (tree->type == RANDOMSEED){ + arg1 = eval_tree(tree->left,i); + if (arg1 != 0.0) + error->one(FLERR,"The argument of randomseed() must be 0"); + + return random_seed(); + } + if (tree->type == GMASK) { if (atom->mask[i] & tree->ivalue1) return 1.0; else return 0.0; @@ -2496,7 +2517,8 @@ int Variable::math_function(char *word, char *contents, Tree **tree, strcmp(word,"ramp") && strcmp(word,"stagger") && strcmp(word,"logfreq") && strcmp(word,"stride") && strcmp(word,"vdisplace") && - strcmp(word,"swiggle") && strcmp(word,"cwiggle")) + strcmp(word,"swiggle") && strcmp(word,"cwiggle") && + strcmp(word,"randomseed")) return 0; // parse contents for arg1,arg2,arg3 separated by commas @@ -2819,6 +2841,12 @@ int Variable::math_function(char *word, char *contents, Tree **tree, double value = value1 + value2*(1.0-cos(omega*delta*update->dt)); argstack[nargstack++] = value; } + + } else if (strcmp(word,"randomseed") == 0) { + if (narg != 1) + error->all(FLERR,"Invalid math function in variable formula"); + if (tree) newtree->type = RANDOMSEED; + else argstack[nargstack++] = random_seed(); } delete [] arg1; @@ -3931,6 +3959,18 @@ unsigned int Variable::data_mask(char *str) return datamask; } + +/* ---------------------------------------------------------------------- + generates a randim prime number between 10'000 and INT_MAX +------------------------------------------------------------------------- */ +int Variable::random_seed(){ + int seed = 1; + + printf("random seed generated: %d\n", seed); + + return seed; +} + /* ---------------------------------------------------------------------- class to read variable values from a file for flag = SCALARFILE, reads one value per line diff --git a/src/variable.h b/src/variable.h index 328bfbafa..b362bc762 100644 --- a/src/variable.h +++ b/src/variable.h @@ -128,6 +128,8 @@ class Variable : protected Pointers { int inumeric(char *); char *find_next_comma(char *); void print_tree(Tree *, int); + + int random_seed(); }; class VarReader : protected Pointers { From 639ad73531d1056b3732b0f37b477850bba0c67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Fri, 24 Mar 2023 15:25:02 +0100 Subject: [PATCH 2/8] variable: implement randomseed(). --- src/variable.cpp | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index f6068f2bd..71dcc8e9f 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -69,6 +69,9 @@ #include "memory.h" #include "error.h" #include "force.h" +#include "math_extra_liggghts.h" +#include "stdlib.h" +#include "time.h" #if defined(_WIN32) || defined(_WIN64) #include @@ -138,6 +141,9 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp) precedence[MULTIPLY] = precedence[DIVIDE] = precedence[MODULO] = 6; precedence[CARAT] = 7; precedence[UNARY] = precedence[NOT] = 8; + + // NOTE: better random generator for random_seed()? + srand(time(NULL)); } /* ---------------------------------------------------------------------- */ @@ -3961,12 +3967,33 @@ unsigned int Variable::data_mask(char *str) /* ---------------------------------------------------------------------- - generates a randim prime number between 10'000 and INT_MAX + generates a random prime number between 10'000 and INT_MAX + + rand() is not the best, a more optimal soultion would be: + + #define FIRTS_PRIME 10007 // first prime greather than 10'000 + #define LAST_PRIME 2147483647 // last prime less than INT_MAX + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist(FIRTS_PRIME, LAST_PRIME); + seed = dist(rng); + + but it depends on C++11, so the backward compatibility would be lost ------------------------------------------------------------------------- */ int Variable::random_seed(){ - int seed = 1; + int seed = 0; + + static const int FIRTS_PRIME = 10007; + static const int LAST_PRIME = 2147483647; + static const int SEED_RANGE = (LAST_PRIME - FIRTS_PRIME); + + if(me == 0){ + while(!MathExtraLiggghts::isPrime(seed)){ + seed = (rand() % SEED_RANGE) + FIRTS_PRIME; + } + } - printf("random seed generated: %d\n", seed); + MPI_Bcast(&seed,1,MPI_INT,0,world); return seed; } From 4fd218fcf613fdcbb761d3172b1ffbc98d18354b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Fri, 24 Mar 2023 15:44:24 +0100 Subject: [PATCH 3/8] variable: clean up randomseed(). --- src/variable.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 71dcc8e9f..6791fd798 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -2115,11 +2115,8 @@ double Variable::collapse_tree(Tree *tree) } if (tree->type == RANDOMSEED) { - arg1 = collapse_tree(tree->left); - if (tree->left->type != VALUE || arg1 != 0){ - error->one(FLERR,"The argument of randomseed() must be 0"); - } - + // parser does not allow functions with 0 arguments + // the value of the argument does not matter in this case tree->type = VALUE; tree->value = random_seed(); return tree->value; @@ -2388,10 +2385,6 @@ double Variable::eval_tree(Tree *tree, int i) } if (tree->type == RANDOMSEED){ - arg1 = eval_tree(tree->left,i); - if (arg1 != 0.0) - error->one(FLERR,"The argument of randomseed() must be 0"); - return random_seed(); } @@ -2850,7 +2843,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"randomseed") == 0) { if (narg != 1) - error->all(FLERR,"Invalid math function in variable formula"); + error->all(FLERR,"randomseed() must be called whith 1 argument"); if (tree) newtree->type = RANDOMSEED; else argstack[nargstack++] = random_seed(); } From c5eabe06482904310aa0bcd5ee10c63b88eda24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Mon, 27 Mar 2023 08:57:14 +0200 Subject: [PATCH 4/8] Variable: move srand() to LAMMPS initialization. --- src/lammps.cpp | 11 +++++++++++ src/variable.cpp | 7 ++----- src/variable.h | 2 ++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/lammps.cpp b/src/lammps.cpp index 1c347ad37..95e8f9c35 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -47,6 +47,8 @@ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. + + Tóth János (MATE, Gödöllő) ------------------------------------------------------------------------- */ #include @@ -86,6 +88,9 @@ #include "error.h" #include "granular_styles.h" +#include +#include + using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- @@ -559,6 +564,12 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) input->one(cmd); error->done(); } + + // used in Variable::random_seed() + if(me == 0){ + // NOTE: better random generator for random_seed()? + srand(time(NULL)); + } } /* ---------------------------------------------------------------------- diff --git a/src/variable.cpp b/src/variable.cpp index 6791fd798..40a7afc9b 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -41,6 +41,8 @@ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. + + Tóth János (MATE, Gödöllő) ------------------------------------------------------------------------- */ #include @@ -70,8 +72,6 @@ #include "error.h" #include "force.h" #include "math_extra_liggghts.h" -#include "stdlib.h" -#include "time.h" #if defined(_WIN32) || defined(_WIN64) #include @@ -141,9 +141,6 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp) precedence[MULTIPLY] = precedence[DIVIDE] = precedence[MODULO] = 6; precedence[CARAT] = 7; precedence[UNARY] = precedence[NOT] = 8; - - // NOTE: better random generator for random_seed()? - srand(time(NULL)); } /* ---------------------------------------------------------------------- */ diff --git a/src/variable.h b/src/variable.h index b362bc762..c0a8e978d 100644 --- a/src/variable.h +++ b/src/variable.h @@ -41,6 +41,8 @@ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. + + Tóth János (MATE, Gödöllő) ------------------------------------------------------------------------- */ #ifndef LMP_VARIABLE_H From f9e92520248bc982a47ebb944b9362cee99db50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Mon, 27 Mar 2023 09:06:20 +0200 Subject: [PATCH 5/8] doc: Add randomseed(). --- doc/variable.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/variable.txt b/doc/variable.txt index 8208c8a90..d0c2812e1 100644 --- a/doc/variable.txt +++ b/doc/variable.txt @@ -46,7 +46,8 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st math functions = sqrt(x), exp(x), ln(x), log(x), abs(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x) - ramp(x,y), stagger(x,y), logfreq(x,y,z), stride(x,y,z), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z) + ramp(x,y), stagger(x,y), logfreq(x,y,z), stride(x,y,z), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z), + randomseed(0) group functions = count(group), mass(group), charge(group), xcm(group,dim), vcm(group,dim), fcm(group,dim), bound(group,xmin), gyration(group), ke(group), @@ -553,6 +554,11 @@ the {start} keyword of the "run"_run.html command. See the "thermo_style"_thermo_style.html keyword elaplong = timestep-startstep. +The randomseed(0) function generates a random prime number between 10000 and +INT_MAX (2147483647). The output of this function can be used to be the seed of +particletemplate, particledistribution, etc. The argument of the function is not +used, it is there because the parser cannot handle functions without arguments. + :line Group and Region Functions :h4 From fa19e6e05faeb7629d5e77d5c301bd92b304e1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Mon, 27 Mar 2023 09:08:15 +0200 Subject: [PATCH 6/8] variable: fix range in random_seed(). --- src/variable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variable.cpp b/src/variable.cpp index 40a7afc9b..51618311a 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -3975,7 +3975,7 @@ int Variable::random_seed(){ static const int FIRTS_PRIME = 10007; static const int LAST_PRIME = 2147483647; - static const int SEED_RANGE = (LAST_PRIME - FIRTS_PRIME); + static const int SEED_RANGE = (LAST_PRIME - FIRTS_PRIME) + 1; if(me == 0){ while(!MathExtraLiggghts::isPrime(seed)){ From 86e3f9559d8e989fcc1e9cc4ab0714265e0bf18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Mon, 27 Mar 2023 11:41:13 +0200 Subject: [PATCH 7/8] Variable: fix typo. --- src/variable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variable.cpp b/src/variable.cpp index 51618311a..5ac4791bf 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -2840,7 +2840,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, } else if (strcmp(word,"randomseed") == 0) { if (narg != 1) - error->all(FLERR,"randomseed() must be called whith 1 argument"); + error->all(FLERR,"randomseed() must be called with 1 argument"); if (tree) newtree->type = RANDOMSEED; else argstack[nargstack++] = random_seed(); } From c920d5ccd81c2ca69ebeb54bd7edc67b178d134f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=B3th=20J=C3=A1nos?= Date: Wed, 3 May 2023 15:24:50 +0200 Subject: [PATCH 8/8] variable: rework seed(n). --- doc/variable.txt | 9 +-- src/variable.cpp | 150 +++++++++++++++++++++++++++++++++++++---------- src/variable.h | 2 +- 3 files changed, 126 insertions(+), 35 deletions(-) diff --git a/doc/variable.txt b/doc/variable.txt index d0c2812e1..7fd1a27c5 100644 --- a/doc/variable.txt +++ b/doc/variable.txt @@ -47,7 +47,7 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x) ramp(x,y), stagger(x,y), logfreq(x,y,z), stride(x,y,z), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z), - randomseed(0) + seed(n) group functions = count(group), mass(group), charge(group), xcm(group,dim), vcm(group,dim), fcm(group,dim), bound(group,xmin), gyration(group), ke(group), @@ -554,10 +554,11 @@ the {start} keyword of the "run"_run.html command. See the "thermo_style"_thermo_style.html keyword elaplong = timestep-startstep. -The randomseed(0) function generates a random prime number between 10000 and +The seed(n) function generates a prime number between 10000 and INT_MAX (2147483647). The output of this function can be used to be the seed of -particletemplate, particledistribution, etc. The argument of the function is not -used, it is there because the parser cannot handle functions without arguments. +particletemplate, particledistribution, etc. +If the argument is 0, a random prime number is generated, else the n-th greater, +than 10000 prime (n = 1 -> 10007, n = 2 -> 10009, etc) is the output. :line diff --git a/src/variable.cpp b/src/variable.cpp index 5ac4791bf..dd1e4a9ef 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -102,7 +102,7 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY, SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2, RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,STRIDE, VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK, - VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,RANDOMSEED}; + VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,SEED}; // customize by adding a special function @@ -1677,7 +1677,7 @@ double Variable::evaluate(char *str, Tree **tree) ramp(x,y),stagger(x,y),logfreq(x,y,z),stride(x,y,z), vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z), gmask(x),rmask(x),grmask(x,y), - randomseed() + seed(n) ---------------------------------------------------------------------- */ double Variable::collapse_tree(Tree *tree) @@ -2111,11 +2111,14 @@ double Variable::collapse_tree(Tree *tree) return tree->value; } - if (tree->type == RANDOMSEED) { - // parser does not allow functions with 0 arguments - // the value of the argument does not matter in this case + if (tree->type == SEED) { + int ivalue1 = static_cast (collapse_tree(tree->left)); + + if (ivalue1 < 0) + error->one(FLERR,"seed() must be called with a non-negative argument (>= 0)"); + tree->type = VALUE; - tree->value = random_seed(); + tree->value = generate_seed(ivalue1); return tree->value; } @@ -2137,7 +2140,7 @@ double Variable::collapse_tree(Tree *tree) ramp(x,y),stagger(x,y),logfreq(x,y,z),stride(x,y,z), vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z), gmask(x),rmask(x),grmask(x,y), - randomseed() + seed(n) ---------------------------------------------------------------------- */ double Variable::eval_tree(Tree *tree, int i) @@ -2381,8 +2384,13 @@ double Variable::eval_tree(Tree *tree, int i) return arg; } - if (tree->type == RANDOMSEED){ - return random_seed(); + if (tree->type == SEED){ + int ivalue1 = static_cast (eval_tree(tree->left,i)); + + if (ivalue1 < 0) + error->one(FLERR,"seed() must be called with a non-negative argument (>= 0)"); + + return generate_seed(ivalue1); } if (tree->type == GMASK) { @@ -2514,7 +2522,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree, strcmp(word,"logfreq") && strcmp(word,"stride") && strcmp(word,"vdisplace") && strcmp(word,"swiggle") && strcmp(word,"cwiggle") && - strcmp(word,"randomseed")) + strcmp(word,"seed")) return 0; // parse contents for arg1,arg2,arg3 separated by commas @@ -2838,11 +2846,18 @@ int Variable::math_function(char *word, char *contents, Tree **tree, argstack[nargstack++] = value; } - } else if (strcmp(word,"randomseed") == 0) { + } else if (strcmp(word,"seed") == 0) { if (narg != 1) - error->all(FLERR,"randomseed() must be called with 1 argument"); - if (tree) newtree->type = RANDOMSEED; - else argstack[nargstack++] = random_seed(); + error->all(FLERR,"seed() must be called with 1 argument"); + if (tree) newtree->type = SEED; + else { + int ivalue1 = static_cast (value1); + + if(ivalue1 < 0) + error->all(FLERR,"seed() must be called with a non-negative argument (>= 0)"); + + argstack[nargstack++] = generate_seed(ivalue1); + } } delete [] arg1; @@ -3955,31 +3970,106 @@ unsigned int Variable::data_mask(char *str) return datamask; } - /* ---------------------------------------------------------------------- generates a random prime number between 10'000 and INT_MAX + in a form of 6k +- 1 +------------------------------------------------------------------------- */ +static int generate_random_seed(){ + static const int MIN_K = 1678; // 6*1678-1 = 10067, prime + static const int MAX_K = 357913904; // 6*357913904-1 = 2147483423, prime - rand() is not the best, a more optimal soultion would be: + static const int RANGE_K = MAX_K - MIN_K + 1; - #define FIRTS_PRIME 10007 // first prime greather than 10'000 - #define LAST_PRIME 2147483647 // last prime less than INT_MAX - std::random_device dev; - std::mt19937 rng(dev()); - std::uniform_int_distribution dist(FIRTS_PRIME, LAST_PRIME); - seed = dist(rng); + int p = 0; - but it depends on C++11, so the backward compatibility would be lost + // it will find a prime + while(true){ + int k = (rand() % RANGE_K) + MIN_K; + p = 6 * k - 1; + + if(MathExtraLiggghts::isPrime(p)){ + break; + } + + p += 2; + + if(MathExtraLiggghts::isPrime(p)){ + break; + } + } + + return p; +} + +/* + first 200 prime greater than 10'000: + */ +static const int PRIME_TABLE_COUNT = 200; +static const int PRIME_TABLE[PRIME_TABLE_COUNT] = { + 10007, 10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, + 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 10169, 10177, 10181, + 10193, 10211, 10223, 10243, 10247, 10253, 10259, 10267, 10271, 10273, 10289, + 10301, 10303, 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, 10391, + 10399, 10427, 10429, 10433, 10453, 10457, 10459, 10463, 10477, 10487, 10499, + 10501, 10513, 10529, 10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, + 10627, 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, + 10723, 10729, 10733, 10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, + 10847, 10853, 10859, 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, + 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 11027, 11047, 11057, + 11059, 11069, 11071, 11083, 11087, 11093, 11113, 11117, 11119, 11131, 11149, + 11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, 11257, + 11261, 11273, 11279, 11287, 11299, 11311, 11317, 11321, 11329, 11351, 11353, + 11369, 11383, 11393, 11399, 11411, 11423, 11437, 11443, 11447, 11467, 11471, + 11483, 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, 11579, 11587, + 11593, 11597, 11617, 11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, + 11717, 11719, 11731, 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, + 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, + 11923, 11927 +}; + +static int generate_nth_prime_impl(int n){ + int p = PRIME_TABLE[PRIME_TABLE_COUNT - 1]; + n -= PRIME_TABLE_COUNT; + + while(n > 0){ + p += 2; + + if(MathExtraLiggghts::isPrime(p)){ + n -= 1; + } + } + + return p; +} + +/* ---------------------------------------------------------------------- + gives the n-th prime number between 10'000 and INT_MAX + + n p + 1 10007 + 2 10009 + 3 10037 + ... ------------------------------------------------------------------------- */ -int Variable::random_seed(){ - int seed = 0; +static int generate_nth_prime(int n){ + // fast + if(n <= PRIME_TABLE_COUNT){ + return PRIME_TABLE[n-1]; + // small + } else { + return generate_nth_prime_impl(n); + } +} + +int Variable::generate_seed(int n){ - static const int FIRTS_PRIME = 10007; - static const int LAST_PRIME = 2147483647; - static const int SEED_RANGE = (LAST_PRIME - FIRTS_PRIME) + 1; + int seed = 0; if(me == 0){ - while(!MathExtraLiggghts::isPrime(seed)){ - seed = (rand() % SEED_RANGE) + FIRTS_PRIME; + if (n == 0){ + seed = generate_random_seed(); + } else { + seed = generate_nth_prime(n); } } diff --git a/src/variable.h b/src/variable.h index c0a8e978d..c538a770e 100644 --- a/src/variable.h +++ b/src/variable.h @@ -131,7 +131,7 @@ class Variable : protected Pointers { char *find_next_comma(char *); void print_tree(Tree *, int); - int random_seed(); + int generate_seed(int); }; class VarReader : protected Pointers {