BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
anonymous_namespace{IDistribution2DSampler.cpp} Namespace Reference

Classes

struct  ZigguratBox
 

Functions

std::pair< double, double > samplingZiggurat (double r, double x_func_max, double(*func_phi)(double))
 
double func_phi_Cauchy (double phi)
 
double func_phi_Cone (double phi)
 

Variables

double sigma_scale = 3.0
 
size_t n_boxes = 256
 

Function Documentation

◆ samplingZiggurat()

std::pair<double, double> anonymous_namespace{IDistribution2DSampler.cpp}::samplingZiggurat ( double  r,
double  x_func_max,
double(*)(double)  func_phi 
)

Definition at line 37 of file IDistribution2DSampler.cpp.

38 {
39  // This sampling is based on vertical boxes instead of the conventional
40  // Ziggurat sampling that is done with horizontal boxes
41 
42  std::random_device rd; // random device class instance
43  std::mt19937 gen(rd()); // Standard mersenne_twister_engine seeded with rd()
44  std::uniform_real_distribution<double> uniformDist(0.0, 1.0);
45 
46  double box_width = (x_func_max + r) / n_boxes; // r = rightmost box's right-edge from x_func_max
47  std::vector<ZigguratBox> boxes;
48  std::vector<double> cum_area_vector;
49 
50  double x_min = 0, x_max = 0, y_max = 0, y_lower = 0, cum_area_box = 0;
51 
52  // Establising vectors of boxes and cumulative area (probability of each box) for Ziggurat
53  // sampling
54  for (size_t i = 0; i < n_boxes; ++i) {
55  if (i != 0)
56  x_min = x_max;
57 
58  x_max += box_width;
59 
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));
66  } else {
67  y_max = func_phi(x_min);
68  y_lower = func_phi(x_max);
69  }
70 
71  boxes.emplace_back(ZigguratBox(x_min, x_max, y_max, y_lower));
72 
73  cum_area_box += box_width * y_max;
74  cum_area_vector.emplace_back(cum_area_box);
75  }
76 
77  // Normalizing the cumulative area to 1
78  for (size_t i = 0; i < n_boxes; ++i)
79  cum_area_vector[i] = cum_area_vector[i] / cum_area_vector.back();
80 
81  // Sampling a phi value
82  double phi = 0;
83  bool solnFound(false);
84 
85  while (!solnFound) {
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;
90 
91  std::uniform_real_distribution<double> uniformDistAB(boxes[i].m_x_min,
92  boxes[i].m_x_max);
93  double phi_attempt = uniformDistAB(gen);
94 
95  if (random_y <= boxes[i].m_y_lower) {
96  phi = phi_attempt;
97  solnFound = true;
98  } else {
99  if (random_y <= func_phi(phi_attempt)) {
100  phi = phi_attempt;
101  solnFound = true;
102  }
103  }
104  break;
105  }
106  }
107  }
108 
109  // Sampling an alpha value
110  double alpha = 2 * M_PI * uniformDist(gen);
111  return std::make_pair(phi, alpha);
112 }
#define M_PI
Definition: MathConstants.h:39

References M_PI, and n_boxes.

Referenced by Distribution2DCauchySampler::randomSample(), and Distribution2DConeSampler::randomSample().

◆ func_phi_Cauchy()

double anonymous_namespace{IDistribution2DSampler.cpp}::func_phi_Cauchy ( double  phi)

Definition at line 114 of file IDistribution2DSampler.cpp.

115 {
116  // The independent "phi" density function of the 2D Cauchy distribution
117  return phi * std::exp(-phi);
118 }

Referenced by Distribution2DCauchySampler::randomSample().

◆ func_phi_Cone()

double anonymous_namespace{IDistribution2DSampler.cpp}::func_phi_Cone ( double  phi)

Definition at line 120 of file IDistribution2DSampler.cpp.

121 {
122  // The independent "phi" density function of the 2D Cone distribution
123  return 6 * (1 - phi) * phi;
124 }

Referenced by Distribution2DConeSampler::randomSample().

Variable Documentation

◆ sigma_scale

double anonymous_namespace{IDistribution2DSampler.cpp}::sigma_scale = 3.0

◆ n_boxes

size_t anonymous_namespace{IDistribution2DSampler.cpp}::n_boxes = 256

Definition at line 21 of file IDistribution2DSampler.cpp.

Referenced by samplingZiggurat().