1 /* 2 ** This is a standalone module and exists independently of the original Rmath module. 3 ** As so it is being released under the Boost Software License 1.0. 4 ** Author: Chibisi Chima-Okereke 5 ** Date: 2017-08-08 6 ** 7 */ 8 9 module rmathd.rng.rng; 10 11 import std.random; 12 13 static bool seedSet = false; 14 static bool userSeed = false; 15 static uint randomSeed = 0; 16 17 void set_seed(uint _seed) 18 { 19 randomSeed = _seed; 20 userSeed = true; 21 seedSet = false; 22 } 23 24 void seed_set() 25 { 26 seedSet = true; 27 } 28 29 void get_seed(ref uint _seed) 30 { 31 _seed = randomSeed; 32 } 33 34 class RandomNumberGenerator{ 35 immutable(string) RNGName; 36 this() 37 { 38 RNGName = "default"; 39 } 40 this(immutable(string) name) 41 { 42 RNGName = name; 43 } 44 } 45 class MT19937: RandomNumberGenerator 46 { 47 immutable(string) RNGName; 48 Mt19937 engine; 49 this(){ 50 super("MT19937"); 51 RNGName = "MT19937"; 52 } 53 this(immutable(string) name){ 54 super("MT19937"); 55 RNGName = "MT19937"; 56 } 57 } 58 class MT1993764: RandomNumberGenerator 59 { 60 immutable(string) RNGName; 61 Mt19937_64 engine; 62 this(){ 63 super("MT1993764"); 64 RNGName = "MT1993764"; 65 } 66 this(immutable(string) name){ 67 super("MT1993764"); 68 RNGName = "MT1993764"; 69 } 70 } 71 class MINSTDRAND: RandomNumberGenerator 72 { 73 immutable(string) RNGName; 74 MinstdRand engine; 75 this(){ 76 super("MINSTDRAND"); 77 RNGName = "MINSTDRAND"; 78 } 79 this(immutable(string) name){ 80 super("MINSTDRAND"); 81 RNGName = "MINSTDRAND"; 82 } 83 } 84 class MINSTDRAND0: RandomNumberGenerator 85 { 86 immutable(string) RNGName; 87 MinstdRand0 engine; 88 this(){ 89 super("MINSTDRAND0"); 90 RNGName = "MINSTDRAND0"; 91 } 92 this(immutable(string) name){ 93 super("MINSTDRAND0"); 94 RNGName = "MINSTDRAND0"; 95 } 96 } 97 98 __gshared static RandomNumberGenerator threadRNG = new MT1993764(); 99 100 void setRNG(RNG: RandomNumberGenerator)(RNG rng) 101 { 102 threadRNG = rng; 103 } 104 105 immutable(string) gen_rand_num_code() 106 { 107 return `if(!seedSet && userSeed){ 108 Rng.engine.seed(randomSeed); 109 seed_set(); 110 }else if(!seedSet && !userSeed){ 111 Rng.engine.seed(unpredictableSeed); 112 seed_set(); 113 } 114 auto output = uniform!("[]", T, T)(lower, upper, Rng.engine); 115 return output;`; 116 } 117 118 auto rand(T = double)(T lower = 0.0, T upper = 1.0) 119 { 120 if(threadRNG.RNGName == "MT19937"){ 121 MT19937 Rng = cast(MT19937)threadRNG; 122 mixin (gen_rand_num_code()); 123 } 124 else if(threadRNG.RNGName == "MT1993764"){ 125 MT1993764 Rng = cast(MT1993764)threadRNG; 126 mixin (gen_rand_num_code()); 127 } 128 else if(threadRNG.RNGName == "MINSTDRAND"){ 129 MINSTDRAND Rng = cast(MINSTDRAND)threadRNG; 130 mixin (gen_rand_num_code()); 131 } 132 else if(threadRNG.RNGName == "MINSTDRAND0"){ 133 MINSTDRAND0 Rng = cast(MINSTDRAND0)threadRNG; 134 mixin (gen_rand_num_code()); 135 } 136 else{ 137 MT1993764 Rng = cast(MT1993764)threadRNG; 138 mixin (gen_rand_num_code()); 139 } 140 }