Skip to content
Snippets Groups Projects
DistributionsTest.h 15.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • #ifndef DISTRIBUTIONSTEST_H
    #define DISTRIBUTIONSTEST_H
    
    
    #include "Units.h"
    
    #include "Distributions.h"
    
    
    class DistributionsTest : public ::testing::Test
    {
    protected:
    
    // -------------------------------------------------------------------------- //
    
    
    TEST_F(DistributionsTest, DistributionGateDefaultConstructor)
    {
    
        std::unique_ptr<DistributionGate> P_distr_gate { new DistributionGate() };
        EXPECT_EQ(0.5, P_distr_gate->getMean());
        EXPECT_EQ(0.0, P_distr_gate->getMin());
        EXPECT_EQ(1.0, P_distr_gate->getMax());
        EXPECT_EQ(1.0, P_distr_gate->probabilityDensity(1.0));
        EXPECT_EQ(0, P_distr_gate->probabilityDensity(3.0));
        EXPECT_EQ(BornAgain::DistributionGateType, P_distr_gate->getName());
    
        std::vector<double> list1 = P_distr_gate->generateValueList(1, 0.0);
    
        EXPECT_EQ(list1.size(), size_t(1));
    
        std::vector<double> list2 = P_distr_gate->generateValueList(2, 0.0);
    
        EXPECT_EQ(list2.size(), size_t(2));
    
        EXPECT_EQ(0, list2[0]);
        EXPECT_EQ(1, list2[1]);
    }
    
    TEST_F(DistributionsTest, DistributionGateConstructor)
    {
    
        // Throw error when m_min > m_max:
        EXPECT_THROW(DistributionGate(1.1, 1.0), ClassInitializationException);
    
        // When m_min == m_max, only one sample is generated (the mean):
        DistributionGate distr1(1.0, 1.0);
        std::vector<double> list1 = distr1.generateValueList(5, 0.0);
        EXPECT_EQ(size_t(1), list1.size());
        EXPECT_EQ(1.0, list1[0]);
    
        // Test distribution with m_min < m_max:
        DistributionGate distr2(1.0, 2.0);
        EXPECT_EQ(1.5, distr2.getMean());
        EXPECT_EQ(1.0, distr2.getMin());
        EXPECT_EQ(2.0, distr2.getMax());
        EXPECT_EQ(1.0, distr2.probabilityDensity(1));
        EXPECT_EQ(0, distr2.probabilityDensity(3));
    
        EXPECT_EQ(BornAgain::DistributionGateType, distr2.getName());
    
    
        std::vector<double> list2 = distr2.generateValueList(1, 0.0);
        EXPECT_EQ(list2.size(), size_t(1));
        EXPECT_EQ(distr2.getMean(), list2[0]);
    
        list2 = distr2.generateValueList(2, 0.0);
        EXPECT_EQ(list2.size(), size_t(2));
        EXPECT_EQ(1.0, list2[0]);
        EXPECT_EQ(2.0, list2[1]);
    
        std::vector<ParameterSample> samples = distr2.generateSamples(3);
    
        EXPECT_EQ(samples.size(), size_t(3));
        EXPECT_EQ(samples[0].value, 1.0);
        EXPECT_EQ(samples[0].weight, 1./3.);
        EXPECT_EQ(samples[1].value, 1.5);
        EXPECT_EQ(samples[1].weight, 1./3.);
        EXPECT_EQ(samples[2].value, 2.0);
        EXPECT_EQ(samples[2].weight, 1./3.);
    
    TEST_F(DistributionsTest, DistributionGateParameters)
    {
        DistributionGate gate(2.0, 3.0);
    
        /* TEMPORARILY DISABLED getParameterPool() 
    
        EXPECT_EQ(gate.getMin(), gate.getParameterPool()->getParameter(BornAgain::Minimum).getValue());
        EXPECT_EQ(gate.getMax(), gate.getParameterPool()->getParameter(BornAgain::Maximum).getValue());
    
    }
    
    TEST_F(DistributionsTest, DistributionGateClone)
    {
        DistributionGate gate(2.0, 3.0);
        DistributionGate *clone = gate.clone();
        EXPECT_EQ(gate.getName(), clone->getName());
        EXPECT_EQ(gate.getMean(), clone->getMean());
        EXPECT_EQ(gate.getMin(), clone->getMin());
        EXPECT_EQ(gate.getMax(), clone->getMax());
        delete clone;
    }
    
    // -------------------------------------------------------------------------- //
    
    
    TEST_F(DistributionsTest, DistributionLorentzDefaultConstructor)
    
        std::unique_ptr<DistributionLorentz> P_distr_lorentz { new DistributionLorentz() };
        EXPECT_EQ(0.0, P_distr_lorentz->getMean());
        EXPECT_EQ(1.0, P_distr_lorentz->getHWHM());
        EXPECT_EQ(BornAgain::DistributionLorentzType, P_distr_lorentz->getName());
        EXPECT_EQ(1/(2*Units::PI), P_distr_lorentz->probabilityDensity(1.0));
    
        std::vector<double> list1 = P_distr_lorentz->generateValueList(1, 0.0);
        EXPECT_EQ(P_distr_lorentz->getMean(), list1[0]);
    
        std::vector<double> list2 = P_distr_lorentz->generateValueList(2, 0.0);
    
        EXPECT_EQ(-2, list2[0]);
        EXPECT_EQ(2, list2[1]);
    }
    
    
    TEST_F(DistributionsTest, DistributionLorentzConstructor)
    
        // When HWHM == 0.0, only one sample is generated (the mean):
        DistributionLorentz distr1(1.0, 0.0);
        std::vector<double> list1 = distr1.generateValueList(5, 0.0);
        EXPECT_EQ(size_t(1), list1.size());
        EXPECT_EQ(1.0, list1[0]);
    
        // Test distribution with HWHM > 0.0:
        DistributionLorentz distr2(1.0, 1.0);
        EXPECT_EQ(1.0, distr2.getMean());
        EXPECT_EQ(1.0, distr2.getHWHM());
    
        EXPECT_EQ(BornAgain::DistributionLorentzType, distr2.getName());
    
        EXPECT_EQ(1.0/Units::PI, distr2.probabilityDensity(1.0));
    
    
        std::vector<double> list2 = distr2.generateValueList(1, 0.0);
        EXPECT_EQ(distr2.getMean(), list2[0]);
    
        std::vector<double> list3 = distr2.generateValueList(2, 0.0);
        EXPECT_EQ(-1, list3[0]);
        EXPECT_EQ(3, list3[1]);
    
    TEST_F(DistributionsTest, DistributionLorentzParameters)
    {
        DistributionLorentz lorentz(2.0, 3.0);
    
        /* TEMPORARILY DISABLED getParameterPool() 
    
        EXPECT_EQ(lorentz.getMean(),
                  lorentz.getParameterPool()->getParameter(BornAgain::Mean).getValue());
        EXPECT_EQ(lorentz.getHWHM(),
                  lorentz.getParameterPool()->getParameter(BornAgain::HWHM).getValue());
    
    TEST_F(DistributionsTest, DistributionLorentzClone)
    {
    
        std::unique_ptr<DistributionLorentz> P_distr_lorentz { new DistributionLorentz(1.0, 2.0) };
        std::unique_ptr<DistributionLorentz> P_clone { P_distr_lorentz->clone() };
        EXPECT_EQ(1.0, P_clone->getMean());
        EXPECT_EQ(2.0, P_clone->getHWHM());
        EXPECT_EQ(BornAgain::DistributionLorentzType, P_clone->getName());
    
    TEST_F(DistributionsTest, DistributionLorentzSamples)
    {
        DistributionLorentz distr(1.0, 0.1);
    
        const int nbr_samples(3);
    
        // with sigma factor
        const double sigma_factor(2.0);
        std::vector<ParameterSample> samples = distr.generateSamples(nbr_samples, sigma_factor);
    
        EXPECT_EQ(samples.size(), size_t(nbr_samples));
        EXPECT_EQ(samples[0].value, 1.0 - sigma_factor*0.1);
        EXPECT_EQ(samples[1].value, 1.0);
        EXPECT_EQ(samples[2].value, 1.0 + sigma_factor*0.1);
        double d1 = distr.probabilityDensity(samples[0].value);
        double d2 = distr.probabilityDensity(samples[1].value);
        double d3 = distr.probabilityDensity(samples[2].value);
        EXPECT_EQ(samples[0].weight, d1/(d1+d2+d3));
        EXPECT_EQ(samples[1].weight, d2/(d1+d2+d3));
        EXPECT_EQ(samples[2].weight, d3/(d1+d2+d3));
    
        // with AttLimits
        samples = distr.generateSamples(nbr_samples, sigma_factor, AttLimits::lowerLimited(0.99));
        EXPECT_EQ(samples[0].value, 0.99);
        EXPECT_EQ(samples[1].value, samples[0].value + (samples[2].value - samples[0].value)/2.0);
        EXPECT_EQ(samples[2].value, 1.0 + sigma_factor*0.1);
    
        // with xmin, xmax
        samples = distr.generateSamples(nbr_samples, 0.8, 1.2);
        EXPECT_EQ(samples[0].value, 0.8);
        EXPECT_EQ(samples[1].value, 1.0);
        EXPECT_EQ(samples[2].value, 1.2);
    }
    
    
    // -------------------------------------------------------------------------- //
    
    
    TEST_F(DistributionsTest, DistributionGaussianDefaultConstructor)
    {
    
        std::unique_ptr<DistributionGaussian> P_distr_gauss { new DistributionGaussian() };
        EXPECT_EQ(0.0, P_distr_gauss->getMean());
        EXPECT_EQ(1.0, P_distr_gauss->getStdDev());
        EXPECT_EQ(std::exp(-1.0/2.0)/std::sqrt(2.0*Units::PI), P_distr_gauss->probabilityDensity(1.0));
        EXPECT_EQ(BornAgain::DistributionGaussianType, P_distr_gauss->getName());
    
        std::vector<double> list1 = P_distr_gauss->generateValueList(1, 0.0);
        EXPECT_EQ(P_distr_gauss->getMean(), list1[0]);
    
        std::vector<double> list2 = P_distr_gauss->generateValueList(2, 0.0);
    
        EXPECT_EQ(-2, list2[0]);
        EXPECT_EQ(2, list2[1]);
    }
    
    TEST_F(DistributionsTest, DistributionGaussianConstructor)
    {
    
        // When std_dev == 0.0, only one sample is generated (the mean):
        DistributionGaussian distr1(1.0, 0.0);
        std::vector<double> list1 = distr1.generateValueList(5, 0.0);
        EXPECT_EQ(size_t(1), list1.size());
        EXPECT_EQ(1.0, list1[0]);
    
        // Test distribution with std_dev > 0.0:
        DistributionGaussian distr2(1.0, 1.0);
        EXPECT_EQ(1.0, distr2.getMean());
        EXPECT_EQ(1.0, distr2.getStdDev());
    
        EXPECT_EQ(1/std::sqrt(2.0*Units::PI), distr2.probabilityDensity(1.0));
    
        EXPECT_EQ(BornAgain::DistributionGaussianType, distr2.getName());
    
    
        std::vector<double> list2 = distr2.generateValueList(1, 0.0);
        EXPECT_EQ(distr2.getMean(), list2[0]);
    
        std::vector<double> list3 = distr2.generateValueList(2, 0.0);
        EXPECT_EQ(-1, list3[0]);
        EXPECT_EQ(3, list3[1]);
    
    TEST_F(DistributionsTest, DistributionGaussianParameters)
    {
        DistributionGaussian gaussian(2.0, 3.0);
    
        /* TEMPORARILY DISABLED getParameterPool() 
    
        EXPECT_EQ(gaussian.getMean(),
                  gaussian.getParameterPool()->getParameter(BornAgain::Mean).getValue());
        EXPECT_EQ(gaussian.getStdDev(),
                  gaussian.getParameterPool()->getParameter(BornAgain::StdDeviation).getValue());
    
    TEST_F(DistributionsTest, DistributionGaussianClone)
    {
    
        std::unique_ptr<DistributionGaussian> P_distr_gauss { new DistributionGaussian(1.0, 1.0) };
        std::unique_ptr<DistributionGaussian> P_clone { P_distr_gauss->clone() };
        EXPECT_EQ(1.0, P_clone->getMean());
        EXPECT_EQ(1.0, P_clone->getStdDev());
        EXPECT_EQ(1/std::sqrt(2.0*Units::PI), P_clone->probabilityDensity(1.0));
        EXPECT_EQ(BornAgain::DistributionGaussianType, P_clone->getName());
    
        std::vector<double> list1 = P_clone->generateValueList(1, 0.0);
        EXPECT_EQ(P_distr_gauss->getMean(), list1[0]);
    
        std::vector<double> list2 = P_clone->generateValueList(2, 0.0);
    
        EXPECT_EQ(-1, list2[0]);
        EXPECT_EQ(3, list2[1]);
    }
    
    
    // -------------------------------------------------------------------------- //
    
    
    TEST_F(DistributionsTest, DistributionLogNormalConstructorWithOneParameter)
    {
    
        // When scale_par == 0.0, only one sample is generated (the mean):
        DistributionLogNormal distr1(1.0, 0.0);
        std::vector<double> list1 = distr1.generateValueList(5, 0.0);
        EXPECT_EQ(size_t(1), list1.size());
        EXPECT_EQ(1.0, list1[0]);
    
        // Test distribution with scale_par > 0.0:
        DistributionLogNormal distr2(1.0);
        EXPECT_EQ(1.0, distr2.getMedian());
        EXPECT_EQ(1.0, distr2.getScalePar());
        EXPECT_EQ(std::exp(0.5), distr2.getMean());
    
        EXPECT_EQ(1.0/std::sqrt(2.0*Units::PI), distr2.probabilityDensity(1.0));
    
        EXPECT_EQ(BornAgain::DistributionLogNormalType, distr2.getName());
    
    
        std::vector<double> list2 = distr2.generateValueList(1, 0.0);
        EXPECT_EQ(distr2.getMedian(), list2[0]);
    
        std::vector<double> list3 = distr2.generateValueList(2, 0.0);
        EXPECT_EQ(std::exp(-2), list3[0]);
        EXPECT_EQ(std::exp(-2) + std::exp(2) - std::exp(-2), list3[1]);
    
    }
    
    TEST_F(DistributionsTest, DistributionLogNormalConstructorWithTwoParameter)
    {
    
        std::unique_ptr<DistributionLogNormal> P_distr_lognormal { new DistributionLogNormal(1.0,1.0) };
        EXPECT_EQ(1.0, P_distr_lognormal->getMedian());
        EXPECT_EQ(1.0, P_distr_lognormal->getScalePar());
        EXPECT_EQ(std::exp(0.5), P_distr_lognormal->getMean());
        EXPECT_EQ(1.0/std::sqrt(2.0*Units::PI), P_distr_lognormal->probabilityDensity(1.0));
        EXPECT_EQ(BornAgain::DistributionLogNormalType, P_distr_lognormal->getName());
    
        std::vector<double> list1 = P_distr_lognormal->generateValueList(1, 0.0);
        EXPECT_EQ(P_distr_lognormal->getMedian(), list1[0]);
    
        std::vector<double> list2 = P_distr_lognormal->generateValueList(2, 0.0);
    
        EXPECT_EQ(std::exp(-2), list2[0]);
        EXPECT_EQ(std::exp(-2) + std::exp(2) - std::exp(-2), list2[1]);
    }
    
    
    TEST_F(DistributionsTest, DistributionLogNormalParameters)
    {
        DistributionLogNormal logNormal(2.0, 3.0);
    
        /* TEMPORARILY DISABLED getParameterPool() 
    
        EXPECT_EQ(logNormal.getMedian(),
                  logNormal.getParameterPool()->getParameter(BornAgain::Median).getValue());
        EXPECT_EQ(logNormal.getScalePar(),
                  logNormal.getParameterPool()->getParameter(BornAgain::ScaleParameter).getValue());
    
    TEST_F(DistributionsTest, DistributionLogNormalClone)
    {
    
        std::unique_ptr<DistributionLogNormal> P_distr_lognormal { new DistributionLogNormal(1.0, 1.0) };
        std::unique_ptr<DistributionLogNormal> P_clone { P_distr_lognormal->clone() };
        EXPECT_EQ(1.0, P_distr_lognormal->getMedian());
        EXPECT_EQ(1.0, P_distr_lognormal->getScalePar());
        EXPECT_EQ(std::exp(0.5), P_distr_lognormal->getMean());
        EXPECT_EQ(1/std::sqrt(2.0*Units::PI), P_distr_lognormal->probabilityDensity(1.0));
        EXPECT_EQ(BornAgain::DistributionLogNormalType, P_distr_lognormal->getName());
    
        std::vector<double> list1 = P_distr_lognormal->generateValueList(1, 0.0);
        EXPECT_EQ(P_distr_lognormal->getMedian(), list1[0]);
    
        std::vector<double> list2 = P_distr_lognormal->generateValueList(2,0.0);
    
        EXPECT_EQ(std::exp(-2), list2[0]);
        EXPECT_EQ(std::exp(-2) + std::exp(2) - std::exp(-2), list2[1]);
    }
    
    
    // -------------------------------------------------------------------------- //
    
    
    TEST_F(DistributionsTest, DistributionCosineDefaultConstructor)
    {
    
        std::unique_ptr<DistributionCosine> P_distr_cosine { new DistributionCosine() };
        EXPECT_EQ(0.0, P_distr_cosine->getMean());
        EXPECT_EQ(1.0, P_distr_cosine->getSigma());
        EXPECT_DOUBLE_EQ((1.0+std::cos(1.0))/(2.0*Units::PI), P_distr_cosine->probabilityDensity(1.0));
        EXPECT_EQ(0, P_distr_cosine->probabilityDensity(100.0));
        EXPECT_EQ(BornAgain::DistributionCosineType, P_distr_cosine->getName());
    
        std::vector<double> list1 = P_distr_cosine->generateValueList(1, 0.0);
        EXPECT_EQ(P_distr_cosine->getMean(), list1[0]);
    
        std::vector<double> list2 = P_distr_cosine->generateValueList(2, 0.0);
    
        EXPECT_EQ(-Units::PI, list2[0]);
        EXPECT_EQ(Units::PI, list2[1]);
    
    }
    
    TEST_F(DistributionsTest, DistributionCosineConstructor)
    {
    
        // When sigma == 0.0, only one sample is generated (the mean):
        DistributionCosine distr1(1.0, 0.0);
        std::vector<double> list1 = distr1.generateValueList(5, 0.0);
        EXPECT_EQ(size_t(1), list1.size());
        EXPECT_EQ(1.0, list1[0]);
    
        // Test distribution with sigma > 0.0:
        DistributionCosine distr2(1.0,1.0);
        EXPECT_EQ(1.0, distr2.getMean());
        EXPECT_EQ(1.0, distr2.getSigma());
    
        EXPECT_EQ(2.0/(2.0*Units::PI), distr2.probabilityDensity(1.0));
    
        EXPECT_EQ(0, distr2.probabilityDensity(100.0));
    
        EXPECT_EQ(BornAgain::DistributionCosineType, distr2.getName());
    
    
        std::vector<double> list2 = distr2.generateValueList(1, 0.0);
        EXPECT_EQ(distr2.getMean(), list2[0]);
    
        std::vector<double> list3 = distr2.generateValueList(2, 0.0);
    
        EXPECT_EQ(1-Units::PI, list3[0]);
        EXPECT_EQ(1+Units::PI, list3[1]);
    
    TEST_F(DistributionsTest, DistributionCosineParameters)
    {
        DistributionCosine cosine(2.0, 3.0);
    
        /* TEMPORARILY DISABLED getParameterPool() 
    
        EXPECT_EQ(cosine.getMean(), cosine.getParameterPool()->getParameter(BornAgain::Mean).getValue());
        EXPECT_EQ(cosine.getSigma(), cosine.getParameterPool()->getParameter(BornAgain::Sigma).getValue());
    
    TEST_F(DistributionsTest, DistributionCosineClone)
    {
    
        std::unique_ptr<DistributionCosine> P_distr_cosine { new DistributionCosine(1.0,1.0) };
        std::unique_ptr<DistributionCosine> P_clone { P_distr_cosine->clone() };
        EXPECT_EQ(1.0, P_clone->getMean());
        EXPECT_EQ(1.0, P_clone->getSigma());
        EXPECT_EQ(2.0/(2.0*Units::PI), P_clone->probabilityDensity(1.0));
        EXPECT_EQ(0, P_distr_cosine->probabilityDensity(100.0));
        EXPECT_EQ(BornAgain::DistributionCosineType, P_clone->getName());
    
        std::vector<double> list1 = P_clone->generateValueList(1, 0.0);
        EXPECT_EQ(P_clone->getMean(), list1[0]);
    
        std::vector<double> list2 = P_clone->generateValueList(2, 0.0);
    
        EXPECT_EQ(1-Units::PI, list2[0]);
        EXPECT_EQ(1+Units::PI, list2[1]);