/***********************************************************************//** * @brief Returns vector of random event times * * @param[in] rate Mean event rate (events per second). * @param[in] tmin Minimum event time. * @param[in] tmax Maximum event time. * @param[in,out] ran Random number generator. * * This method returns a vector of random event times between @p tmin and * @p tmax assuming a light curve specified in a FITS file. ***************************************************************************/ GTimes GModelTemporalLightCurve::mc(const double& rate, const GTime& tmin, const GTime& tmax, GRan& ran) const { // Allocates empty vector of times GTimes times; // Update Monte Carlo cache mc_update(tmin, tmax); // Continue only if effective duration is positive and cache is not empty if (m_mc_eff_duration > 0.0 && m_mc_cum.size() > 0) { // Compute mean number of times by multiplying the rate with the // effective duration. Note that the light curve normalization factor // is already included in the effective rate, hence we should not // multiply it here again (see #2181). double lambda = rate * m_mc_eff_duration; // Compute number of times to be sampled int ntimes = int(ran.poisson(lambda)+0.5); // Loop over number of times for (int i = 0; i < ntimes; ++i) { // Determine in which bin we reside int inx = 0; if (m_mc_cum.size() > 1) { double u = ran.uniform(); for (inx = m_mc_cum.size()-1; inx > 0; --inx) { if (m_mc_cum[inx-1] <= u) { break; } } } // Get random time double seconds; if (m_mc_slope[inx] == 0.0) { seconds = m_mc_dt[inx] * ran.uniform() + m_mc_time[inx]; } else { seconds = (std::sqrt(m_mc_offset[inx]*m_mc_offset[inx] + 2.0 * m_mc_slope[inx] * ran.uniform()) - m_mc_offset[inx]) / m_mc_slope[inx] + m_mc_time[inx]; } // Append random time GTime time(seconds, m_timeref); times.append(time); } // endfor: looped over times } // endif: cache was valid // Return vector of times return times; }
/***********************************************************************//** * @brief Returns MC energy between [emin, emax] * * @param[in] emin Minimum photon energy. * @param[in] emax Maximum photon energy. * @param[in] ran Random number generator. * @return Energy. * * @exception GException::erange_invalid * Energy range is invalid (emin < emax required). * * Simulates a random energy in the interval [emin, emax] for a spectral * function. ***************************************************************************/ GEnergy GModelSpectralFunc::mc(const GEnergy& emin, const GEnergy& emax, GRan& ran) const { // Throw an exception if energy range is invalid if (emin >= emax) { throw GException::erange_invalid(G_MC, emin.MeV(), emax.MeV(), "Minimum energy < maximum energy required."); } // Allocate energy GEnergy energy; // Continue only if emax > emin if (emax > emin) { // Update cache mc_update(emin, emax); // Determine in which bin we reside int inx = 0; if (m_mc_cum.size() > 1) { double u = ran.uniform(); for (inx = m_mc_cum.size()-1; inx > 0; --inx) { if (m_mc_cum[inx-1] <= u) { break; } } } // Get random energy for specific bin if (m_mc_exp[inx] != 0.0) { double e_min = m_mc_min[inx]; double e_max = m_mc_max[inx]; double u = ran.uniform(); double eng = (u > 0.0) ? std::exp(std::log(u * (e_max - e_min) + e_min) / m_mc_exp[inx]) : 0.0; energy.MeV(eng); } else { double e_min = m_mc_min[inx]; double e_max = m_mc_max[inx]; double u = ran.uniform(); double eng = std::exp(u * (e_max - e_min) + e_min); energy.MeV(eng); } } // endif: emax > emin // Return energy return energy; }
int main(int argc, char **argv) { int i, l; int accepted = 0; //Total number of accepted configurations int total_updates = 0; //Total number of updates clock_t begin, end; /* Initialize the random number generator */ rlxd_init(2, time(NULL)); /* Initialize the lattice geometry */ init_lattice(Lx, Ly, Lt); /* Initialize the fields */ hotstart(); /* Print out the run parameters */ echo_sim_params(); mc_init(); /* thermalization */ mc_iter = 0; //Counts the total number of calls to the update() routine printf("\n Thermalization: \n\n"); //begin = clock(); for(i=0; i<g_thermalize; i++) { mc_update(); //printf("\t Step %04i\n", i); }; //end = clock(); //printf("Time for one MC update: %f\n", (double)(end - begin) / CLOCKS_PER_SEC); /* measure the iterations only during real simulation, not thermalization */ R = 0; //Counts the total number of accepted configurations mc_iter = 0; //Counts the total number of calls to the update() routine printf("\n Generation: \n\n"); measurement_init(); measure(); printf("Average density: \t %.5f %.5f\n", creal(m_density[measure_iter]), cimag(m_density[measure_iter])); printf("Wilson plaquette: \t %.5f\n", mean_plaq()); for(i=0; i<g_measurements; i++) { /* do g_intermediate updates before measurement */ for (l=0; l<g_intermediate; l++) { mc_update(); }; mc_update(); /* doing measurement */ measure(); printf("Average density: \t %.5f %.5f\n", creal(m_density[measure_iter]), cimag(m_density[measure_iter])); printf("Wilson plaquette: \t %.5f\n", mean_plaq()); fflush(stdout); }; printf("Wrapping up...\n"); output_measurement(); measurement_finish(); /* Some output for diagnostics */ total_updates = g_measurements*(g_intermediate + 1)*GRIDPOINTS; printf("\n\n Algorithm performance:\n"); printf("\t Acceptance rate: %.4f\n", (double)R/(double)total_updates); return 0; }