BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
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 //! @ingroup distribution_internal
33 
34 class IDistribution1D : public ICloneable, public INode {
35 public:
36  IDistribution1D(const NodeMeta& meta, const std::vector<double>& PValues);
37 
38  virtual IDistribution1D* clone() const = 0;
39 
40  //! Returns the distribution-specific probability density for value x.
41  virtual double probabilityDensity(double x) const = 0;
42 
43  //! Returns the distribution-specific mean.
44  virtual double getMean() const = 0;
45 
46  //! Returns equidistant samples, using intrinsic parameters, weighted with probabilityDensity().
47  std::vector<ParameterSample> equidistantSamples(size_t nbr_samples, double sigma_factor = 0.,
48  const RealLimits& limits = RealLimits()) const;
49 
50  //! Returns equidistant samples from xmin to xmax, weighted with probabilityDensity().
51  std::vector<ParameterSample> equidistantSamplesInRange(size_t nbr_samples, double xmin,
52  double xmax) const;
53 
54  //! Returns equidistant interpolation points, with range computed in distribution-specific
55  //! way from mean and width parameter, taking into account limits and sigma_factor.
56  virtual std::vector<double>
57  equidistantPoints(size_t nbr_samples, double sigma_factor,
58  const RealLimits& limits = RealLimits()) const = 0;
59 
60  //! Returns equidistant interpolation points from xmin to xmax.
61  virtual std::vector<double> equidistantPointsInRange(size_t nbr_samples, double xmin,
62  double xmax) const;
63 
64  //! Returns true if the distribution is in the limit case of a Dirac delta distribution.
65  virtual bool isDelta() const = 0;
66 
67  //! Sets distribution units.
68  virtual void setUnits(const std::string& units);
69 
70 protected:
71  //! modifies xmin and xmax if they are outside of limits
72  void adjustMinMaxForLimits(double& xmin, double& xmax, const RealLimits& limits) const;
73 
74  //! Returns weighted samples from given interpolation points and probabilityDensity().
75  std::vector<ParameterSample>
76  generateSamplesFromValues(const std::vector<double>& sample_values) const;
77 };
78 
79 #endif // USER_API
80 
81 // ************************************************************************************************
82 // class DistributionGate
83 // ************************************************************************************************
84 
85 //! Uniform distribution function with half width hwhm.
86 //! @ingroup paramDistribution
87 
89 public:
90  DistributionGate(const std::vector<double> P);
91  DistributionGate(double min, double max);
93 
94  DistributionGate* clone() const final { return new DistributionGate(m_min, m_max); }
95 
96  double probabilityDensity(double x) const final;
97  double getMean() const final { return (m_min + m_max) / 2.0; }
98  double lowerBound() const { return m_min; }
99  double upperBound() const { return m_max; }
100 
101  //! Returns list of sample values
102  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
103  const RealLimits& limits = RealLimits()) const;
104 
105  bool isDelta() const final;
106 
107  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
108 
109 private:
110  const double& m_min;
111  const double& m_max;
112 };
113 
114 // ************************************************************************************************
115 // class DistributionLorentz
116 // ************************************************************************************************
117 
118 //! Lorentz distribution with half width hwhm.
119 //! @ingroup paramDistribution
120 
122 public:
123  DistributionLorentz(const std::vector<double> P);
124  DistributionLorentz(double mean, double hwhm);
126 
127  DistributionLorentz* clone() const final { return new DistributionLorentz(m_mean, m_hwhm); }
128 
129  double probabilityDensity(double x) const final;
130  double getMean() const final { return m_mean; }
131  double getHWHM() const { return m_hwhm; }
132 
133  //! generate list of sample values
134  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
135  const RealLimits& limits = RealLimits()) const;
136 
137  bool isDelta() const final;
138 
139  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
140 
141 private:
142  const double& m_mean;
143  const double& m_hwhm;
144 };
145 
146 // ************************************************************************************************
147 // class Distribution
148 // ************************************************************************************************
149 
150 //! Gaussian distribution with standard deviation std_dev.
151 //! @ingroup paramDistribution
152 
154 public:
155  DistributionGaussian(const std::vector<double> P);
156  DistributionGaussian(double mean, double std_dev);
158 
160  {
162  }
163 
164  double probabilityDensity(double x) const final;
165  double getMean() const final { return m_mean; }
166  double getStdDev() const { return m_std_dev; }
167 
168  //! generate list of sample values
169  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
170  const RealLimits& limits = RealLimits()) const;
171 
172  bool isDelta() const final;
173 
174  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
175 
176 private:
177  const double& m_mean;
178  const double& m_std_dev;
179 };
180 
181 // ************************************************************************************************
182 // class DistributionLogNormal
183 // ************************************************************************************************
184 
185 //! Log-normal distribution.
186 //! @ingroup paramDistribution
187 
189 public:
190  DistributionLogNormal(const std::vector<double> P);
191  DistributionLogNormal(double median, double scale_param);
193 
195  {
197  }
198 
199  double probabilityDensity(double x) const final;
200  double getMean() const final;
201  double getMedian() const { return m_median; }
202  double getScalePar() const { return m_scale_param; }
203 
204  //! generate list of sample values
205  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
206  const RealLimits& limits = RealLimits()) const;
207 
208  bool isDelta() const final;
209 
210  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
211 
212  virtual void setUnits(const std::string& units);
213 
214 private:
215  const double& m_median;
216  const double& m_scale_param;
217 };
218 
219 // ************************************************************************************************
220 // class DistributionCosine
221 // ************************************************************************************************
222 
223 //! Cosine distribution.
224 //! @ingroup paramDistribution
225 
227 public:
228  DistributionCosine(const std::vector<double> P);
229  DistributionCosine(double mean, double sigma);
231 
232  DistributionCosine* clone() const final { return new DistributionCosine(m_mean, m_sigma); }
233 
234  double probabilityDensity(double x) const final;
235  double getMean() const final { return m_mean; }
236  double getSigma() const { return m_sigma; }
237 
238  //! generate list of sample values
239  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
240  const RealLimits& limits = RealLimits()) const;
241 
242  bool isDelta() const final;
243 
244  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
245 
246 private:
247  const double& m_mean;
248  const double& m_sigma;
249 };
250 
251 // ************************************************************************************************
252 // class DistributionTrapezoid
253 // ************************************************************************************************
254 
255 //! Trapezoidal distribution.
256 //! @ingroup paramDistribution
257 
259 public:
260  DistributionTrapezoid(const std::vector<double> P);
261  DistributionTrapezoid(double center, double left, double middle, double right);
263 
265  {
267  }
268 
269  double probabilityDensity(double x) const final;
270  double getMean() const final { return m_center; }
271  double getLeftWidth() const { return m_left; }
272  double getMiddleWidth() const { return m_middle; }
273  double getRightWidth() const { return m_right; }
274 
275  //! generate list of sample values
276  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
277  const RealLimits& limits = RealLimits()) const;
278 
279  bool isDelta() const final;
280 
281  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
282 
283 private:
284  void adjustLimitsToNonZeroSamples(double& min, double& max, size_t nbr_samples) const;
285  const double& m_center;
286  const double& m_left;
287  const double& m_middle;
288  const double& m_right;
289 };
290 
291 #endif // BORNAGAIN_PARAM_DISTRIB_DISTRIBUTIONS_H
Defines and implements the standard mix-in ICloneable.
Defines interface INode.
Defines class RealLimits.
Cosine distribution.
double getMean() const final
Returns the distribution-specific mean.
const double & m_sigma
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
void accept(INodeVisitor *visitor) const final
Calls the INodeVisitor's visit method.
bool isDelta() const final
Returns true if the distribution is in the limit case of a Dirac delta distribution.
double getSigma() const
const double & m_mean
virtual std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const
generate list of sample values
DistributionCosine * clone() const final
Uniform distribution function with half width hwhm.
Definition: Distributions.h:88
double lowerBound() const
Definition: Distributions.h:98
void accept(INodeVisitor *visitor) const final
Calls the INodeVisitor's visit method.
const double & m_max
double upperBound() const
Definition: Distributions.h:99
DistributionGate * clone() const final
Definition: Distributions.h:94
const double & m_min
bool isDelta() const final
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
Returns list of sample values.
double getMean() const final
Returns the distribution-specific mean.
Definition: Distributions.h:97
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
Gaussian distribution with standard deviation std_dev.
double getMean() const final
Returns the distribution-specific mean.
bool isDelta() const final
Returns true if the distribution is in the limit case of a Dirac delta distribution.
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
const double & m_std_dev
const double & m_mean
void accept(INodeVisitor *visitor) const final
Calls the INodeVisitor's visit method.
virtual std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const
generate list of sample values
double getStdDev() const
DistributionGaussian * clone() const final
Log-normal distribution.
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
DistributionLogNormal * clone() const final
double getMean() const final
Returns the distribution-specific mean.
double getMedian() const
const double & m_scale_param
virtual void setUnits(const std::string &units)
Sets distribution units.
void accept(INodeVisitor *visitor) const final
Calls the INodeVisitor's visit method.
double getScalePar() const
DistributionLogNormal()=delete
bool isDelta() const final
Returns true if the distribution is in the limit case of a Dirac delta distribution.
const double & m_median
virtual std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const
generate list of sample values
Lorentz distribution with half width hwhm.
bool isDelta() const final
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
generate list of sample values
DistributionLorentz * clone() const final
double getHWHM() const
double getMean() const final
Returns the distribution-specific mean.
const double & m_mean
void accept(INodeVisitor *visitor) const final
Calls the INodeVisitor's visit method.
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
const double & m_hwhm
Trapezoidal distribution.
bool isDelta() const final
Returns true if the distribution is in the limit case of a Dirac delta distribution.
double getMean() const final
Returns the distribution-specific mean.
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
virtual std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const
generate list of sample values
DistributionTrapezoid * clone() const final
double getRightWidth() const
double getLeftWidth() const
double getMiddleWidth() const
const double & m_center
void accept(INodeVisitor *visitor) const final
Calls the INodeVisitor's visit method.
const double & m_left
const double & m_middle
const double & m_right
void adjustLimitsToNonZeroSamples(double &min, double &max, size_t nbr_samples) const
Interface for polymorphic classes that should not be copied, except by explicit cloning.
Definition: ICloneable.h:25
Interface for one-dimensional distributions.
Definition: Distributions.h:34
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.
virtual double getMean() const =0
Returns the distribution-specific mean.
std::vector< ParameterSample > equidistantSamplesInRange(size_t nbr_samples, double xmin, double xmax) const
Returns equidistant samples from xmin to xmax, weighted with probabilityDensity().
IDistribution1D(const NodeMeta &meta, const std::vector< double > &PValues)
void adjustMinMaxForLimits(double &xmin, double &xmax, const RealLimits &limits) const
modifies xmin and xmax if they are outside of limits
virtual std::vector< double > equidistantPointsInRange(size_t nbr_samples, double xmin, double xmax) const
Returns equidistant interpolation points from xmin to xmax.
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 ...
virtual IDistribution1D * clone() const =0
virtual void setUnits(const std::string &units)
Sets distribution units.
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().
Visitor interface to visit ISampleNode objects.
Definition: INodeVisitor.h:146
Base class for tree-like structures containing parameterized objects.
Definition: INode.h:49
A parameter value with a weight, as obtained when sampling from a distribution.
Limits for a real fit parameter.
Definition: RealLimits.h:24
Metadata of one model node.
Definition: INode.h:38