BornAgain  1.18.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 scattering at grazing incidence
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_CORE_PARAMETRIZATION_DISTRIBUTIONS_H
16 #define BORNAGAIN_CORE_PARAMETRIZATION_DISTRIBUTIONS_H
17 
18 #include "Base/Types/ICloneable.h"
19 #include "Fit/Tools/RealLimits.h"
20 #include "Param/Node/INode.h"
21 #include <vector>
22 
23 class ParameterSample;
24 
25 // ************************************************************************** //
26 // interface IDistribution1D
27 // ************************************************************************** //
28 
29 //! Interface for one-dimensional distributions.
30 //! @ingroup distribution_internal
31 
32 class IDistribution1D : public ICloneable, public INode
33 {
34 public:
35  IDistribution1D(const NodeMeta& meta, const std::vector<double>& PValues);
36 
37  virtual IDistribution1D* clone() const = 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 getMean() 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  //! Sets distribution units.
67  virtual void setUnits(const std::string& units);
68 
69 protected:
70  //! modifies xmin and xmax if they are outside of limits
71  void adjustMinMaxForLimits(double& xmin, double& xmax, const RealLimits& limits) const;
72 
73  //! Returns weighted samples from given interpolation points and probabilityDensity().
74  std::vector<ParameterSample>
75  generateSamplesFromValues(const std::vector<double>& sample_values) const;
76 };
77 
78 // ************************************************************************** //
79 // class DistributionGate
80 // ************************************************************************** //
81 
82 //! Uniform distribution function with half width hwhm.
83 //! @ingroup paramDistribution
84 
86 {
87 public:
88  DistributionGate(const std::vector<double> P);
89  DistributionGate(double min, double max);
91 
92  DistributionGate* clone() const final { return new DistributionGate(m_min, m_max); }
93 
94  double probabilityDensity(double x) const final;
95  double getMean() const final { return (m_min + m_max) / 2.0; }
96  double getMin() const { return m_min; }
97  double getMax() const { return m_max; }
98 
99  //! Returns list of sample values
100  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
101  const RealLimits& limits = RealLimits()) const;
102 
103  bool isDelta() const final;
104 
105  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
106 
107 private:
108  const double& m_min;
109  const double& m_max;
110 };
111 
112 // ************************************************************************** //
113 // class DistributionLorentz
114 // ************************************************************************** //
115 
116 //! Lorentz distribution with half width hwhm.
117 //! @ingroup paramDistribution
118 
120 {
121 public:
122  DistributionLorentz(const std::vector<double> P);
123  DistributionLorentz(double mean, double hwhm);
125 
126  DistributionLorentz* clone() const final { return new DistributionLorentz(m_mean, m_hwhm); }
127 
128  double probabilityDensity(double x) const final;
129  double getMean() const final { return m_mean; }
130  double getHWHM() const { return m_hwhm; }
131 
132  //! generate list of sample values
133  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
134  const RealLimits& limits = RealLimits()) const;
135 
136  bool isDelta() const final;
137 
138  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
139 
140 private:
141  const double& m_mean;
142  const double& m_hwhm;
143 };
144 
145 // ************************************************************************** //
146 // class Distribution
147 // ************************************************************************** //
148 
149 //! Gaussian distribution with standard deviation std_dev.
150 //! @ingroup paramDistribution
151 
153 {
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 {
190 public:
191  DistributionLogNormal(const std::vector<double> P);
192  DistributionLogNormal(double median, double scale_param);
194 
196  {
198  }
199 
200  double probabilityDensity(double x) const final;
201  double getMean() const final;
202  double getMedian() const { return m_median; }
203  double getScalePar() const { return m_scale_param; }
204 
205  //! generate list of sample values
206  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
207  const RealLimits& limits = RealLimits()) const;
208 
209  bool isDelta() const final;
210 
211  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
212 
213  virtual void setUnits(const std::string& units);
214 
215 private:
216  const double& m_median;
217  const double& m_scale_param;
218 };
219 
220 // ************************************************************************** //
221 // class DistributionCosine
222 // ************************************************************************** //
223 
224 //! Cosine distribution.
225 //! @ingroup paramDistribution
226 
228 {
229 public:
230  DistributionCosine(const std::vector<double> P);
231  DistributionCosine(double mean, double sigma);
233 
234  DistributionCosine* clone() const final { return new DistributionCosine(m_mean, m_sigma); }
235 
236  double probabilityDensity(double x) const final;
237  double getMean() const final { return m_mean; }
238  double getSigma() const { return m_sigma; }
239 
240  //! generate list of sample values
241  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
242  const RealLimits& limits = RealLimits()) const;
243 
244  bool isDelta() const final;
245 
246  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
247 
248 private:
249  const double& m_mean;
250  const double& m_sigma;
251 };
252 
253 // ************************************************************************** //
254 // class DistributionTrapezoid
255 // ************************************************************************** //
256 
257 //! Trapezoidal distribution.
258 //! @ingroup paramDistribution
259 
261 {
262 public:
263  DistributionTrapezoid(const std::vector<double> P);
264  DistributionTrapezoid(double center, double left, double middle, double right);
266 
268  {
270  }
271 
272  double probabilityDensity(double x) const final;
273  double getMean() const final { return m_center; }
274  double getLeftWidth() const { return m_left; }
275  double getMiddleWidth() const { return m_middle; }
276  double getRightWidth() const { return m_right; }
277 
278  //! generate list of sample values
279  virtual std::vector<double> equidistantPoints(size_t nbr_samples, double sigma_factor,
280  const RealLimits& limits = RealLimits()) const;
281 
282  bool isDelta() const final;
283 
284  void accept(INodeVisitor* visitor) const final { visitor->visit(this); }
285 
286 private:
287  void adjustLimitsToNonZeroSamples(double& min, double& max, size_t nbr_samples) const;
288  const double& m_center;
289  const double& m_left;
290  const double& m_middle;
291  const double& m_right;
292 };
293 
294 #endif // BORNAGAIN_CORE_PARAMETRIZATION_DISTRIBUTIONS_H
Defines and implements the standard mix-in ICloneable.
Defines class 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:86
void accept(INodeVisitor *visitor) const final
Calls the INodeVisitor's visit method.
double getMin() const
Definition: Distributions.h:96
const double & m_max
double getMax() const
Definition: Distributions.h:97
DistributionGate * clone() const final
Definition: Distributions.h:92
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:95
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: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.
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 ISample objects.
Definition: INodeVisitor.h:149
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:25
Metadata of one model node.
Definition: INode.h:37