File indexing completed on 2026-04-09 07:49:14
0001
0002 #include <cmath>
0003 #include "S4MTRandGaussQ.h"
0004 #include "Randomize.hh"
0005
0006 double S4MTRandGaussQ::shoot()
0007 {
0008 double u = G4UniformRand() ;
0009 return transformQuick(u);
0010 }
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #define Table0size 250
0023 #define Table1size 1000
0024 #define TableSize (Table0size+Table1size)
0025
0026 #define Table0step (2.0E-6)
0027 #define Table1step (5.0E-4)
0028
0029 #define Table0scale (1.0/Table1step)
0030
0031 #define Table0offset 0
0032 #define Table1offset (Table0size)
0033
0034 static const float gaussTables [TableSize] = {
0035 #include "gaussQTables.cdat"
0036 };
0037
0038
0039
0040 double S4MTRandGaussQ::transformQuick (double r)
0041 {
0042 double sign = +1.0;
0043
0044
0045 if ( r > .5 ) {
0046 r = 1-r;
0047 sign = -1.0;
0048 }
0049
0050 int index;
0051 double dx;
0052
0053 if ( r >= Table1step ) {
0054 index = int((Table1size<<1) * r);
0055 if (index == Table1size) return 0.0;
0056 dx = (Table1size<<1) * r - index;
0057 index += Table1offset-1;
0058 } else if ( r > Table0step ) {
0059 double rr = r * Table0scale;
0060 index = int(Table0size * rr);
0061 dx = Table0size * rr - index;
0062 index += Table0offset-1;
0063 } else {
0064 return sign*transformSmall(r);
0065 }
0066
0067 double y0 = gaussTables [index++];
0068 double y1 = gaussTables [index];
0069
0070 return (float) (sign * ( y1 * dx + y0 * (1.0-dx) ));
0071
0072 }
0073
0074
0075
0076 double S4MTRandGaussQ::transformSmall (double r)
0077 {
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 double eps = 1.0e-7;
0098 double guess = 7.5;
0099 double v;
0100
0101 for ( int i = 1; i < 50; i++ ) {
0102 double vn2 = 1.0/(guess*guess);
0103 double s = -13*11*9*7*5*3 * vn2*vn2*vn2*vn2*vn2*vn2*vn2;
0104 s += 11*9*7*5*3 * vn2*vn2*vn2*vn2*vn2*vn2;
0105 s += -9*7*5*3 * vn2*vn2*vn2*vn2*vn2;
0106 s += 7*5*3 * vn2*vn2*vn2*vn2;
0107 s += -5*3 * vn2*vn2*vn2;
0108 s += 3 * vn2*vn2 - vn2 + 1.0;
0109
0110 v = std::sqrt ( 2.0 * std::log ( s / (r*guess*std::sqrt(2.*M_PI)) ) );
0111 if ( std::fabs(v-guess) < eps ) break;
0112 guess = v;
0113 }
0114 return -v;
0115
0116 }
0117
0118