42 void EGS_AliasTable::clear() {
52 void EGS_AliasTable::allocate(
int N,
int Type) {
56 xi =
new EGS_Float [n];
59 fi =
new EGS_Float [n];
60 wi =
new EGS_Float [n];
65 wi =
new EGS_Float [n-1];
68 fi =
new EGS_Float [n-1];
71 fi =
new EGS_Float [n];
81 for (
int j=0; j<np; j++) {
89 if (type == 2 || type == 3) {
101 const EGS_Float *f,
int Type) {
103 for (
int i=0; i<np; i++) {
110 if (Type == 2 || Type == 3) {
116 void EGS_AliasTable::make() {
117 EGS_Float *fcum =
new EGS_Float[np];
118 bool *not_done =
new bool[np];
119 EGS_Float sum = 0, sum1 = 0;
121 for (i=0; i<np; i++) {
125 else if (type == 1) {
126 fcum[i] = fi[i]*(xi[i+1]-xi[i]);
129 fcum[i] = 0.5*(fi[i]+fi[i+1])*(xi[i+1]-xi[i]);
136 sum1 += fcum[i]*xi[i];
138 else if (type == 1) {
139 sum1 += 0.5*fcum[i]*(xi[i+1]+xi[i]);
141 else sum1 += fcum[i]*(fi[i]*(2*xi[i]+xi[i+1])+
142 fi[i+1]*(xi[i]+2*xi[i+1]))/(3*(fi[i]+fi[i+1]));
146 for (i=0; i<np; i++) {
149 if (type == 2 || type == 3) {
155 for (i=0; i<np-1; i++) {
159 for (jh=0; jh<np; jh++) {
160 if (not_done[jh] && fcum[jh] > sum) {
171 for (jl=0; jl<np; jl++) {
172 if (not_done[jl] && fcum[jl] < sum) {
178 egsWarning(
"EGS_AliasTable::make(): found a high bin, but no low bin; this is abnormal.");
183 EGS_Float aux = sum - fcum[low_bin];
184 fcum[high_bin] -= aux;
185 not_done[jl] =
false;
186 wi[low_bin] = fcum[low_bin]/sum;
187 bin[low_bin] = high_bin;
196 int nmax, EGS_AtFunction f,
void *data) {
200 fi[0] = f(xi[0],data);
201 fi[1] = f(xi[1],data);
202 EGS_Float *xtemp, *ftemp;
204 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
206 egsFatal(
"EGS_AliasTable::initialize: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
209 int nnn = (n-1)*AT_NCHECK + n;
210 xtemp =
new EGS_Float[nnn];
211 ftemp =
new EGS_Float[nnn];
212 if (!xtemp || !ftemp)
egsFatal(
"EGS_AliasTable::initialize: "
213 "not enough memory!\n");
216 for (i=0; i<n-1; i++) {
219 EGS_Float dx = (xi[i+1]-xi[i])/(AT_NCHECK+1);
220 for (
int l=0; l<AT_NCHECK; l++) {
221 EGS_Float x = xi[i]+dx*(l+1);
222 EGS_Float fe = f(x,data);
223 EGS_Float fa = fi[i]+(fi[i+1]-fi[i])/(xi[i+1]-xi[i])*(x-xi[i]);
224 EGS_Float test = fabs(fa/fe-1);
237 ftemp[j++] = fi[n-1];
239 for (i=0; i<j; i++) {
258 EGS_Float aj = r1*np;
269 EGS_Float aj = r1*np;
279 EGS_Float dx = xi[j+1] - x;
286 EGS_Float a = fi[j+1]/fi[j]-1;
288 EGS_Float rnno1 = 0.5*(1-r2)*a;
289 res = x + r2*dx*(1+rnno1*(1-r2*a));
292 res = x - dx/a*(1-sqrt(1+r2*a*(2+a)));
296 res = x + dx*sqrt(r2);
310 wi =
new EGS_Float [n];
316 double *p =
new EGS_Float [n];
319 for (i=0; i<n; i++) {
327 egsFatal(
"Error: %s, line %d: degenerate distribution, histogram sum <= 0", __FILE__, __LINE__);
330 for (i=0; i<n; i++) {
336 vector<int> big_list;
337 vector<int> small_list;
338 for (i=0; i<n; i++) {
341 small_list.push_back(i);
344 big_list.push_back(i);
350 while (big_list.size() > 0 && small_list.size() > 0 && loopCount++ <=
loopMax) {
353 int big = big_list.back();
354 int small = small_list.back();
358 wi[big] -= (1.0 - wi[small]);
359 small_list.pop_back();
364 small_list.push_back(big);
367 if (big_list.size() > 0) {
368 egsWarning(
"Warning: %s, line %d: table aliasing may be incomplete", __FILE__, __LINE__);
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
int sampleBin(EGS_RandomGenerator *rndm) const
Get a random bin from this table.
EGS_AliasTable class header file.
A class for sampling random values from a given probability distribution using the alias table techni...
EGS_Float sample(EGS_RandomGenerator *rndm) const
Get a random point from this table using the RNG rndm.
Global egspp functions header file.
~EGS_SimpleAliasTable()
Destructor.
Base random number generator class. All random number generators should be derived from this class...
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
EGS_Float getUniform()
Returns a random number uniformly distributed between zero (inclusive) and 1 (exclusive).
const EGS_Float epsilon
The epsilon constant for floating point comparisons.
void initialize(int N, const EGS_Float *x, const EGS_Float *f, int Type=1)
Initialize the alias table.
EGS_SimpleAliasTable(int N, const EGS_Float *f)
Constructor.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.