IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 17, 2009, 12:08:50 PM (17 years ago)
Author:
beaumont
Message:

merged with head

Location:
branches/cnb_branches/cnb_branch_20090301
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/cnb_branches/cnb_branch_20090301

  • branches/cnb_branches/cnb_branch_20090301/psLib/src/math/psRandom.c

    r20547 r23352  
    2929#include <inttypes.h>
    3030
     31#include "psAbort.h"
    3132#include "psMemory.h"
    3233#include "psRandom.h"
     
    3839
    3940
     41unsigned long seed = 0;                 // Seed for RNG
     42
     43
    4044psU64 p_psRandomGetSystemSeed(bool log)
    4145{
    42     FILE*  fd;
    43     psU64  seedVal = 0;
    44     time_t timeVal;
     46    psU64 seedVal = 0;                  // Seed value to return
    4547
    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        }
    5561    }
    5662
     
    6369}
    6470
    65 psRandom *psRandomAlloc(psRandomType type,
    66                         unsigned long seed)
     71psU64 psRandomSeed(psU64 value)
    6772{
    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}
    7079
     80// Destructor for psRandom
     81static void randomFree(psRandom *rng)
     82{
     83    if (rng->gsl) {
     84        gsl_rng_free(rng->gsl);
     85    }
     86    return;
     87}
     88
     89// Constructor for psRandom
     90static 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
    7198    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;
    82101        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);
    86104        break;
    87105    }
    88106
    89     return(myRNG);
     107    rng->gsl = gsl_rng_alloc(gslType);
     108    return rng;
    90109}
    91110
    92 void psRandomReset(psRandom *rand,
    93                    unsigned long seed)
     111psRandom *psRandomAlloc(psRandomType type)
    94112{
    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
     119psRandom *psRandomAllocSpecific(psRandomType type, psU64 specificSeed)
     120{
     121    psRandom *rng = randomAlloc(type);
     122    if (specificSeed == 0) {
     123        specificSeed = p_psRandomGetSystemSeed(true);
    107124    }
     125    gsl_rng_set(rng->gsl, specificSeed);
     126    return rng;
     127}
     128
     129bool 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;
    108137}
    109138
    110139double psRandomUniform(const psRandom *r)
    111140{
    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);
    121143}
    122144
    123145double psRandomGaussian(const psRandom *r)
    124146{
    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);
    135149}
    136150
    137151double p_psRandomGaussian(const psRandom *r, double sigma)
    138152{
    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);
    148155}
    149156
    150157double psRandomPoisson(const psRandom *r, double mean)
    151158{
    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);
    161161}
    162162
Note: See TracChangeset for help on using the changeset viewer.