24 ZigguratBox(
double x_min,
double x_max,
double y_max,
double y_lower)
25 : m_x_min(x_min), m_x_max(x_max), m_y_max(y_max), m_y_lower(y_lower)
37 std::pair<double, double>
samplingZiggurat(
double r,
double x_func_max,
double (*func_phi)(
double))
42 std::random_device rd;
43 std::mt19937 gen(rd());
44 std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
46 double box_width = (x_func_max + r) /
n_boxes;
47 std::vector<ZigguratBox> boxes;
48 std::vector<double> cum_area_vector;
50 double x_min = 0, x_max = 0, y_max = 0, y_lower = 0, cum_area_box = 0;
54 for (
size_t i = 0; i <
n_boxes; ++i) {
60 if (x_func_max >= x_max) {
61 y_max = func_phi(x_max);
62 y_lower = func_phi(x_min);
63 }
else if (x_func_max > x_min && x_func_max <= x_max) {
64 y_max = func_phi(x_func_max);
65 y_lower = std::min(func_phi(x_min), func_phi(x_max));
67 y_max = func_phi(x_min);
68 y_lower = func_phi(x_max);
71 boxes.emplace_back(
ZigguratBox(x_min, x_max, y_max, y_lower));
73 cum_area_box += box_width * y_max;
74 cum_area_vector.emplace_back(cum_area_box);
78 for (
size_t i = 0; i <
n_boxes; ++i)
79 cum_area_vector[i] = cum_area_vector[i] / cum_area_vector.back();
83 bool solnFound(
false);
86 double random_cum_area = uniformDist(gen);
87 for (
size_t i = 0; i <
n_boxes; ++i) {
88 if (random_cum_area <= cum_area_vector[i]) {
89 double random_y = uniformDist(gen) * boxes[i].m_y_max;
91 std::uniform_real_distribution<double> uniformDistAB(boxes[i].m_x_min,
93 double phi_attempt = uniformDistAB(gen);
95 if (random_y <= boxes[i].m_y_lower) {
99 if (random_y <= func_phi(phi_attempt)) {
110 double alpha = 2 *
M_PI * uniformDist(gen);
111 return std::make_pair(phi, alpha);
117 return phi * std::exp(-phi);
123 return 6 * (1 - phi) * phi;
133 double phi_max_Cauchy = 1.0;
137 return std::make_pair(
m_omega_x * samples.first * std::cos(samples.second),
138 m_omega_y * samples.first * std::sin(samples.second));
143 std::random_device rd;
144 std::mt19937 gen(rd());
145 std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
147 double cdf_value_phi = uniformDist(gen);
150 double phi = std::sqrt(-2 * std::log(1 - cdf_value_phi));
151 double alpha = 2 *
M_PI * uniformDist(gen);
152 return std::make_pair(
m_omega_x * phi * std::cos(alpha),
m_omega_y * phi * std::sin(alpha));
157 std::random_device rd;
158 std::mt19937 gen(rd());
159 std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
161 double cdf_value_phi = uniformDist(gen);
164 double phi = std::sqrt(cdf_value_phi);
165 double alpha = 2 *
M_PI * uniformDist(gen);
166 return std::make_pair(
m_omega_x * phi * std::cos(alpha),
m_omega_y * phi * std::sin(alpha));
173 double phi_max_Cone = 0.5;
177 return std::make_pair(
m_omega_x * samples.first * std::cos(samples.second),
178 m_omega_y * samples.first * std::sin(samples.second));
Defines interface class IFTDistribution1D, and children thereof.
std::pair< double, double > randomSample() const final
std::pair< double, double > randomSample() const final
std::pair< double, double > randomSample() const final
std::pair< double, double > randomSample() const final
virtual ~IDistribution2DSampler()
double func_phi_Cone(double phi)
double func_phi_Cauchy(double phi)
std::pair< double, double > samplingZiggurat(double r, double x_func_max, double(*func_phi)(double))
ZigguratBox(double x_min, double x_max, double y_max, double y_lower)