- Timestamp:
- Mar 17, 2009, 12:08:50 PM (17 years ago)
- Location:
- branches/cnb_branches/cnb_branch_20090301
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psLib/src/math/psRandom.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/cnb_branches/cnb_branch_20090301
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk merged eligible /branches/eam_branches/eam_branch_20090303 23158-23228
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/cnb_branches/cnb_branch_20090301/psLib/src/math/psRandom.c
r20547 r23352 29 29 #include <inttypes.h> 30 30 31 #include "psAbort.h" 31 32 #include "psMemory.h" 32 33 #include "psRandom.h" … … 38 39 39 40 41 unsigned long seed = 0; // Seed for RNG 42 43 40 44 psU64 p_psRandomGetSystemSeed(bool log) 41 45 { 42 FILE* fd; 43 psU64 seedVal = 0; 44 time_t timeVal; 46 psU64 seedVal = 0; // Seed value to return 45 47 46 fd = fopen("/dev/urandom","r"); 47 if(fd == NULL) { 48 // Read system clock to get seed 49 seedVal = (psU64)time(&timeVal); 50 } else { 51 // Read urandom to get seed 52 if (fread(&seedVal, sizeof(psU64),1,fd)) {;} // ignore return value 53 // Close file 54 fclose(fd); 48 // Since zero is a special value in our context, don't allow the final value chosen to be zero 49 while (seedVal == 0) { 50 FILE *fd = fopen("/dev/urandom", "r"); 51 if (fd) { 52 // Read urandom to get seed 53 if (fread(&seedVal, sizeof(psU64), 1, fd)) {;} // ignore return value 54 // Close file 55 fclose(fd); 56 } else { 57 // Read system clock to get seed 58 time_t timeVal; // Time value 59 seedVal = (psU64)time(&timeVal); 60 } 55 61 } 56 62 … … 63 69 } 64 70 65 psRandom *psRandomAlloc(psRandomType type, 66 unsigned long seed) 71 psU64 psRandomSeed(psU64 value) 67 72 { 68 gsl_rng *r = NULL; 69 psRandom *myRNG = NULL; 73 while (value == 0) { 74 value = p_psRandomGetSystemSeed(false); 75 } 76 seed = value; 77 return seed; 78 } 70 79 80 // Destructor for psRandom 81 static void randomFree(psRandom *rng) 82 { 83 if (rng->gsl) { 84 gsl_rng_free(rng->gsl); 85 } 86 return; 87 } 88 89 // Constructor for psRandom 90 static psRandom *randomAlloc(psRandomType type) 91 { 92 psRandom *rng = psAlloc(sizeof(psRandom)); // Random number generator to return 93 psMemSetDeallocator(rng, (psFreeFunc)randomFree); 94 95 rng->type = type; 96 97 const gsl_rng_type *gslType; // Type of RNG according to GSL 71 98 switch (type) { 72 case PS_RANDOM_TAUS: 73 myRNG = (psRandom*)psAlloc(sizeof(psRandom)); 74 r = gsl_rng_alloc(gsl_rng_taus); 75 myRNG->gsl = r; 76 if(seed == 0) { 77 gsl_rng_set(myRNG->gsl, p_psRandomGetSystemSeed(true)); 78 } else { 79 gsl_rng_set(myRNG->gsl, seed); 80 } 81 myRNG->type = type; 99 case PS_RANDOM_TAUS: 100 gslType = gsl_rng_taus; 82 101 break; 83 84 default: 85 psError(PS_ERR_UNEXPECTED_NULL, true, _("Unknown Random Number Generator Type")); 102 default: 103 psAbort("Unknown Random Number Generator Type: %x", type); 86 104 break; 87 105 } 88 106 89 return(myRNG); 107 rng->gsl = gsl_rng_alloc(gslType); 108 return rng; 90 109 } 91 110 92 void psRandomReset(psRandom *rand, 93 unsigned long seed) 111 psRandom *psRandomAlloc(psRandomType type) 94 112 { 95 // Check null psRandom 96 if(rand==NULL) { 97 psError(PS_ERR_UNEXPECTED_NULL, 98 true, 99 _("Random variable is NULL.")); 100 } else { 101 // Check seed value to see if system seed should be used 102 if(seed == 0) { 103 gsl_rng_set(rand->gsl,p_psRandomGetSystemSeed(true)); 104 } else { 105 gsl_rng_set(rand->gsl, seed); 106 } 113 psRandom *rng = randomAlloc(type); 114 psRandomReset(rng); 115 116 return rng; 117 } 118 119 psRandom *psRandomAllocSpecific(psRandomType type, psU64 specificSeed) 120 { 121 psRandom *rng = randomAlloc(type); 122 if (specificSeed == 0) { 123 specificSeed = p_psRandomGetSystemSeed(true); 107 124 } 125 gsl_rng_set(rng->gsl, specificSeed); 126 return rng; 127 } 128 129 bool psRandomReset(psRandom *rand) 130 { 131 PS_ASSERT_RANDOM_NON_NULL(rand, false); 132 if (seed == 0) { 133 seed = p_psRandomGetSystemSeed(true); 134 } 135 gsl_rng_set(rand->gsl, seed); 136 return true; 108 137 } 109 138 110 139 double psRandomUniform(const psRandom *r) 111 140 { 112 // Check null psRandom variable 113 if(r == NULL) { 114 psError(PS_ERR_UNEXPECTED_NULL, 115 true, 116 _("Random variable is NULL.")); 117 return(0); 118 } else { 119 return(gsl_rng_uniform(r->gsl)); 120 } 141 PS_ASSERT_RANDOM_NON_NULL(r, NAN); 142 return gsl_rng_uniform(r->gsl); 121 143 } 122 144 123 145 double psRandomGaussian(const psRandom *r) 124 146 { 125 // Check null psRandom variable 126 if(r == NULL) { 127 psError(PS_ERR_UNEXPECTED_NULL, 128 true, 129 _("Random variable is NULL.")); 130 return(0); 131 } else { 132 // XXX: What should sigma be? 133 return(gsl_ran_gaussian(r->gsl, 1.0)); 134 } 147 PS_ASSERT_RANDOM_NON_NULL(r, NAN); 148 return gsl_ran_gaussian(r->gsl, 1.0); 135 149 } 136 150 137 151 double p_psRandomGaussian(const psRandom *r, double sigma) 138 152 { 139 // Check null psRandom variable 140 if(r == NULL) { 141 psError(PS_ERR_UNEXPECTED_NULL, 142 true, 143 _("Random variable is NULL.")); 144 return(0); 145 } else { 146 return(gsl_ran_gaussian(r->gsl, sigma)); 147 } 153 PS_ASSERT_RANDOM_NON_NULL(r, NAN); 154 return gsl_ran_gaussian(r->gsl, sigma); 148 155 } 149 156 150 157 double psRandomPoisson(const psRandom *r, double mean) 151 158 { 152 // Check null psRandom variable 153 if(r == NULL) { 154 psError(PS_ERR_UNEXPECTED_NULL, 155 true, 156 _("Random variable is NULL.")); 157 return(0); 158 } else { 159 return((psF64) gsl_ran_poisson(r->gsl, mean)); 160 } 159 PS_ASSERT_RANDOM_NON_NULL(r, NAN); 160 return gsl_ran_poisson(r->gsl, mean); 161 161 } 162 162
Note:
See TracChangeset
for help on using the changeset viewer.
