BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
RangedDistributions.h
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Param/Distrib/RangedDistributions.h
6 //! @brief Defines classes representing ranged 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_RANGEDDISTRIBUTIONS_H
16 #define BORNAGAIN_CORE_PARAMETRIZATION_RANGEDDISTRIBUTIONS_H
17 
18 #include "Base/Types/ICloneable.h"
19 #include "Fit/Tools/RealLimits.h"
20 #include <memory>
21 #include <vector>
22 
23 class IDistribution1D;
24 class ParameterSample;
25 
26 // ************************************************************************** //
27 // interface class IDistribution1D
28 // ************************************************************************** //
29 
30 //! Interface for one-dimensional ranged distributions.
31 //! All derived distributions
32 //! allow for generating samples in-place for known mean and standard deviation
33 //! (except for RangedDistributionLorentz which uses median and hwhm).
34 //! @ingroup distribution_internal
35 
37 {
38 public:
40  RangedDistribution(size_t n_samples, double sigma_factor,
42  //! Initializes Ranged distribution with given number of samples, sigma factor
43  //! (range in standard deviations to take into account during sample generation)
44  //! and limits (either RealLimits object or just min and max limits).
45  //! By default _n_samples_ = 5, _sigma_factor_ = 2.0, while the limits are (-inf, +inf).
46  RangedDistribution(size_t n_samples, double sigma_factor, double min, double max);
47  RangedDistribution* clone() const override = 0;
48 
49  ~RangedDistribution() override;
50 
51  std::vector<ParameterSample> generateSamples(double mean, double stddev) const;
52  //! Generates list of sampled values with their weights from given means and standard
53  //! deviations.
54  std::vector<std::vector<ParameterSample>>
55  generateSamples(const std::vector<double>& mean, const std::vector<double>& stddev) const;
56 
57  //! Public interface function to underlying IDistribution1D object
58  std::unique_ptr<IDistribution1D> distribution(double mean, double stddev) const;
59 
60  // getters
61 
62  //! Returns current limits of the distribution
63  RealLimits limits() const { return m_limits; }
64  //! Returns sigma factor to use during sampling
65  double sigmaFactor() const { return m_sigma_factor; }
66  //! Returns number of samples to generate
67  size_t nSamples() const { return m_n_samples; }
68 
69  // setters
70 
72 
73  //! Prints python-formatted definition of the distribution
74  std::string pyString() const;
75 
76 protected:
77  //! Returns distribution name for python-formatted text.
78  virtual std::string name() const = 0;
79  //! Returns underlying IDistribution1D object
80  virtual std::unique_ptr<IDistribution1D> distribution_impl(double mean,
81  double stddev) const = 0;
82 
83 private:
84  void checkInitialization();
85 
86  size_t m_n_samples;
89 };
90 
91 // ************************************************************************** //
92 // specific distribution classes
93 // ************************************************************************** //
94 
95 //! Uniform distribution function.
96 //! @ingroup paramDistribution
97 
99 {
100 public:
102  RangedDistributionGate(size_t n_samples, double sigma_factor,
104  //! Initializes Ranged distribution with given number of samples, sigma factor
105  //! (range in standard deviations to take into account during sample generation)
106  //! and limits (either RealLimits object or just min and max limits).
107  //! By default _n_samples_ = 5, _sigma_factor_ = 2.0, while the limits are (-inf, +inf).
108  RangedDistributionGate(size_t n_samples, double sigma_factor, double min, double max);
109 
110  RangedDistributionGate* clone() const override;
111  ~RangedDistributionGate() override = default;
112 
113 protected:
114  //! Returns distribution name for python-formatted text.
115  std::string name() const override;
116  //! Returns underlying IDistribution1D object
117  std::unique_ptr<IDistribution1D> distribution_impl(double mean, double stddev) const override;
118 };
119 
120 //! Lorentz distribution with median and hwhm.
121 //! @ingroup paramDistribution
122 
124 {
125 public:
127  RangedDistributionLorentz(size_t n_samples, double hwhm_factor,
129  //! Initializes Ranged distribution with given number of samples, sigma factor
130  //! (range in standard deviations to take into account during sample generation)
131  //! and limits (either RealLimits object or just min and max limits).
132  //! By default _n_samples_ = 5, _hwhm_factor_ = 2.0, while the limits are (-inf, +inf).
133  RangedDistributionLorentz(size_t n_samples, double hwhm_factor, double min, double max);
134 
135  RangedDistributionLorentz* clone() const override;
136  ~RangedDistributionLorentz() override = default;
137 
138 protected:
139  //! Returns distribution name for python-formatted text.
140  std::string name() const override;
141  //! Returns underlying IDistribution1D object
142  std::unique_ptr<IDistribution1D> distribution_impl(double median, double hwhm) const override;
143 };
144 
145 //! Gaussian distribution with standard deviation std_dev.
146 //! @ingroup paramDistribution
147 
149 {
150 public:
152  RangedDistributionGaussian(size_t n_samples, double sigma_factor,
154  //! Initializes Ranged distribution with given number of samples, sigma factor
155  //! (range in standard deviations to take into account during sample generation)
156  //! and limits (either RealLimits object or just min and max limits).
157  //! By default _n_samples_ = 5, _sigma_factor_ = 2.0, while the limits are (-inf, +inf).
158  RangedDistributionGaussian(size_t n_samples, double sigma_factor, double min, double max);
159 
160  RangedDistributionGaussian* clone() const override;
161  ~RangedDistributionGaussian() override = default;
162 
163 protected:
164  //! Returns distribution name for python-formatted text.
165  std::string name() const override;
166  //! Returns underlying IDistribution1D object
167  std::unique_ptr<IDistribution1D> distribution_impl(double mean, double stddev) const override;
168 };
169 
170 //! Log-normal distribution.
171 //! @ingroup paramDistribution
172 
174 {
175 public:
177  RangedDistributionLogNormal(size_t n_samples, double sigma_factor,
179  //! Initializes Ranged distribution with given number of samples, sigma factor
180  //! (range in standard deviations to take into account during sample generation)
181  //! and limits (either RealLimits object or just min and max limits).
182  //! By default _n_samples_ = 5, _sigma_factor_ = 2.0, while the limits are (-inf, +inf).
183  RangedDistributionLogNormal(size_t n_samples, double sigma_factor, double min, double max);
184 
185  RangedDistributionLogNormal* clone() const override;
186  ~RangedDistributionLogNormal() override = default;
187 
188 protected:
189  //! Returns distribution name for python-formatted text.
190  std::string name() const override;
191  //! Returns underlying IDistribution1D object
192  std::unique_ptr<IDistribution1D> distribution_impl(double mean, double stddev) const override;
193 };
194 
195 //! Cosine distribution.
196 //! @ingroup paramDistribution
197 
199 {
200 public:
202  RangedDistributionCosine(size_t n_samples, double sigma_factor,
204  //! Initializes Ranged distribution with given number of samples, sigma factor
205  //! (range in standard deviations to take into account during sample generation)
206  //! and limits (either RealLimits object or just min and max limits).
207  //! By default _n_samples_ = 5, _sigma_factor_ = 2.0, while the limits are (-inf, +inf).
208  RangedDistributionCosine(size_t n_samples, double sigma_factor, double min, double max);
209 
210  RangedDistributionCosine* clone() const override;
211  ~RangedDistributionCosine() override = default;
212 
213 protected:
214  //! Returns distribution name for python-formatted text.
215  std::string name() const override;
216  //! Returns underlying IDistribution1D object
217  std::unique_ptr<IDistribution1D> distribution_impl(double mean, double stddev) const override;
218 };
219 
220 inline std::ostream& operator<<(std::ostream& os, const RangedDistribution& distribution)
221 {
222  return os << distribution.pyString();
223 }
224 
225 #endif // BORNAGAIN_CORE_PARAMETRIZATION_RANGEDDISTRIBUTIONS_H
Defines and implements the standard mix-in ICloneable.
Defines class RealLimits.
std::ostream & operator<<(std::ostream &os, const BasicVector3D< T > &a)
Output to stream.
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
A parameter value with a weight, as obtained when sampling from a distribution.
~RangedDistributionCosine() override=default
RangedDistributionCosine * clone() const override
std::unique_ptr< IDistribution1D > distribution_impl(double mean, double stddev) const override
Returns underlying IDistribution1D object.
std::string name() const override
Returns distribution name for python-formatted text.
Uniform distribution function.
~RangedDistributionGate() override=default
RangedDistributionGate * clone() const override
std::string name() const override
Returns distribution name for python-formatted text.
std::unique_ptr< IDistribution1D > distribution_impl(double mean, double stddev) const override
Returns underlying IDistribution1D object.
Gaussian distribution with standard deviation std_dev.
std::string name() const override
Returns distribution name for python-formatted text.
std::unique_ptr< IDistribution1D > distribution_impl(double mean, double stddev) const override
Returns underlying IDistribution1D object.
~RangedDistributionGaussian() override=default
RangedDistributionGaussian * clone() const override
Log-normal distribution.
RangedDistributionLogNormal * clone() const override
std::string name() const override
Returns distribution name for python-formatted text.
~RangedDistributionLogNormal() override=default
std::unique_ptr< IDistribution1D > distribution_impl(double mean, double stddev) const override
Returns underlying IDistribution1D object.
Lorentz distribution with median and hwhm.
~RangedDistributionLorentz() override=default
std::string name() const override
Returns distribution name for python-formatted text.
std::unique_ptr< IDistribution1D > distribution_impl(double median, double hwhm) const override
Returns underlying IDistribution1D object.
RangedDistributionLorentz * clone() const override
Interface for one-dimensional ranged distributions.
std::string pyString() const
Prints python-formatted definition of the distribution.
RangedDistribution * clone() const override=0
RealLimits limits() const
Returns current limits of the distribution.
~RangedDistribution() override
virtual std::unique_ptr< IDistribution1D > distribution_impl(double mean, double stddev) const =0
Returns underlying IDistribution1D object.
size_t nSamples() const
Returns number of samples to generate.
std::vector< ParameterSample > generateSamples(double mean, double stddev) const
std::unique_ptr< IDistribution1D > distribution(double mean, double stddev) const
Public interface function to underlying IDistribution1D object.
double sigmaFactor() const
Returns sigma factor to use during sampling.
virtual std::string name() const =0
Returns distribution name for python-formatted text.
void setLimits(const RealLimits &limits)
Limits for a real fit parameter.
Definition: RealLimits.h:25
static RealLimits limitless()
Creates an object withoud bounds (default)
Definition: RealLimits.cpp:128