diff --git a/Core/Parametrization/Distributions.cpp b/Core/Parametrization/Distributions.cpp index 79e23f53def305f0ddfafedc74c73d8b5c137a94..9f68149d70dd4b9e79b194a0f047c1b03743c74c 100644 --- a/Core/Parametrization/Distributions.cpp +++ b/Core/Parametrization/Distributions.cpp @@ -20,7 +20,10 @@ #include <cmath> #include <sstream> -using namespace BornAgain; + +// ************************************************************************** // +// class IDistribution1D +// ************************************************************************** // IDistribution1D* IDistribution1D::clone() const { @@ -28,11 +31,12 @@ IDistribution1D* IDistribution1D::clone() const } std::vector<ParameterSample> IDistribution1D::generateSamples( - size_t nbr_samples, double sigma_factor, const RealLimits &limits) const + size_t nbr_samples, double sigma_factor, const RealLimits& limits) const { if (nbr_samples == 0) - throw Exceptions::OutOfBoundsException("IDistribution1D::generateSamples: number " - "of generated samples must be bigger than zero"); + throw Exceptions::OutOfBoundsException( + "IDistribution1D::generateSamples: " + "number of generated samples must be bigger than zero"); if (isDelta()) { std::vector<ParameterSample> result = { getMeanSample() }; return result; @@ -45,29 +49,23 @@ std::vector<ParameterSample> IDistribution1D::generateSamples( size_t nbr_samples, double xmin, double xmax) const { if (nbr_samples == 0) - throw Exceptions::OutOfBoundsException("IDistribution1D::generateSamples: number " - "of generated samples must be bigger than zero"); - if (isDelta()) { - std::vector<ParameterSample> result = { getMeanSample() }; - return result; - } - std::vector<double> sample_values = generateValues(nbr_samples, xmin, xmax); - return generateSamplesFromValues(sample_values); + throw Exceptions::OutOfBoundsException( + "IDistribution1D::generateSamples: " + "number of generated samples must be bigger than zero"); + if (isDelta()) + return { getMeanSample() }; + return generateSamplesFromValues( generateValues(nbr_samples, xmin, xmax) ); } //! Interface std::vector<double> IDistribution1D::generateValues( size_t nbr_samples, double xmin, double xmax) const { - std::vector<double> result; - if (nbr_samples < 2 || xmin == xmax) { - result.push_back(getMean()); - } else { - result.resize(nbr_samples); - for (size_t i=0; i<nbr_samples; ++i) { - result[i] = xmin + i*(xmax-xmin)/(nbr_samples-1.0); - } - } + if (nbr_samples < 2 || xmin == xmax) + return { getMean() }; + std::vector<double> result(nbr_samples); + for (size_t i=0; i<nbr_samples; ++i) + result[i] = xmin + i*(xmax-xmin)/(nbr_samples-1.0); return result; } @@ -86,7 +84,7 @@ void IDistribution1D::SignalBadInitialization(std::string distribution_name) } void IDistribution1D::adjustMinMaxForLimits( - double &xmin, double &xmax, const RealLimits &limits) const + double& xmin, double& xmax, const RealLimits& limits) const { if(limits.hasLowerLimit() && xmin < limits.getLowerLimit()) xmin = limits.getLowerLimit(); if(limits.hasUpperLimit() && xmax > limits.getUpperLimit()) xmax = limits.getUpperLimit(); @@ -99,10 +97,9 @@ void IDistribution1D::adjustMinMaxForLimits( } std::vector<ParameterSample> IDistribution1D::generateSamplesFromValues( - const std::vector<double> &sample_values) const + const std::vector<double>& sample_values) const { - std::vector<ParameterSample> result; - result.resize(sample_values.size()); + std::vector<ParameterSample> result(sample_values.size()); double norm_factor = 0.0; for (size_t i=0; i<sample_values.size(); ++i) { double pdf = probabilityDensity(sample_values[i]); @@ -111,26 +108,22 @@ std::vector<ParameterSample> IDistribution1D::generateSamplesFromValues( norm_factor += pdf; } if (norm_factor <= 0.0) - throw Exceptions::RuntimeErrorException("IDistribution1D::generateSamples: " - "total probability must be bigger than zero"); - for (size_t i=0; i<sample_values.size(); ++i) { + throw Exceptions::RuntimeErrorException( + "IDistribution1D::generateSamples: " + "total probability must be bigger than zero"); + for (size_t i=0; i<sample_values.size(); ++i) result[i].weight /= norm_factor; - } return result; } -// ---------------------------------------------------------------------------------------------- // -DistributionGate::DistributionGate() : m_min(0.0), m_max(1.0) -{ - setName(DistributionGateType); - checkInitialization(); - init_parameters(); -} +// ************************************************************************** // +// class DistributionGate +// ************************************************************************** // DistributionGate::DistributionGate(double min, double max) : m_min(min), m_max(max) { - setName(DistributionGateType); + setName(BornAgain::DistributionGateType); checkInitialization(); init_parameters(); } @@ -142,18 +135,16 @@ double DistributionGate::probabilityDensity(double x) const return 1.0/(m_max-m_min); } -std::vector<double> DistributionGate::generateValueList(size_t nbr_samples, - double sigma_factor, const RealLimits &limits) const +std::vector<double> DistributionGate::generateValueList( + size_t nbr_samples, double, const RealLimits&) const { - (void)sigma_factor; - (void)limits; return generateValues(nbr_samples, m_min, m_max); } void DistributionGate::init_parameters() { - registerParameter(Minimum, &m_min); - registerParameter(Maximum, &m_max); + registerParameter(BornAgain::Minimum, &m_min); + registerParameter(BornAgain::Maximum, &m_max); } bool DistributionGate::isDelta() const @@ -163,38 +154,37 @@ bool DistributionGate::isDelta() const bool DistributionGate::checkInitialization() const { - bool result = true; - if (m_max < m_min) result = false; - if (!result) SignalBadInitialization(DistributionGateType); - return result; + if (m_max < m_min) { + SignalBadInitialization(BornAgain::DistributionGateType); + return false; + } + return true; } -// ---------------------------------------------------------------------------------------------- // -DistributionLorentz::DistributionLorentz() : m_mean(0.0), m_hwhm(1.0) -{ - setName(DistributionLorentzType); - checkInitialization(); - init_parameters(); -} +// ************************************************************************** // +// class DistributionLorentz +// ************************************************************************** // DistributionLorentz::DistributionLorentz(double mean, double hwhm) : m_mean(mean), m_hwhm(hwhm) { - setName(DistributionLorentzType); + setName(BornAgain::DistributionLorentzType); checkInitialization(); init_parameters(); } double DistributionLorentz::probabilityDensity(double x) const { - if (m_hwhm == 0.0) return x==m_mean ? 1.0 : 0.0; + if (m_hwhm == 0.0) + return x==m_mean ? 1.0 : 0.0; return m_hwhm/(m_hwhm*m_hwhm + (x-m_mean)*(x-m_mean))/M_PI; } -std::vector<double> DistributionLorentz::generateValueList(size_t nbr_samples, - double sigma_factor, const RealLimits &limits) const +std::vector<double> DistributionLorentz::generateValueList( + size_t nbr_samples, double sigma_factor, const RealLimits& limits) const { - if (sigma_factor <= 0.0) sigma_factor = 2.0; + if (sigma_factor <= 0.0) + sigma_factor = 2.0; double xmin = m_mean - sigma_factor*m_hwhm; double xmax = m_mean + sigma_factor*m_hwhm; adjustMinMaxForLimits(xmin, xmax, limits); @@ -203,8 +193,8 @@ std::vector<double> DistributionLorentz::generateValueList(size_t nbr_samples, void DistributionLorentz::init_parameters() { - registerParameter(Mean, &m_mean); - registerParameter(HWHM, &m_hwhm); + registerParameter(BornAgain::Mean, &m_mean); + registerParameter(BornAgain::HWHM, &m_hwhm); } bool DistributionLorentz::isDelta() const @@ -214,44 +204,40 @@ bool DistributionLorentz::isDelta() const bool DistributionLorentz::checkInitialization() const { - bool result = true; - if (m_hwhm < 0.0) result = false; - if (!result) SignalBadInitialization(DistributionLorentzType); - return result; + if (m_hwhm < 0.0) { + SignalBadInitialization(BornAgain::DistributionLorentzType); + return false; + } + return true; } -// ---------------------------------------------------------------------------------------------- // -DistributionGaussian::DistributionGaussian() - : m_mean(0.0) - , m_std_dev(1.0) -{ - setName(DistributionGaussianType); - checkInitialization(); - init_parameters(); -} +// ************************************************************************** // +// class DistributionGaussian +// ************************************************************************** // DistributionGaussian::DistributionGaussian(double mean, double std_dev) : m_mean(mean) , m_std_dev(std_dev) { - setName(DistributionGaussianType); + setName(BornAgain::DistributionGaussianType); checkInitialization(); init_parameters(); } double DistributionGaussian::probabilityDensity(double x) const { - if (m_std_dev == 0.0) return x==m_mean ? 1.0 : 0.0; - double exponential = std::exp(-(x-m_mean)*(x-m_mean) - /(2.0*m_std_dev*m_std_dev)); + if (m_std_dev == 0.0) + return x==m_mean ? 1.0 : 0.0; + double exponential = std::exp(-(x-m_mean)*(x-m_mean) / (2.0*m_std_dev*m_std_dev)); return exponential/m_std_dev/std::sqrt(M_TWOPI); } -std::vector<double> DistributionGaussian::generateValueList(size_t nbr_samples, - double sigma_factor, const RealLimits &limits) const +std::vector<double> DistributionGaussian::generateValueList( + size_t nbr_samples, double sigma_factor, const RealLimits& limits) const { - if (sigma_factor <= 0.0) sigma_factor = 2.0; + if (sigma_factor <= 0.0) + sigma_factor = 2.0; double xmin = m_mean - sigma_factor*m_std_dev; double xmax = m_mean + sigma_factor*m_std_dev; adjustMinMaxForLimits(xmin, xmax, limits); @@ -260,8 +246,8 @@ std::vector<double> DistributionGaussian::generateValueList(size_t nbr_samples, void DistributionGaussian::init_parameters() { - registerParameter(Mean, &m_mean); - registerParameter(StdDeviation, &m_std_dev); + registerParameter(BornAgain::Mean, &m_mean); + registerParameter(BornAgain::StdDeviation, &m_std_dev); } bool DistributionGaussian::isDelta() const @@ -271,35 +257,31 @@ bool DistributionGaussian::isDelta() const bool DistributionGaussian::checkInitialization() const { - bool result = true; - if (m_std_dev < 0.0) result = false; - if (!result) SignalBadInitialization(DistributionGaussianType); - return result; + if (m_std_dev < 0.0) { + SignalBadInitialization(BornAgain::DistributionGaussianType); + return false; + } + return true; } -// ---------------------------------------------------------------------------------------------- // -DistributionLogNormal::DistributionLogNormal(double scale_param) - : m_median(1.0) - , m_scale_param(scale_param) -{ - setName(DistributionLogNormalType); - checkInitialization(); - init_parameters(); -} +// ************************************************************************** // +// class DistributionLogNormal +// ************************************************************************** // DistributionLogNormal::DistributionLogNormal(double median, double scale_param) : m_median(median) , m_scale_param(scale_param) { - setName(DistributionLogNormalType); + setName(BornAgain::DistributionLogNormalType); checkInitialization(); init_parameters(); } double DistributionLogNormal::probabilityDensity(double x) const { - if (m_scale_param==0.0) return x==m_median ? 1.0 : 0.0; + if (m_scale_param==0.0) + return x==m_median ? 1.0 : 0.0; double t = std::log(x/m_median)/m_scale_param; return std::exp(-t*t/2.0)/(x*m_scale_param*std::sqrt(M_TWOPI)); } @@ -310,26 +292,26 @@ double DistributionLogNormal::getMean() const return m_median*std::exp(exponent); } -std::vector<double> DistributionLogNormal::generateValueList(size_t nbr_samples, - double sigma_factor, const RealLimits &limits) const +std::vector<double> DistributionLogNormal::generateValueList( + size_t nbr_samples, double sigma_factor, const RealLimits& limits) const { if(nbr_samples < 2) { std::vector<double> result; result.push_back(m_median); return result; - } else { - if (sigma_factor <= 0.0) sigma_factor = 2.0; - double xmin = m_median*std::exp(-sigma_factor*m_scale_param); - double xmax = m_median*std::exp(sigma_factor*m_scale_param); - adjustMinMaxForLimits(xmin, xmax, limits); - return generateValues(nbr_samples, xmin, xmax); } + if (sigma_factor <= 0.0) + sigma_factor = 2.0; + double xmin = m_median*std::exp(-sigma_factor*m_scale_param); + double xmax = m_median*std::exp(sigma_factor*m_scale_param); + adjustMinMaxForLimits(xmin, xmax, limits); + return generateValues(nbr_samples, xmin, xmax); } void DistributionLogNormal::init_parameters() { - registerParameter(Median, &m_median); - registerParameter(ScaleParameter, &m_scale_param); + registerParameter(BornAgain::Median, &m_median); + registerParameter(BornAgain::ScaleParameter, &m_scale_param); } bool DistributionLogNormal::isDelta() const @@ -339,44 +321,41 @@ bool DistributionLogNormal::isDelta() const bool DistributionLogNormal::checkInitialization() const { - bool result = true; - if (m_scale_param < 0.0) result = false; - if (m_median <= 0.0) result = false; - if (!result) SignalBadInitialization(DistributionLogNormalType); - return result; + if (m_scale_param < 0.0 || m_median <= 0.0) { + SignalBadInitialization(BornAgain::DistributionLogNormalType); + return false; + } + return true; } -// ---------------------------------------------------------------------------------------------- // -DistributionCosine::DistributionCosine() - : m_mean(0.0) - , m_sigma(1.0) -{ - setName(DistributionCosineType); - checkInitialization(); - init_parameters(); -} +// ************************************************************************** // +// class DistributionCosine +// ************************************************************************** // DistributionCosine::DistributionCosine(double mean, double sigma) : m_mean(mean) , m_sigma(sigma) { - setName(DistributionCosineType); + setName(BornAgain::DistributionCosineType); checkInitialization(); init_parameters(); } double DistributionCosine::probabilityDensity(double x) const { - if (m_sigma == 0.0) return x==m_mean ? 1.0 : 0.0; - if (std::abs(x-m_mean)>M_PI*m_sigma) return 0.0; + if (m_sigma == 0.0) + return x==m_mean ? 1.0 : 0.0; + if (std::abs(x-m_mean)>M_PI*m_sigma) + return 0.0; return (1.0 + std::cos((x-m_mean)/m_sigma))/(m_sigma*M_TWOPI); } -std::vector<double> DistributionCosine::generateValueList(size_t nbr_samples, - double sigma_factor, const RealLimits &limits) const +std::vector<double> DistributionCosine::generateValueList( + size_t nbr_samples, double sigma_factor, const RealLimits& limits) const { - if (sigma_factor <= 0.0 || sigma_factor > 2.0) sigma_factor = 2.0; + if (sigma_factor <= 0.0 || sigma_factor > 2.0) + sigma_factor = 2.0; double xmin = m_mean - sigma_factor*m_sigma*M_PI_2; double xmax = m_mean + sigma_factor*m_sigma*M_PI_2; adjustMinMaxForLimits(xmin, xmax, limits); @@ -385,8 +364,8 @@ std::vector<double> DistributionCosine::generateValueList(size_t nbr_samples, void DistributionCosine::init_parameters() { - registerParameter(Mean, &m_mean); - registerParameter(Sigma, &m_sigma); + registerParameter(BornAgain::Mean, &m_mean); + registerParameter(BornAgain::Sigma, &m_sigma); } bool DistributionCosine::isDelta() const @@ -396,8 +375,9 @@ bool DistributionCosine::isDelta() const bool DistributionCosine::checkInitialization() const { - bool result = true; - if (m_sigma < 0.0) result = false; - if (!result) SignalBadInitialization(DistributionCosineType); - return result; + if (m_sigma < 0.0) { + SignalBadInitialization(BornAgain::DistributionCosineType); + return false; + } + return true; } diff --git a/Core/Parametrization/Distributions.h b/Core/Parametrization/Distributions.h index a91b96af1487e77494d14a103378b9c45293b0f0..956a3b9bcf7b650e1c9ee2716423e331938cce76 100644 --- a/Core/Parametrization/Distributions.h +++ b/Core/Parametrization/Distributions.h @@ -64,7 +64,7 @@ public: //! generate a single sample containing the mean value and weight 1 ParameterSample getMeanSample() const; - //! signals that the distribution is in the limit case of a delta distribution + //! signals that the distribution is in the limit case of a Dirac delta distribution virtual bool isDelta() const=0; protected: @@ -85,7 +85,7 @@ protected: class BA_CORE_API_ DistributionGate : public IDistribution1D { public: - DistributionGate(); + DistributionGate() : DistributionGate( 0., 1. ) {} DistributionGate(double min, double max); virtual ~DistributionGate() {} @@ -93,10 +93,10 @@ public: virtual DistributionGate* clone() const { return new DistributionGate(m_min, m_max); } //! get the probability density for value x - virtual double probabilityDensity(double x) const; + double probabilityDensity(double x) const final; //! get the mean of the distribution - virtual double getMean() const { return (m_min+m_max)/2.0; } + double getMean() const final { return (m_min+m_max)/2.0; } //! Returns the minimum value of the distribution double getMin() const { return m_min; } @@ -108,8 +108,8 @@ public: virtual std::vector<double> generateValueList( size_t nbr_samples, double sigma_factor, const RealLimits& limits = RealLimits()) const; - //! signals that the distribution is in the limit case of a delta distribution - virtual bool isDelta() const; + //! signals that the distribution is in the limit case of a Dirac delta distribution + bool isDelta() const final; protected: //! Registers some class members for later access via parameter pool @@ -129,17 +129,17 @@ private: class BA_CORE_API_ DistributionLorentz : public IDistribution1D { public: - DistributionLorentz(); + DistributionLorentz() : DistributionLorentz(0., 1.) {} DistributionLorentz(double mean, double hwhm); virtual ~DistributionLorentz() {} virtual DistributionLorentz* clone() const { return new DistributionLorentz(m_mean, m_hwhm); } //! get the probability density for value x - virtual double probabilityDensity(double x) const; + double probabilityDensity(double x) const final; //! Returns the mean of the distribution - virtual double getMean() const { return m_mean; } + double getMean() const final { return m_mean; } //! Returns the half width at half maximum double getHWHM() const { return m_hwhm; } @@ -149,7 +149,7 @@ public: size_t nbr_samples, double sigma_factor, const RealLimits& limits = RealLimits()) const; //! signals that the distribution is in the limit case of a delta distribution - virtual bool isDelta() const; + bool isDelta() const final; protected: //! Registers some class members for later access via parameter pool @@ -169,7 +169,7 @@ private: class BA_CORE_API_ DistributionGaussian: public IDistribution1D { public: - DistributionGaussian(); + DistributionGaussian() : DistributionGaussian(0., 1.) {} DistributionGaussian(double mean, double std_dev); virtual ~DistributionGaussian() {} @@ -178,10 +178,10 @@ public: return new DistributionGaussian(m_mean, m_std_dev); } //! get the probability density for value x - virtual double probabilityDensity(double x) const; + double probabilityDensity(double x) const final; //! Returns the mean of the distribution - virtual double getMean() const { return m_mean; } + double getMean() const final { return m_mean; } //! Returns the standard deviation double getStdDev() const { return m_std_dev; } @@ -191,7 +191,7 @@ public: double sigma_factor, const RealLimits& limits = RealLimits()) const; //! signals that the distribution is in the limit case of a delta distribution - virtual bool isDelta() const; + bool isDelta() const final; protected: //! Registers some class members for later access via parameter pool @@ -211,7 +211,7 @@ private: class BA_CORE_API_ DistributionLogNormal: public IDistribution1D { public: - DistributionLogNormal(double scale_param); + DistributionLogNormal(double scale_param) : DistributionLogNormal(1., scale_param) {} DistributionLogNormal(double median, double scale_param); virtual ~DistributionLogNormal() {} @@ -220,10 +220,10 @@ public: return new DistributionLogNormal(m_median, m_scale_param); } //! get the probability density for value x - virtual double probabilityDensity(double x) const; + double probabilityDensity(double x) const final; //! get the mean of the distribution - virtual double getMean() const; + double getMean() const final; //! Returns the median of the distribution double getMedian() const { return m_median; } @@ -236,7 +236,7 @@ public: size_t nbr_samples, double sigma_factor, const RealLimits& limits = RealLimits()) const; //! signals that the distribution is in the limit case of a delta distribution - virtual bool isDelta() const; + bool isDelta() const final; protected: //! Registers some class members for later access via parameter pool @@ -256,7 +256,7 @@ private: class BA_CORE_API_ DistributionCosine: public IDistribution1D { public: - DistributionCosine(); + DistributionCosine() : DistributionCosine(0., 1.) {} DistributionCosine(double mean, double sigma); virtual ~DistributionCosine() {} @@ -264,10 +264,10 @@ public: virtual DistributionCosine* clone() const { return new DistributionCosine(m_mean, m_sigma); } //! get the probability density for value x - virtual double probabilityDensity(double x) const; + double probabilityDensity(double x) const final; //! Returns the mean of the distribution - virtual double getMean() const { return m_mean; } + double getMean() const final { return m_mean; } //! Returns the sigma parameter of the distribution double getSigma() const { return m_sigma; } @@ -277,7 +277,7 @@ public: size_t nbr_samples, double sigma_factor, const RealLimits& limits = RealLimits()) const; //! signals that the distribution is in the limit case of a delta distribution - virtual bool isDelta() const; + bool isDelta() const final; protected: //! Registers some class members for later access via parameter pool diff --git a/Core/Parametrization/ParameterSample.h b/Core/Parametrization/ParameterSample.h index 5357fba3b6633e40717d948bcddee3aff6a40485..35c9d4f1a9cb1f3e204a6f35613ce10041c5e083 100644 --- a/Core/Parametrization/ParameterSample.h +++ b/Core/Parametrization/ParameterSample.h @@ -16,9 +16,9 @@ #ifndef PARAMETERSAMPLE_H #define PARAMETERSAMPLE_H -//! @class ParameterSample +//! A parameter value with a weight, as obtained when sampling from a distribution. //! @ingroup algorithms_internal -//! @brief Represents a sampled parameter value with its weight + class ParameterSample { public: