21 double sigma_scale = 3.0;
25 ZigguratBox(
double x_min,
double x_max,
double y_max,
double y_lower)
41 std::pair<double, double> samplingZiggurat(
double r,
double x_func_max,
double (*func_phi)(
double))
46 std::random_device rd;
47 std::mt19937 gen(rd());
48 std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
50 double box_width = (x_func_max + r) / n_boxes;
51 std::vector<ZigguratBox> boxes;
52 std::vector<double> cum_area_vector;
54 double x_min = 0, x_max = 0, y_max = 0, y_lower = 0, cum_area_box = 0;
58 for (
size_t i = 0; i < n_boxes; ++i) {
64 if (x_func_max >= x_max) {
65 y_max = func_phi(x_max);
66 y_lower = func_phi(x_min);
67 }
else if (x_func_max > x_min && x_func_max <= x_max) {
68 y_max = func_phi(x_func_max);
69 y_lower = std::min(func_phi(x_min), func_phi(x_max));
71 y_max = func_phi(x_min);
72 y_lower = func_phi(x_max);
75 boxes.emplace_back(ZigguratBox(x_min, x_max, y_max, y_lower));
77 cum_area_box += box_width * y_max;
78 cum_area_vector.emplace_back(cum_area_box);
82 for (
size_t i = 0; i < n_boxes; ++i)
83 cum_area_vector[i] = cum_area_vector[i] / cum_area_vector.back();
87 bool solnFound(
false);
90 double random_cum_area = uniformDist(gen);
91 for (
size_t i = 0; i < n_boxes; ++i) {
92 if (random_cum_area <= cum_area_vector[i]) {
93 double random_y = uniformDist(gen) * boxes[i].m_y_max;
95 std::uniform_real_distribution<double> uniformDistAB(boxes[i].m_x_min,
97 double phi_attempt = uniformDistAB(gen);
99 if (random_y <= boxes[i].m_y_lower) {
103 if (random_y <= func_phi(phi_attempt)) {
114 double alpha =
M_TWOPI * uniformDist(gen);
115 return std::make_pair(phi, alpha);
118 double func_phi_Cauchy(
double phi)
121 return phi * std::exp(-phi);
124 double func_phi_Cone(
double phi)
127 return 6 * (1 - phi) * phi;
139 double phi_max_Cauchy = 1.0;
141 double r = sigma_scale * std::sqrt(2);
142 std::pair<double, double> samples = samplingZiggurat(r, phi_max_Cauchy, func_phi_Cauchy);
143 return std::make_pair(
m_omega_x * samples.first * std::cos(samples.second),
144 m_omega_y * samples.first * std::sin(samples.second));
149 std::random_device rd;
150 std::mt19937 gen(rd());
151 std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
153 double cdf_value_phi = uniformDist(gen);
156 double phi = std::sqrt(-2 * std::log(1 - cdf_value_phi));
157 double alpha =
M_TWOPI * uniformDist(gen);
158 return std::make_pair(
m_omega_x * phi * std::cos(alpha),
m_omega_y * phi * std::sin(alpha));
163 std::random_device rd;
164 std::mt19937 gen(rd());
165 std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
167 double cdf_value_phi = uniformDist(gen);
170 double phi = std::sqrt(cdf_value_phi);
171 double alpha =
M_TWOPI * uniformDist(gen);
172 return std::make_pair(
m_omega_x * phi * std::cos(alpha),
m_omega_y * phi * std::sin(alpha));
179 double phi_max_Cone = 0.5;
182 std::pair<double, double> samples = samplingZiggurat(r, phi_max_Cone, func_phi_Cone);
183 return std::make_pair(
m_omega_x * samples.first * std::cos(samples.second),
184 m_omega_y * samples.first * std::sin(samples.second));
Defines M_PI and some more mathematical constants.
Defines interface class IProfile1D, and children thereof.
std::pair< double, double > randomSample() const override
std::pair< double, double > randomSample() const override
std::pair< double, double > randomSample() const override
std::pair< double, double > randomSample() const override
virtual ~IDistribution2DSampler()