NEURON
mcran4.cpp
Go to the documentation of this file.
1 /*
2 The copyrighted code from Numerical Recipes Software has been removed
3 and replaced by an independent implementation found in the random.cpp file
4 in function Ranint4
5 from http://www.inference.phy.cam.ac.uk/bayesys/BayesSys.tar.gz
6 by John Skilling
7 http://www.inference.phy.cam.ac.uk/bayesys/
8 The code fragment was further modified by Michael Hines to change prototypes
9 and produce output identical to the old version. This code is now
10 placed under the General GNU Public License, version 2. The random.cpp file
11 contained the header:
12 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 // Filename: random.cpp
14 //
15 // Purpose: Random utility procedures for BayeSys3.
16 //
17 // History: Random.cpp 17 Nov 1994 - 13 Sep 2003
18 //
19 // Acknowledgments:
20 // "Numerical Recipes", Press et al, for ideas
21 // "Handbook of Mathematical Functions", Abramowitz and Stegun, for formulas
22 // Peter J Acklam website, for inverse normal code
23 //-----------------------------------------------------------------------------
24  Copyright (c) 1994-2003 Maximum Entropy Data Consultants Ltd,
25  114c Milton Road, Cambridge CB4 1XE, England
26 
27  This library is free software; you can redistribute it and/or
28  modify it under the terms of the GNU Lesser General Public
29  License as published by the Free Software Foundation; either
30  version 2.1 of the License, or (at your option) any later version.
31 
32  This library is distributed in the hope that it will be useful,
33  but WITHOUT ANY WARRANTY; without even the implied warranty of
34  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35  Lesser General Public License for more details.
36 
37  You should have received a copy of the GNU Lesser General Public
38  License along with this library; if not, write to the Free Software
39  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 */
41 
42 #include <stdio.h>
43 #include <stddef.h>
44 #include <math.h>
45 #include <float.h>
46 #include <stdlib.h>
47 #include "mcran4.h"
48 
49 static uint32_t lowindex = 0;
50 
51 double mcell_lowindex() {
52  return static_cast<double>(lowindex);
53 }
54 
55 void mcell_ran4_init(uint32_t low) {
56  lowindex = low;
57 }
58 
59 double mcell_ran4(uint32_t* high, double* x, unsigned int n, double range) {
60  int i;
61  for (i = 0; i < n; i++) {
62  x[i] = range * nrnRan4dbl(high, lowindex);
63  }
64  return x[0];
65 }
66 
67 double mcell_ran4a(uint32_t* high) {
68  return nrnRan4dbl(high, lowindex);
69 }
70 
71 uint32_t mcell_iran4(uint32_t* high) {
72  return nrnRan4int(high, lowindex);
73 }
74 
75 uint32_t nrnRan4int(uint32_t* idx1, uint32_t idx2) {
76  uint32_t u, v, w, m, n;
77  /* 64-bit hash */
78  n = (*idx1)++;
79  m = idx2;
80 
81  w = n ^ 0xbaa96887;
82  v = w >> 16;
83  w &= 0xffff;
84  u = ~((v - w) * (v + w));
85  /*m ^= (((u >> 16) | (u << 16)) ^ 0xb4f0c4a7) + w * v;*/
86  m ^= (((u >> 16) | (u << 16)) ^ 0x4b0f3b58) + w * v;
87 
88  w = m ^ 0x1e17d32c;
89  v = w >> 16;
90  w &= 0xffff;
91  u = ~((v - w) * (v + w));
92  /*n ^= (((u >> 16) | (u << 16)) ^ 0x178b0f3c) + w * v;*/
93  n ^= (((u >> 16) | (u << 16)) ^ 0xe874f0c3) + w * v;
94  return n;
95 }
96 
97 /*
98 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
99 // Function: Randouble (hines now nrnRan4dbl
100 //
101 // Purpose: Random double-precision floating-point sample.
102 // The 2^52 allowed values are odd multiples of 2^-53,
103 // symmetrically placed in strict interior of (0,1).
104 //
105 // Notes: (1) Tuned to 52-bit mantissa in "double" format.
106 // (2) Uses one call to Ranint to get 64 random bits, with extra
107 // random integer available in Rand[3].
108 // (3) All floating-point random calls are directed through this code,
109 // except Rangauss which uses the extra random integer in Rand[3].
110 //
111 // History: John Skilling 6 May 1995, 3 Dec 1995, 24 Aug 1996
112 // 20 Oct 2002, 17 Dec 2002
113 //-----------------------------------------------------------------------------
114 //
115 */
116 static const double SHIFT32 = 1.0 / 4294967296.0; /* 2^-32 */
117 double nrnRan4dbl(uint32_t* idx1, uint32_t idx2) {
118  uint32_t hi;
119  hi = (uint32_t) nrnRan4int(idx1, idx2); /*top 32 bits*/
120  /*
121  // lo = (extra // low bits
122  // & 0xfffff000) ^ 0x00000800; // switch lowest (2^-53) bit ON
123  // return ((double)hi + (double)lo * SHIFT32) * SHIFT32;
124  */
125  return ((double) hi) * SHIFT32;
126 }
#define v
Definition: md1redef.h:11
#define i
Definition: md1redef.h:19
constexpr auto range(T &&iterable)
Definition: enumerate.h:32
uint32_t nrnRan4int(uint32_t *idx1, uint32_t idx2)
Definition: mcran4.cpp:75
uint32_t mcell_iran4(uint32_t *high)
Definition: mcran4.cpp:71
double nrnRan4dbl(uint32_t *idx1, uint32_t idx2)
Definition: mcran4.cpp:117
double mcell_ran4a(uint32_t *high)
Definition: mcran4.cpp:67
static const double SHIFT32
Definition: mcran4.cpp:116
double mcell_ran4(uint32_t *high, double *x, unsigned int n, double range)
Definition: mcran4.cpp:59
static uint32_t lowindex
Definition: mcran4.cpp:49
void mcell_ran4_init(uint32_t low)
Definition: mcran4.cpp:55
double mcell_lowindex()
Definition: mcran4.cpp:51
int const size_t const size_t n
Definition: nrngsl.h:10