24 template <
class T> std::unique_ptr<T> makeCopy(
const T& item);
26 const double gate_stddev_factor = 2.0 * std::sqrt(3.0);
29 RangedDistribution::RangedDistribution()
30 : m_n_samples(5), m_sigma_factor(2.0), m_limits(
RealLimits::limitless())
32 checkInitialization();
35 RangedDistribution::RangedDistribution(
size_t n_samples,
double sigma_factor,
37 : m_n_samples(n_samples), m_sigma_factor(sigma_factor), m_limits(limits)
39 checkInitialization();
42 RangedDistribution::RangedDistribution(
size_t n_samples,
double sigma_factor,
double min,
44 : m_n_samples(n_samples), m_sigma_factor(sigma_factor), m_limits(
RealLimits::limited(min, max))
46 checkInitialization();
49 RangedDistribution::~RangedDistribution() =
default;
51 std::vector<ParameterSample> RangedDistribution::generateSamples(
double mean,
double stddev)
const
54 if (!generator->isDelta())
55 return generator->equidistantSamples(m_n_samples, m_sigma_factor, m_limits);
58 auto samples = generator->equidistantSamples(m_n_samples, m_sigma_factor, m_limits);
60 sample.weight = 1.0 / m_n_samples;
61 return std::vector<ParameterSample>(m_n_samples, sample);
64 std::vector<std::vector<ParameterSample>>
65 RangedDistribution::generateSamples(
const std::vector<double>& mean,
66 const std::vector<double>& stddev)
const
68 if (mean.size() != stddev.size())
69 throw std::runtime_error(
"Error in RangedDistribution::generateSamples: mean and variance "
70 "vectors shall be of the same size");
72 const size_t size = mean.size();
74 std::vector<std::vector<ParameterSample>> result;
76 for (
size_t i = 0; i < size; ++i)
77 result[i] = generateSamples(mean[i], stddev[i]);
84 throw std::runtime_error(
85 "Error in RangedDistribution::distribution: standard deviation is less than zero");
91 std::stringstream result;
93 result <<
"(" << m_n_samples <<
", " << pyfmt::printDouble(m_sigma_factor);
94 if (!m_limits.isLimitless())
100 void RangedDistribution::checkInitialization()
102 if (m_n_samples < 1u)
103 throw std::runtime_error(
"Error in RangedDistribution::checkInitialization: number of "
104 "samples shall be positive");
106 if (m_sigma_factor < 0.0)
107 throw std::runtime_error(
"Error in RangedDistribution::checkInitialization: sigma factor "
108 "shall be non-negative.");
114 throw std::runtime_error(
"Error in RangedDistribution::checkInitialization: lower limit "
115 "shall not exceed the upper one.");
120 RangedDistributionGate::RangedDistributionGate(
size_t n_samples,
double sigma_factor,
126 RangedDistributionGate::RangedDistributionGate(
size_t n_samples,
double sigma_factor,
double min,
134 return makeCopy(*this).release();
139 return "ba.RangedDistributionGate";
145 const double x_min = mean - gate_stddev_factor * stddev;
146 const double x_max = mean + gate_stddev_factor * stddev;
147 return std::make_unique<DistributionGate>(x_min, x_max);
152 RangedDistributionLorentz::RangedDistributionLorentz(
size_t n_samples,
double hwhm_factor,
158 RangedDistributionLorentz::RangedDistributionLorentz(
size_t n_samples,
double hwhm_factor,
159 double min,
double max)
166 return makeCopy(*this).release();
171 return "ba.RangedDistributionLorentz";
177 return std::make_unique<DistributionLorentz>(median, hwhm);
182 RangedDistributionGaussian::RangedDistributionGaussian(
size_t n_samples,
double sigma_factor,
188 RangedDistributionGaussian::RangedDistributionGaussian(
size_t n_samples,
double sigma_factor,
189 double min,
double max)
196 return makeCopy(*this).release();
201 return "ba.RangedDistributionGaussian";
207 return std::make_unique<DistributionGaussian>(mean, stddev);
212 RangedDistributionLogNormal::RangedDistributionLogNormal(
size_t n_samples,
double sigma_factor,
218 RangedDistributionLogNormal::RangedDistributionLogNormal(
size_t n_samples,
double sigma_factor,
219 double min,
double max)
226 return makeCopy(*this).release();
231 return "ba.RangedDistributionLogNormal";
237 const double mean_2 = mean * mean;
238 if (mean_2 <= std::numeric_limits<double>::min())
239 throw std::runtime_error(
"Error in DistributionLogNormal::distribution: mean square value "
240 "is less or indistinguishable from zero.");
242 const double scale = std::sqrt(std::log(stddev * stddev / mean_2 + 1.0));
243 const double median = mean * std::exp(-scale * scale / 2.0);
244 return std::make_unique<DistributionLogNormal>(median, scale);
249 RangedDistributionCosine::RangedDistributionCosine(
size_t n_samples,
double sigma_factor,
255 RangedDistributionCosine::RangedDistributionCosine(
size_t n_samples,
double sigma_factor,
256 double min,
double max)
263 return makeCopy(*this).release();
268 return "ba.RangedDistributionCosine";
274 return std::make_unique<DistributionCosine>(mean, stddev);
279 template <
class T> std::unique_ptr<T> makeCopy(
const T& item)
281 return std::make_unique<T>(item.nSamples(), item.sigmaFactor(), item.limits());
Defines classes representing one-dimensional distributions.
Defines class ParameterSample.
Defines functions in namespace pyfmt.
Defines functions in namespace pyfmt.
Defines classes representing ranged one-dimensional distributions.
A parameter value with a weight, as obtained when sampling from a distribution.
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.
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.
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.
Lorentz distribution with median and hwhm.
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.
Interface for one-dimensional ranged distributions.
std::string pyString() const
Prints python-formatted definition of the distribution.
virtual std::unique_ptr< IDistribution1D > distribution_impl(double mean, double stddev) const =0
Returns underlying IDistribution1D object.
std::unique_ptr< IDistribution1D > distribution(double mean, double stddev) const
Public interface function to underlying IDistribution1D object.
virtual std::string name() const =0
Returns distribution name for python-formatted text.
Limits for a real fit parameter.
bool hasLowerAndUpperLimits() const
if has lower and upper limit
double upperLimit() const
Returns upper limit.
double lowerLimit() const
Returns lower limit.
std::string indent(size_t width)
Returns a string of blanks with given width.
std::string printRealLimitsArg(const RealLimits &limits, const std::string &units)
Prints RealLimits in the form of argument (in the context of ParameterDistribution and similar).