/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FastSimulation/Utilities/src/BaseNumericalRandomGenerator.cc
137 строк
4 KB
Cms Build
Clang-Format
24 май 2019, 00:14
24 май 2019, 00:14
740c44a
Код
Авторство
О чём код?
#include "FastSimulation/Utilities/interface/BaseNumericalRandomGenerator.h" #include "FastSimulation/Utilities/interface/RandomEngineAndDistribution.h" #include <cmath> // #include <iostream> BaseNumericalRandomGenerator::BaseNumericalRandomGenerator(double xmin, double xmax, int n, int iter) : xmin(xmin), xmax(xmax), n(n), iter(iter) { f.resize(n); sampling.resize(n); } void BaseNumericalRandomGenerator::initialize() { m = n - 1; rmin = 0.; deltar = (double)m - rmin; std::vector<double> a, y, z, xnew; a.resize(n); y.resize(n); z.resize(n); xnew.resize(n); double sig1 = 0.; // Initialize sampling double du = (xmax - xmin) / (float)m; sampling[0] = xmin; for (int i = 1; i < n; ++i) sampling[i] = sampling[i - 1] + du; // Starting point for iterations for (int it = 0; it < iter; ++it) { // Calculate function values for (int i = 0; i < n; ++i) f[i] = function(sampling[i]); // Calculate bin areas for (int i = 0; i < m; ++i) a[i] = (sampling[i + 1] - sampling[i]) * (f[i + 1] + f[i]) / 2.; // Calculate cumulative spectrum Y values y[0] = 0.; for (int i = 1; i < n; ++i) y[i] = y[i - 1] + a[i - 1]; // Put equidistant points on y scale double dz = y[n - 1] / (float)m; z[0] = 0; for (int i = 1; i < n; ++i) z[i] = z[i - 1] + dz; // Determine spacinf of Z points in between Y points // From this, determine new X values and finally replace old values xnew[0] = sampling[0]; xnew[n - 1] = sampling[n - 1]; int k = 0; for (int i = 1; i < m; ++i) { while (y[k + 1] < z[i]) ++k; double r = (z[i] - y[k]) / (y[k + 1] - y[k]); xnew[i] = sampling[k] + (sampling[k + 1] - sampling[k]) * r; } for (int i = 0; i < n; ++i) sampling[i] = xnew[i]; sig1 = sig1 + y[m]; // std::cout << "BaseNumericalRandomGenerator::Iteration # " << it+1 // << " Integral = " << sig1/(float)(it+1) // << std::endl; } } double BaseNumericalRandomGenerator::generate(RandomEngineAndDistribution const* random) const { double r = rmin + deltar * random->flatShoot(); int i = (int)r; double s = r - (double)i; // cout << " i,r,s = " << i << " " << r << " " << s << endl; return sampling[i] + s * (sampling[i + 1] - sampling[i]); } double BaseNumericalRandomGenerator::generateExp(RandomEngineAndDistribution const* random) const { double r = rmin + deltar * random->flatShoot(); int i = (int)r; // double s=r-(double)i; // cout << " i,r,s = " << i << " " << r << " " << s << endl; double b = -std::log(f[i + 1] / f[i]) / (sampling[i + 1] - sampling[i]); double a = f[i] * std::exp(b * sampling[i]); double umin = -a / b * std::exp(-b * sampling[i]); double umax = -a / b * std::exp(-b * sampling[i + 1]); double u = (umax - umin) * random->flatShoot() + umin; return -std::log(-b / a * u) / b; } double BaseNumericalRandomGenerator::generateLin(RandomEngineAndDistribution const* random) const { double r = rmin + deltar * random->flatShoot(); int i = (int)r; // double s=r-(double)i; // cout << " i,r,s = " << i << " " << r << " " << s << endl; double a = (f[i + 1] - f[i]) / (sampling[i + 1] - sampling[i]); double b = f[i] - a * sampling[i]; double umin = a * sampling[i] * sampling[i] / 2. + b * sampling[i]; double umax = a * sampling[i + 1] * sampling[i + 1] / 2. + b * sampling[i + 1]; double u = (umax - umin) * random->flatShoot() + umin; return (-b + std::sqrt(b * b + 2. * a * u)) / a; } bool BaseNumericalRandomGenerator::setSubInterval(double x1, double x2) { if (x1 < xmin || x2 > xmax) return false; if (x1 > x2) { double tmp = x1; x1 = x2; x2 = tmp; } unsigned ibin = 1; for (; ibin < (unsigned)n && x1 > sampling[ibin]; ++ibin) ; unsigned ibin1 = ibin; for (; ibin < (unsigned)n && x2 > sampling[ibin]; ++ibin) ; unsigned ibin2 = ibin; // cout << sampling[ibin1-1] << " " << x1 << " " << sampling[ibin1] << endl; // cout << sampling[ibin2-1] << " " << x2 << " " << sampling[ibin2] << endl; rmin = ibin1 + (x1 - sampling[ibin1]) / (sampling[ibin1] - sampling[ibin1 - 1]); deltar = ibin2 + (x2 - sampling[ibin2]) / (sampling[ibin2] - sampling[ibin2 - 1]) - rmin; // cout << rmin << " " << deltar << endl; return true; }