28 bool DoubleEqual(
double a,
double b);
35 IDistribution1D::IDistribution1D(
const NodeMeta& meta,
const std::vector<double>& PValues)
36 :
INode(meta, PValues)
48 "IDistribution1D::generateSamples: "
49 "number of generated samples must be bigger than zero");
57 std::vector<ParameterSample>
62 "IDistribution1D::generateSamples: "
63 "number of generated samples must be bigger than zero");
74 if (nbr_samples < 2 || DoubleEqual(xmin, xmax))
76 std::vector<double> result(nbr_samples);
77 for (
size_t i = 0; i < nbr_samples; ++i)
78 result[i] = xmin + i * (xmax - xmin) / (nbr_samples - 1.0);
96 std::ostringstream ostr;
97 ostr <<
"IDistribution1D::adjustMinMaxForLimits() -> Error. Can't' adjust ";
98 ostr <<
"xmin:" << xmin <<
" xmax:" << xmax <<
" for given limits " << limits << std::endl;
105 std::vector<ParameterSample>
108 std::vector<ParameterSample> result;
109 double norm_factor = 0.0;
110 for (
double value : sample_values) {
115 if (norm_factor <= 0.0)
117 "total probability must be bigger than zero");
119 sample.weight /= norm_factor;
127 DistributionGate::DistributionGate(
const std::vector<double> P)
131 {{
"Min",
"",
"para_tooltip", -INF, +INF, 0}, {
"Max",
"",
"para_tooltip", -INF, +INF, 0}}},
133 m_min(m_P[0]), m_max(m_P[1])
139 DistributionGate::DistributionGate(
double min,
double max)
148 if (x < m_min || x > m_max)
150 if (DoubleEqual(m_min, m_max))
152 return 1.0 / (m_max - m_min);
166 return DoubleEqual(m_min, m_max);
173 DistributionLorentz::DistributionLorentz(
const std::vector<double> P)
176 {{
"Mean",
"",
"para_tooltip", -INF, +INF, 0},
177 {
"HWHM",
"",
"para_tooltip", -INF, +INF, 0}}},
179 m_mean(m_P[0]), m_hwhm(m_P[1])
185 DistributionLorentz::DistributionLorentz(
double mean,
double hwhm)
195 return DoubleEqual(x, m_mean) ? 1.0 : 0.0;
196 return m_hwhm / (m_hwhm * m_hwhm + (x - m_mean) * (x - m_mean)) / M_PI;
202 if (sigma_factor <= 0.0)
204 double xmin = m_mean - sigma_factor * m_hwhm;
205 double xmax = m_mean + sigma_factor * m_hwhm;
212 return m_hwhm == 0.0;
219 DistributionGaussian::DistributionGaussian(
const std::vector<double> P)
222 {{
"Mean",
"",
"para_tooltip", -INF, +INF, 0},
223 {
"StdDev",
"",
"para_tooltip", -INF, +INF, 0}}},
225 m_mean(m_P[0]), m_std_dev(m_P[1])
231 DistributionGaussian::DistributionGaussian(
double mean,
double std_dev)
240 if (m_std_dev == 0.0)
241 return DoubleEqual(x, m_mean) ? 1.0 : 0.0;
242 double exponential = std::exp(-(x - m_mean) * (x - m_mean) / (2.0 * m_std_dev * m_std_dev));
243 return exponential / m_std_dev / std::sqrt(M_TWOPI);
249 if (sigma_factor <= 0.0)
251 double xmin = m_mean - sigma_factor * m_std_dev;
252 double xmax = m_mean + sigma_factor * m_std_dev;
259 return m_std_dev == 0.0;
266 DistributionLogNormal::DistributionLogNormal(
const std::vector<double> P)
269 {{
"Median",
"",
"para_tooltip", -INF, +INF, 0},
270 {
"ScaleParameter",
"",
"para_tooltip", -INF, +INF, 0}}},
272 m_median(m_P[0]), m_scale_param(m_P[1])
274 if (m_scale_param < 0.0)
280 DistributionLogNormal::DistributionLogNormal(
double median,
double scale_param)
289 if (m_scale_param == 0.0)
290 return DoubleEqual(x, m_median) ? 1.0 : 0.0;
291 double t = std::log(x / m_median) / m_scale_param;
292 return std::exp(-t * t / 2.0) / (x * m_scale_param * std::sqrt(M_TWOPI));
297 double exponent = m_scale_param * m_scale_param / 2.0;
298 return m_median * std::exp(exponent);
305 if (nbr_samples < 2) {
306 std::vector<double> result;
307 result.push_back(m_median);
310 if (sigma_factor <= 0.0)
312 double xmin = m_median * std::exp(-sigma_factor * m_scale_param);
313 double xmax = m_median * std::exp(sigma_factor * m_scale_param);
320 return m_scale_param == 0.0;
333 DistributionCosine::DistributionCosine(
const std::vector<double> P)
336 {{
"Mean",
"",
"para_tooltip", -INF, +INF, 0},
337 {
"Sigma",
"",
"para_tooltip", -INF, +INF, 0}}},
339 m_mean(m_P[0]), m_sigma(m_P[1])
345 DistributionCosine::DistributionCosine(
double mean,
double sigma)
355 return DoubleEqual(x, m_mean) ? 1.0 : 0.0;
356 if (std::abs(x - m_mean) > M_PI * m_sigma)
358 return (1.0 + std::cos((x - m_mean) / m_sigma)) / (m_sigma * M_TWOPI);
364 if (sigma_factor <= 0.0 || sigma_factor > 2.0)
366 double xmin = m_mean - sigma_factor * m_sigma * M_PI_2;
367 double xmax = m_mean + sigma_factor * m_sigma * M_PI_2;
374 return m_sigma == 0.0;
381 DistributionTrapezoid::DistributionTrapezoid(
const std::vector<double> P)
384 {{
"Center",
"",
"para_tooltip", -INF, +INF, 0},
385 {
"LeftWidth",
"",
"para_tooltip", -INF, +INF, 0},
386 {
"MiddleWidth",
"",
"para_tooltip", -INF, +INF, 0},
387 {
"RightWidth",
"",
"para_tooltip", -INF, +INF, 0}}},
389 m_center(m_P[0]), m_left(m_P[1]), m_middle(m_P[2]), m_right(m_P[3])
399 DistributionTrapezoid::DistributionTrapezoid(
double center,
double left,
double middle,
407 double height = 2.0 / (m_left + 2.0 * m_middle + m_right);
408 double min = m_center - m_middle / 2.0 - m_left;
411 if (x < min + m_left)
412 return (x - min) * height / m_left;
413 if (x < min + m_left + m_middle)
415 if (x < min + m_left + m_middle + m_right) {
416 return height - (x - min - m_left - m_middle) * height / m_right;
424 double xmin = m_center - m_middle / 2.0 - m_left;
425 double xmax = xmin + m_left + m_middle + m_right;
426 adjustLimitsToNonZeroSamples(xmin, xmax, nbr_samples);
433 return (m_left + m_middle + m_right) == 0.0;
436 void DistributionTrapezoid::adjustLimitsToNonZeroSamples(
double& min,
double& max,
437 size_t nbr_samples)
const
439 if (nbr_samples <= 1)
441 size_t N = nbr_samples;
446 if (N == nbr_samples)
448 double step = (max - min) / (N - 1);
457 bool DoubleEqual(
double a,
double b)
460 * std::max(std::abs(a) * std::numeric_limits<double>::epsilon(),
461 std::numeric_limits<double>::min());
462 return std::abs(a - b) < eps;
Defines classes representing one-dimensional distributions.
Defines many exception classes in namespace Exceptionss.
Defines M_PI and some more mathematical constants.
Defines class ParameterPool.
Defines class ParameterSample.
Defines class RealParameter.
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
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
Uniform distribution function 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
Returns list of sample values.
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
Gaussian distribution with standard deviation std_dev.
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.
virtual std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const
generate list of sample values
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
double getMean() const final
Returns the distribution-specific mean.
virtual void setUnits(const std::string &units)
Sets distribution units.
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
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
double probabilityDensity(double x) const final
Returns the distribution-specific probability density for value x.
Trapezoidal distribution.
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.
virtual std::vector< double > equidistantPoints(size_t nbr_samples, double sigma_factor, const RealLimits &limits=RealLimits()) const
generate list of sample values
Interface for one-dimensional distributions.
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().
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 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().
Base class for tree-like structures containing parameterized objects.
RealParameter * parameter(const std::string &name) const
Returns parameter with given 'name'.
ParameterPool * parameterPool() const
Returns pointer to the parameter pool.
A parameter value with a weight, as obtained when sampling from a distribution.
Limits for a real fit parameter.
bool hasUpperLimit() const
if has upper limit
double upperLimit() const
Returns upper limit.
double lowerLimit() const
Returns lower limit.
bool hasLowerLimit() const
if has lower limit