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 <../../nrnconf.h>
43 #include <stdio.h>
44 #include <stddef.h>
45 #include <math.h>
46 #include <float.h>
47 #include <stdlib.h>
48 #include <mcran4.h>
49 #include "hocdec.h"
50 
51 static uint32_t lowindex = 0;
52 
53 extern "C" void mcell_ran4_init(uint32_t low) {
54  lowindex = low;
55 }
56 
57 extern "C" double mcell_ran4(uint32_t *high, double *x, unsigned int n, double range) {
58  int i;
59  for (i=0;i<n;i++) { x[i]=range*nrnRan4dbl(high, lowindex); }
60  return x[0];
61 }
62 
63 extern "C" double mcell_ran4a(uint32_t *high) {
64  return nrnRan4dbl(high, lowindex);
65 }
66 
67 extern "C" uint32_t mcell_iran4(uint32_t *high){
68  return nrnRan4int(high, lowindex);
69 }
70 
71 /* Hoc interface */
72 extern double chkarg();
73 extern int use_mcell_ran4_;
74 
75 
76 void hoc_mcran4() {
77  uint32_t idx;
78  double* xidx;
79  double x;
80  xidx = hoc_pgetarg(1);
81  idx = (uint32_t)(*xidx);
82  x = mcell_ran4a(&idx);
83  *xidx = idx;
84  hoc_ret();
85  hoc_pushx(x);
86 }
88  double prev = (double)lowindex;
89  if (ifarg(1)) {
90  uint32_t idx = (uint32_t) chkarg(1, 0., 4294967295.);
91  mcell_ran4_init(idx);
92  }
93  hoc_ret();
94  hoc_pushx(prev);
95 
96 }
97 void hoc_usemcran4() {
98  double prev = (double)use_mcell_ran4_;
99  if (ifarg(1)) {
100  use_mcell_ran4_ = (int)chkarg(1, 0., 1.);
101  }
102  hoc_ret();
103  hoc_pushx(prev);
104 }
105 
106 extern "C" uint32_t nrnRan4int(uint32_t* idx1, uint32_t idx2)
107 {
108  uint32_t u, v, w, m, n;
109  /* 64-bit hash */
110  n = (*idx1)++;
111  m = idx2;
112 
113  w = n ^ 0xbaa96887;
114  v = w >> 16;
115  w &= 0xffff;
116  u = ~((v - w) * (v + w));
117  /*m ^= (((u >> 16) | (u << 16)) ^ 0xb4f0c4a7) + w * v;*/
118  m ^= (((u >> 16) | (u << 16)) ^ 0x4b0f3b58) + w * v;
119 
120  w = m ^ 0x1e17d32c;
121  v = w >> 16;
122  w &= 0xffff;
123  u = ~((v - w) * (v + w));
124  /*n ^= (((u >> 16) | (u << 16)) ^ 0x178b0f3c) + w * v;*/
125  n ^= (((u >> 16) | (u << 16)) ^ 0xe874f0c3) + w * v;
126  return n;
127 
128  w = n ^ 0x03bcdc3c;
129  v = w >> 16;
130  w &= 0xffff;
131  u = (v - w) * (v + w);
132  m ^= (((u >> 16) | (u << 16)) ^ 0x96aa3a59) + w * v;
133 
134  w = m ^ 0x0f33d1b2;
135  v = w >> 16;
136  w &= 0xffff;
137  u = (v - w) * (v + w);
138  n ^= (((u >> 16) | (u << 16)) ^ 0xaa5835b9) + w * v;
139  return n;
140 }
141 
142 /*
143 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
144 // Function: Randouble (hines now nrnRan4dbl
145 //
146 // Purpose: Random double-precision floating-point sample.
147 // The 2^52 allowed values are odd multiples of 2^-53,
148 // symmetrically placed in strict interior of (0,1).
149 //
150 // Notes: (1) Tuned to 52-bit mantissa in "double" format.
151 // (2) Uses one call to Ranint to get 64 random bits, with extra
152 // random integer available in Rand[3].
153 // (3) All floating-point random calls are directed through this code,
154 // except Rangauss which uses the extra random integer in Rand[3].
155 //
156 // History: John Skilling 6 May 1995, 3 Dec 1995, 24 Aug 1996
157 // 20 Oct 2002, 17 Dec 2002
158 //-----------------------------------------------------------------------------
159 //
160 */
161 static const double SHIFT32 = 1.0 / 4294967296.0; /* 2^-32 */
162 extern "C" double nrnRan4dbl(uint32_t* idx1, uint32_t idx2)
163 {
164  uint32_t hi, lo, extra;
165  hi = (uint32_t)nrnRan4int(idx1, idx2); /*top 32 bits*/
166 /*
167 // lo = (extra // low bits
168 // & 0xfffff000) ^ 0x00000800; // switch lowest (2^-53) bit ON
169 // return ((double)hi + (double)lo * SHIFT32) * SHIFT32;
170 */
171  return ((double)hi) * SHIFT32;
172 }
173 
174 
void hoc_mcran4()
Definition: mcran4.cpp:76
#define v
Definition: md1redef.h:4
double * hoc_pgetarg(int narg)
Definition: code.cpp:1604
void hoc_ret()
Item * prev(Item *item)
Definition: list.cpp:101
int const size_t const size_t n
Definition: nrngsl.h:12
int
Definition: nrnmusic.cpp:71
double mcell_ran4a(uint32_t *high)
Definition: mcran4.cpp:63
int use_mcell_ran4_
Definition: hoc_init.cpp:271
int ifarg(int)
Definition: code.cpp:1562
static uint32_t lowindex
Definition: mcran4.cpp:51
void hoc_pushx(double)
static const double SHIFT32
Definition: mcran4.cpp:161
double mcell_ran4(uint32_t *high, double *x, unsigned int n, double range)
Definition: mcran4.cpp:57
void hoc_mcran4init()
Definition: mcran4.cpp:87
#define i
Definition: md1redef.h:12
void hoc_usemcran4()
Definition: mcran4.cpp:97
double nrnRan4dbl(uint32_t *idx1, uint32_t idx2)
Definition: mcran4.cpp:162
void mcell_ran4_init(uint32_t low)
Definition: mcran4.cpp:53
uint32_t mcell_iran4(uint32_t *high)
Definition: mcran4.cpp:67
uint32_t nrnRan4int(uint32_t *idx1, uint32_t idx2)
Definition: mcran4.cpp:106
uint uint32_t
double chkarg()