BornAgain  1.19.79
Open-source research software to simulate and fit neutron and x-ray reflectometry and grazing-incidence small-angle scattering
Distributions.h
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Param/Distrib/Distributions.h
6 //! @brief Defines classes representing one-dimensional distributions.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #ifndef BORNAGAIN_PARAM_DISTRIB_DISTRIBUTIONS_H
16 #define BORNAGAIN_PARAM_DISTRIB_DISTRIBUTIONS_H
17 
18 #include "Base/Types/ICloneable.h"
19 #include "Fit/Param/RealLimits.h"
20 #include "Param/Node/INode.h"
21 #include <vector>
22 
23 class ParameterSample;
24 
25 // ************************************************************************************************
26 // interface IDistribution1D
27 // ************************************************************************************************
28 
29 #ifndef USER_API
30 
31 //! Interface for one-dimensional distributions.
32 
33 class IDistribution1D : public ICloneable, public INode {
34 public:
35  IDistribution1D(const std::vector<double>& PValues);
36 
37  IDistribution1D* clone() const override = 0;
38 
39  //! Returns the distribution-specific probability density for value x.
40  virtual double probabilityDensity(double x) const = 0;
41 
42  //! Returns the distribution-specific mean.
43  virtual double mean() const = 0;
44 
45  //! Returns equidistant samples, using intrinsic parameters, weighted with probabilityDensity().
46  std::vector<ParameterSample> equidistantSamples(size_t nbr_samples, double sigma_factor = 0.,
47  const RealLimits& limits = RealLimits()) const;
48 
49  //! Returns equidistant samples from xmin to xmax, weighted with probabilityDensity().
50  std::vector<ParameterSample> equidistantSamplesInRange(size_t nbr_samples, double xmin,
51  double xmax) const;
52 
53  //! Returns equidistant interpolation points, with range computed in distribution-specific
54  //! way from mean and width parameter, taking into account limits and sigma_factor.
55  virtual std::vector<double>
56  equidistantPoints(size_t nbr_samples, double sigma_factor,
57  const RealLimits& limits = RealLimits()) const = 0;
58 
59  //! Returns equidistant interpolation points from xmin to xmax.
60  virtual std::vector<double> equidistantPointsInRange(size_t nbr_samples, double xmin,
61  double xmax) const;
62 
63  //! Returns true if the distribution is in the limit case of a Dirac delta distribution.
64  virtual bool isDelta() const = 0;
65 
66 #ifndef SWIG
67  //! Prints distribution with constructor parameters in given units.
68  //! ba.DistributionGaussian(2.0*deg, 0.02*deg)
69  virtual std::string pythonConstructor(const std::string& units) const = 0;
70 #endif
71 
72 protected:
73  //! modifies xmin and xmax if they are outside of limits
74  void adjustMinMaxForLimits(double& xmin, double& xmax, const RealLimits& limits) const;
75 
76  //! Returns weighted samples from given interpolation points and probabilityDensity().
77  std::vector<ParameterSample>
78  generateSamplesFromValues(const std::vector<double>& sample_values) const;
79 };
80 
81 #endif // USER_API
82 
83 // ************************************************************************************************
84 // class DistributionGate
85 // ************************************************************************************************
86 
87 //! Uniform distribution function with half width hwhm.
88 //! @ingroup paramDistribution
89 
91 public:
92  DistributionGate(std::vector<double> P);
93  DistributionGate(double min, double max);
95 
96  DistributionGate* clone() const override { return new DistributionGate(m_min, m_max); }
97  std::string className() const final { return "DistributionGate"; }
98  // const auto tooltip = "class_tooltip";
99  std::vector<ParaMeta> parDefs() const final
100  {
101  return {{"Min", "", "para_tooltip", -INF, +INF, 0},
102  {"Max", "", "para_tooltip", -INF, +INF, 0}};
103  }
104 
105  double probabilityDensity(double x) const override;
106  double mean() const override { return (m_min + m_max) / 2.0; }
107  double min() const { return m_min; }
108  double max() const { return m_max; }
109 
110  //! Returns list of sample values
111  std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
112  const RealLimits& limits = RealLimits()) const override;
113 
114  bool isDelta() const override;
115 
116 #ifndef SWIG
117  std::string pythonConstructor(const std::string& units) const override;
118 #endif
119 
120 private:
121  const double& m_min;
122  const double& m_max;
123 };
124 
125 // ************************************************************************************************
126 // class DistributionLorentz
127 // ************************************************************************************************
128 
129 //! Lorentz distribution with half width hwhm.
130 //! @ingroup paramDistribution
131 
133 public:
134  DistributionLorentz(std::vector<double> P);
135  DistributionLorentz(double mean, double hwhm);
137 
138  DistributionLorentz* clone() const override { return new DistributionLorentz(m_mean, m_hwhm); }
139  std::string className() const final { return "DistributionLorentz"; }
140  // const auto tooltip = "class_tooltip";
141  std::vector<ParaMeta> parDefs() const final
142  {
143  return {{"Mean", "", "para_tooltip", -INF, +INF, 0},
144  {"HWHM", "", "para_tooltip", -INF, +INF, 0}};
145  }
146 
147  double probabilityDensity(double x) const override;
148  double mean() const override { return m_mean; }
149  double hwhm() const { return m_hwhm; }
150 
151  //! generate list of sample values
152  std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
153  const RealLimits& limits = RealLimits()) const override;
154 
155  bool isDelta() const override;
156 
157 #ifndef SWIG
158  std::string pythonConstructor(const std::string& units) const override;
159 #endif
160 
161 private:
162  const double& m_mean;
163  const double& m_hwhm;
164 };
165 
166 // ************************************************************************************************
167 // class Distribution
168 // ************************************************************************************************
169 
170 //! Gaussian distribution with standard deviation std_dev.
171 //! @ingroup paramDistribution
172 
174 public:
175  DistributionGaussian(std::vector<double> P);
176  DistributionGaussian(double mean, double std_dev);
178 
179  DistributionGaussian* clone() const override
180  {
182  }
183  std::string className() const final { return "DistributionGaussian"; }
184  // const auto tooltip = "class_tooltip";
185  std::vector<ParaMeta> parDefs() const final
186  {
187  return {{"Mean", "", "para_tooltip", -INF, +INF, 0},
188  {"StdDev", "", "para_tooltip", -INF, +INF, 0}};
189  }
190 
191  double probabilityDensity(double x) const override;
192  double mean() const override { return m_mean; }
193  double getStdDev() const { return m_std_dev; }
194 
195  //! generate list of sample values
196  std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
197  const RealLimits& limits = RealLimits()) const override;
198 
199  bool isDelta() const override;
200 
201 #ifndef SWIG
202  std::string pythonConstructor(const std::string& units) const override;
203 #endif
204 
205 private:
206  const double& m_mean;
207  const double& m_std_dev;
208 };
209 
210 // ************************************************************************************************
211 // class DistributionLogNormal
212 // ************************************************************************************************
213 
214 //! Log-normal distribution.
215 //! @ingroup paramDistribution
216 
218 public:
219  DistributionLogNormal(std::vector<double> P);
220  DistributionLogNormal(double median, double scale_param);
221 
222  DistributionLogNormal* clone() const override
223  {
225  }
226  std::string className() const final { return "DistributionLogNormal"; }
227  // const auto tooltip = "class_tooltip";
228  std::vector<ParaMeta> parDefs() const final
229  {
230  return {{"Median", "", "para_tooltip", -INF, +INF, 0},
231  {"ScaleParameter", "", "para_tooltip", -INF, +INF, 0}};
232  }
233 
234  double probabilityDensity(double x) const override;
235  double mean() const override;
236  double getMedian() const { return m_median; }
237  double getScalePar() const { return m_scale_param; }
238 
239  //! generate list of sample values
240  std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
241  const RealLimits& limits = RealLimits()) const override;
242 
243  bool isDelta() const override;
244 
245 #ifndef SWIG
246  std::string pythonConstructor(const std::string& units) const override;
247 #endif
248 
249 private:
250  const double& m_median;
251  const double& m_scale_param;
252 
254 };
255 
256 // ************************************************************************************************
257 // class DistributionCosine
258 // ************************************************************************************************
259 
260 //! Cosine distribution.
261 //! @ingroup paramDistribution
262 
264 public:
265  DistributionCosine(std::vector<double> P);
266  DistributionCosine(double mean, double sigma);
268 
269  DistributionCosine* clone() const override { return new DistributionCosine(m_mean, m_sigma); }
270  std::string className() const final { return "DistributionCosine"; }
271  // const auto tooltip = "class_tooltip";
272  std::vector<ParaMeta> parDefs() const final
273  {
274  return {{"Mean", "", "para_tooltip", -INF, +INF, 0},
275  {"Sigma", "", "para_tooltip", -INF, +INF, 0}};
276  }
277 
278  double probabilityDensity(double x) const override;
279  double mean() const override { return m_mean; }
280  double sigma() const { return m_sigma; }
281 
282  //! generate list of sample values
283  std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
284  const RealLimits& limits = RealLimits()) const override;
285 
286  bool isDelta() const override;
287 
288 #ifndef SWIG
289  std::string pythonConstructor(const std::string& units) const override;
290 #endif
291 
292 private:
293  const double& m_mean;
294  const double& m_sigma;
295 };
296 
297 // ************************************************************************************************
298 // class DistributionTrapezoid
299 // ************************************************************************************************
300 
301 //! Trapezoidal distribution.
302 //! @ingroup paramDistribution
303 
305 public:
306  DistributionTrapezoid(std::vector<double> P);
307  DistributionTrapezoid(double center, double left, double middle, double right);
309 
310  DistributionTrapezoid* clone() const override
311  {
313  }
314  std::string className() const final { return "DistributionTrapezoid"; }
315  // const auto tooltip = "class_tooltip";
316  std::vector<ParaMeta> parDefs() const final
317  {
318  return {{"Center", "", "para_tooltip", -INF, +INF, 0},
319  {"LeftWidth", "", "para_tooltip", -INF, +INF, 0},
320  {"MiddleWidth", "", "para_tooltip", -INF, +INF, 0},
321  {"RightWidth", "", "para_tooltip", -INF, +INF, 0}};
322  }
323 
324  double probabilityDensity(double x) const override;
325  double mean() const override { return m_center; }
326  double getLeftWidth() const { return m_left; }
327  double getMiddleWidth() const { return m_middle; }
328  double getRightWidth() const { return m_right; }
329 
330  //! generate list of sample values
331  std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
332  const RealLimits& limits = RealLimits()) const override;
333 
334  bool isDelta() const override;
335 
336 #ifndef SWIG
337  std::string pythonConstructor(const std::string& units) const override;
338 #endif
339 
340 private:
341  void adjustLimitsToNonZeroSamples(double& min, double& max, size_t nbr_samples) const;
342  const double& m_center;
343  const double& m_left;
344  const double& m_middle;
345  const double& m_right;
346 };
347 
348 #endif // BORNAGAIN_PARAM_DISTRIB_DISTRIBUTIONS_H
Defines and implements the standard mix-in ICloneable.
Defines interface INode.
const double INF
Definition: INode.h:26
Defines class RealLimits.
Cosine distribution.
double sigma() const
DistributionCosine * clone() const override
double mean() const override
Returns the distribution-specific mean.
std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const override
generate list of sample values
std::string className() const final
Returns the class name, to be hard-coded in each leaf class that inherits from INode.
const double & m_sigma
bool isDelta() const override
Returns true if the distribution is in the limit case of a Dirac delta distribution.
std::vector< ParaMeta > parDefs() const final
Returns the parameter definitions, to be hard-coded in each leaf class.
double probabilityDensity(double x) const override
Returns the distribution-specific probability density for value x.
const double & m_mean
std::string pythonConstructor(const std::string &units) const override
Prints distribution with constructor parameters in given units. ba.DistributionGaussian(2....
Uniform distribution function with half width hwhm.
Definition: Distributions.h:90
std::string pythonConstructor(const std::string &units) const override
Prints distribution with constructor parameters in given units. ba.DistributionGaussian(2....
const double & m_max
double max() const
double probabilityDensity(double x) const override
Returns the distribution-specific probability density for value x.
DistributionGate * clone() const override
Definition: Distributions.h:96
std::vector< ParaMeta > parDefs() const final
Returns the parameter definitions, to be hard-coded in each leaf class.
Definition: Distributions.h:99
std::string className() const final
Returns the class name, to be hard-coded in each leaf class that inherits from INode.
Definition: Distributions.h:97
std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const override
Returns list of sample values.
const double & m_min
bool isDelta() const override
Returns true if the distribution is in the limit case of a Dirac delta distribution.
double min() const
double mean() const override
Returns the distribution-specific mean.
Gaussian distribution with standard deviation std_dev.
double probabilityDensity(double x) const override
Returns the distribution-specific probability density for value x.
const double & m_std_dev
std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const override
generate list of sample values
std::string className() const final
Returns the class name, to be hard-coded in each leaf class that inherits from INode.
double mean() const override
Returns the distribution-specific mean.
const double & m_mean
DistributionGaussian * clone() const override
double getStdDev() const
bool isDelta() const override
Returns true if the distribution is in the limit case of a Dirac delta distribution.
std::vector< ParaMeta > parDefs() const final
Returns the parameter definitions, to be hard-coded in each leaf class.
std::string pythonConstructor(const std::string &units) const override
Prints distribution with constructor parameters in given units. ba.DistributionGaussian(2....
Log-normal distribution.
double mean() const override
Returns the distribution-specific mean.
friend class DistributionsTest_DistributionLogNormalParameters_Test
double getMedian() const
const double & m_scale_param
double getScalePar() const
std::string pythonConstructor(const std::string &units) const override
Prints distribution with constructor parameters in given units. ba.DistributionGaussian(2....
bool isDelta() const override
Returns true if the distribution is in the limit case of a Dirac delta distribution.
DistributionLogNormal(std::vector< double > P)
std::string className() const final
Returns the class name, to be hard-coded in each leaf class that inherits from INode.
std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const override
generate list of sample values
DistributionLogNormal * clone() const override
const double & m_median
std::vector< ParaMeta > parDefs() const final
Returns the parameter definitions, to be hard-coded in each leaf class.
double probabilityDensity(double x) const override
Returns the distribution-specific probability density for value x.
Lorentz distribution with half width hwhm.
bool isDelta() const override
Returns true if the distribution is in the limit case of a Dirac delta distribution.
double hwhm() const
std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const override
generate list of sample values
const double & m_mean
std::vector< ParaMeta > parDefs() const final
Returns the parameter definitions, to be hard-coded in each leaf class.
double mean() const override
Returns the distribution-specific mean.
std::string className() const final
Returns the class name, to be hard-coded in each leaf class that inherits from INode.
DistributionLorentz * clone() const override
double probabilityDensity(double x) const override
Returns the distribution-specific probability density for value x.
std::string pythonConstructor(const std::string &units) const override
Prints distribution with constructor parameters in given units. ba.DistributionGaussian(2....
const double & m_hwhm
Trapezoidal distribution.
std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const override
generate list of sample values
double mean() const override
Returns the distribution-specific mean.
double probabilityDensity(double x) const override
Returns the distribution-specific probability density for value x.
std::string pythonConstructor(const std::string &units) const override
Prints distribution with constructor parameters in given units. ba.DistributionGaussian(2....
double getRightWidth() const
double getLeftWidth() const
double getMiddleWidth() const
const double & m_center
const double & m_left
std::string className() const final
Returns the class name, to be hard-coded in each leaf class that inherits from INode.
const double & m_middle
DistributionTrapezoid * clone() const override
std::vector< ParaMeta > parDefs() const final
Returns the parameter definitions, to be hard-coded in each leaf class.
const double & m_right
void adjustLimitsToNonZeroSamples(double &min, double &max, size_t nbr_samples) const
bool isDelta() const override
Returns true if the distribution is in the limit case of a Dirac delta distribution.
Interface for polymorphic classes that should not be copied, except by explicit cloning.
Definition: ICloneable.h:23
Interface for one-dimensional distributions.
Definition: Distributions.h:33
std::vector< ParameterSample > generateSamplesFromValues(const std::vector< double > &sample_values) const
Returns weighted samples from given interpolation points and probabilityDensity().
virtual double probabilityDensity(double x) const =0
Returns the distribution-specific probability density for value x.
std::vector< ParameterSample > equidistantSamplesInRange(size_t nbr_samples, double xmin, double xmax) const
Returns equidistant samples from xmin to xmax, weighted with probabilityDensity().
virtual double mean() const =0
Returns the distribution-specific mean.
void adjustMinMaxForLimits(double &xmin, double &xmax, const RealLimits &limits) const
modifies xmin and xmax if they are outside of limits
virtual std::string pythonConstructor(const std::string &units) const =0
Prints distribution with constructor parameters in given units. ba.DistributionGaussian(2....
virtual std::vector< double > equidistantPointsInRange(size_t nbr_samples, double xmin, double xmax) const
Returns equidistant interpolation points from xmin to xmax.
IDistribution1D(const std::vector< double > &PValues)
virtual bool isDelta() const =0
Returns true if the distribution is in the limit case of a Dirac delta distribution.
virtual std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const =0
Returns equidistant interpolation points, with range computed in distribution-specific way from mean ...
std::vector< ParameterSample > equidistantSamples(size_t nbr_samples, double sigma_factor=0., const RealLimits &limits=RealLimits()) const
Returns equidistant samples, using intrinsic parameters, weighted with probabilityDensity().
IDistribution1D * clone() const override=0
Base class for tree-like structures containing parameterized objects.
Definition: INode.h:40
A parameter value with a weight, as obtained when sampling from a distribution.
Limits for a real fit parameter.
Definition: RealLimits.h:24