43 void EGS_AliasTable::clear() {
53 void EGS_AliasTable::allocate(
int N,
int Type) {
57 xi =
new EGS_Float [n];
60 fi =
new EGS_Float [n];
61 wi =
new EGS_Float [n];
66 wi =
new EGS_Float [n-1];
69 fi =
new EGS_Float [n-1];
72 fi =
new EGS_Float [n];
82 for (
int j=0; j<np; j++) {
90 if (type == 2 || type == 3) {
102 const EGS_Float *f,
int Type) {
104 for (
int i=0; i<np; i++) {
111 if (Type == 2 || Type == 3) {
117 void EGS_AliasTable::make() {
118 EGS_Float *fcum =
new EGS_Float[np];
119 bool *not_done =
new bool[np];
120 EGS_Float sum = 0, sum1 = 0;
122 for (i=0; i<np; i++) {
126 else if (type == 1) {
127 fcum[i] = fi[i]*(xi[i+1]-xi[i]);
130 fcum[i] = 0.5*(fi[i]+fi[i+1])*(xi[i+1]-xi[i]);
137 sum1 += fcum[i]*xi[i];
139 else if (type == 1) {
140 sum1 += 0.5*fcum[i]*(xi[i+1]+xi[i]);
142 else sum1 += fcum[i]*(fi[i]*(2*xi[i]+xi[i+1])+
143 fi[i+1]*(xi[i]+2*xi[i+1]))/(3*(fi[i]+fi[i+1]));
147 for (i=0; i<np; i++) {
150 if (type == 2 || type == 3) {
156 for (i=0; i<np-1; i++) {
160 for (jh=0; jh<np; jh++) {
161 if (not_done[jh] && fcum[jh] > sum) {
172 for (jl=0; jl<np; jl++) {
173 if (not_done[jl] && fcum[jl] < sum) {
179 egsWarning(
"EGS_AliasTable::make(): found a high bin, but no low bin; this is abnormal.");
184 EGS_Float aux = sum - fcum[low_bin];
185 fcum[high_bin] -= aux;
186 not_done[jl] =
false;
187 wi[low_bin] = fcum[low_bin]/sum;
188 bin[low_bin] = high_bin;
197 int nmax, EGS_AtFunction f,
void *data) {
201 fi[0] = f(xi[0],data);
202 fi[1] = f(xi[1],data);
203 EGS_Float *xtemp, *ftemp;
205 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
207 egsFatal(
"EGS_AliasTable::initialize: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
210 int nnn = (n-1)*AT_NCHECK + n;
211 xtemp =
new EGS_Float[nnn];
212 ftemp =
new EGS_Float[nnn];
213 if (!xtemp || !ftemp)
egsFatal(
"EGS_AliasTable::initialize: "
214 "not enough memory!\n");
217 for (i=0; i<n-1; i++) {
220 EGS_Float dx = (xi[i+1]-xi[i])/(AT_NCHECK+1);
221 for (
int l=0; l<AT_NCHECK; l++) {
222 EGS_Float x = xi[i]+dx*(l+1);
223 EGS_Float fe = f(x,data);
224 EGS_Float fa = fi[i]+(fi[i+1]-fi[i])/(xi[i+1]-xi[i])*(x-xi[i]);
225 EGS_Float test = fabs(fa/fe-1);
238 ftemp[j++] = fi[n-1];
240 for (i=0; i<j; i++) {
259 EGS_Float aj = r1*np;
270 EGS_Float aj = r1*np;
280 EGS_Float dx = xi[j+1] - x;
287 EGS_Float a = fi[j+1]/fi[j]-1;
289 EGS_Float rnno1 = 0.5*(1-r2)*a;
290 res = x + r2*dx*(1+rnno1*(1-r2*a));
293 res = x - dx/a*(1-sqrt(1+r2*a*(2+a)));
297 res = x + dx*sqrt(r2);
311 wi =
new EGS_Float [n];
317 double *p =
new EGS_Float [n];
320 for (i=0; i<n; i++) {
328 egsFatal(
"Error: %s, line %d: degenerate distribution, histogram sum <= 0", __FILE__, __LINE__);
331 for (i=0; i<n; i++) {
337 vector<int> big_list;
338 vector<int> small_list;
339 for (i=0; i<n; i++) {
342 small_list.push_back(i);
345 big_list.push_back(i);
351 while (big_list.size() > 0 && small_list.size() > 0 && loopCount++ <=
loopMax) {
354 int big = big_list.back();
355 int small = small_list.back();
359 wi[big] -= (1.0 - wi[small]);
360 small_list.pop_back();
365 small_list.push_back(big);
368 if (big_list.size() > 0) {
369 egsWarning(
"Warning: %s, line %d: table aliasing may be incomplete", __FILE__, __LINE__);
A class for sampling random values from a given probability distribution using the alias table techni...
int sampleBin(EGS_RandomGenerator *rndm) const
Get a random bin from this table.
void initialize(int N, const EGS_Float *x, const EGS_Float *f, int Type=1)
Initialize the alias table.
EGS_Float sample(EGS_RandomGenerator *rndm) const
Get a random point from this table using the RNG rndm.
Base random number generator class. All random number generators should be derived from this class.
EGS_Float getUniform()
Returns a random number uniformly distributed between zero (inclusive) and 1 (exclusive).
EGS_SimpleAliasTable(int N, const EGS_Float *f)
Constructor.
~EGS_SimpleAliasTable()
Destructor.
EGS_AliasTable class header file.
Global egspp functions header file.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
const EGS_Float epsilon
The epsilon constant for floating point comparisons.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.