tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
rand.cc
1 // -*- mode: c++; fill-column: 80; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 /*
3  Copyright (c) 2010 Juan Jose Garcia Ripoll
4 
5  Tensor is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published
7  by the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Library General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include <cstdio>
21 #include <cstdlib>
22 #include <tensor/rand.h>
23 #include "mt.h"
24 
25 namespace tensor {
26 
27 static bool
28 initialize_mt()
29 {
30  rand_reseed();
31  return true;
32 }
33 
34 void rand_reseed() {
35  char *rand_seed = getenv("RANDSEED");
36  if (rand_seed) {
37  int seed = atoi(rand_seed);
38  std::cout << "RANDSEED=" << seed << std::endl;
39  init_genrand(seed);
40  return;
41  } else {
42  FILE *fp = fopen("/dev/urandom", "r");
43 #ifndef SEED_SIZE
44 #define SEED_SIZE 1
45 #endif
46  rand_uint seed[SEED_SIZE];
47  if (fp && (SEED_SIZE > 0)) {
48  fread(&seed, sizeof(rand_uint), SEED_SIZE, fp);
49  fclose(fp);
50  init_by_array(seed, SEED_SIZE);
51  } else {
52  int seed = time(0);
53  init_genrand(seed);
54  }
55  }
56  for (size_t i = 0; i < 624*10; i++) {
57  // Warm up
58  rand<long>();
59  }
60 }
61 
62 static bool mt_initialized = initialize_mt();
63 
64 #ifdef TENSOR_64BITS
65 template<> int rand<int>() { return genrand_int63(); }
66 template<> unsigned int rand<unsigned int>() { return genrand_int64(); }
67 template<> long rand<long>() { return genrand_int63(); }
68 template<> unsigned long rand<unsigned long>() { return genrand_int64(); }
69 #else
70 template<> int rand<int>() { return genrand_int31(); }
71 template<> unsigned int rand<unsigned int>() { return genrand_int32(); }
72 template<> long rand<long>() { return genrand_int31(); }
73 template<> unsigned long rand<unsigned long>() { return genrand_int32(); }
74 #endif
75 
76 template<> float rand<float>() {
77  return genrand_res53();
78 }
79 
80 template<> double rand<double>() {
81  return genrand_res53();
82 }
83 
84 template<> cdouble rand<cdouble>() {
85  return to_complex(genrand_res53(), genrand_res53());
86 }
87 
88 } // namespace rand