Index: trunk/npstat/stat/UnbinnedGOFTests1D.hh =================================================================== --- trunk/npstat/stat/UnbinnedGOFTests1D.hh (revision 740) +++ trunk/npstat/stat/UnbinnedGOFTests1D.hh (revision 741) @@ -1,64 +1,87 @@ #ifndef NPSTAT_UNBINNEDGOFTESTS1D_HH_ #define NPSTAT_UNBINNEDGOFTESTS1D_HH_ #include "npstat/stat/AbsUnbinnedGOFTest1D.hh" namespace npstat { /** Kolmogorov-Smirnov test */ class KSTest1D : public AbsUnbinnedGOFTest1D { public: inline explicit KSTest1D(const AbsDistribution1D& d) : AbsUnbinnedGOFTest1D(d) {} inline virtual ~KSTest1D() {} inline virtual double testStatistic( const double* data, const unsigned long sz, const bool b) const {return testStat(data, sz, b);} inline virtual double testStatistic( const float* data, const unsigned long sz, const bool b) const {return testStat(data, sz, b);} inline virtual bool hasAnalyticPValue() const {return true;} virtual double analyticPValue(double stat, unsigned long sz) const; private: template double testStat(const Numeric* data, unsigned long lenData, bool dataIsSorted) const; }; /** Anderson-Darling test */ class ADTest1D : public AbsUnbinnedGOFTest1D { public: inline explicit ADTest1D(const AbsDistribution1D& d) : AbsUnbinnedGOFTest1D(d) {} inline virtual ~ADTest1D() {} inline virtual double testStatistic( const double* data, const unsigned long sz, const bool b) const {return testStat(data, sz, b);} inline virtual double testStatistic( const float* data, const unsigned long sz, const bool b) const {return testStat(data, sz, b);} inline virtual bool hasAnalyticPValue() const {return true;} virtual double analyticPValue(double stat, unsigned long sz) const; private: template double testStat(const Numeric* data, unsigned long lenData, bool dataIsSorted) const; }; + + /** Cramer-von Mises test */ + class CvMTest1D : public AbsUnbinnedGOFTest1D + { + public: + inline explicit CvMTest1D(const AbsDistribution1D& d) + : AbsUnbinnedGOFTest1D(d) {} + + inline virtual ~CvMTest1D() {} + + inline virtual double testStatistic( + const double* data, const unsigned long sz, const bool b) const + {return testStat(data, sz, b);} + + inline virtual double testStatistic( + const float* data, const unsigned long sz, const bool b) const + {return testStat(data, sz, b);} + + private: + template + double testStat(const Numeric* data, unsigned long lenData, + bool dataIsSorted) const; + }; } #include "npstat/stat/UnbinnedGOFTests1D.icc" #endif // NPSTAT_UNBINNEDGOFTESTS1D_HH_ Index: trunk/npstat/stat/UnbinnedGOFTests1D.icc =================================================================== --- trunk/npstat/stat/UnbinnedGOFTests1D.icc (revision 740) +++ trunk/npstat/stat/UnbinnedGOFTests1D.icc (revision 741) @@ -1,62 +1,82 @@ #include #include #include #include #include #include #include #define npstat_UnbinnedGOFTests1D_get_data_sorted /**/ \ assert(data); \ const Numeric* sorted = data; \ std::unique_ptr > sortedPtr; \ if (!dataIsSorted) \ { \ sortedPtr = std::unique_ptr >( \ new std::vector(data, data + lenData)); \ std::sort(sortedPtr->begin(), sortedPtr->end()); \ sorted = &(*sortedPtr)[0]; \ } namespace npstat { template double KSTest1D::testStat(const Numeric* data, const unsigned long lenData, const bool dataIsSorted) const { if (!lenData) throw std::invalid_argument( "In npstat::KSTest1D::testStat: no data provided"); npstat_UnbinnedGOFTests1D_get_data_sorted; double maxDist = -1.0; const double n = static_cast(lenData); for (unsigned long i = 0; icdf(sorted[i]); maxDist = std::max(maxDist, std::abs(i/n - cdf)); maxDist = std::max(maxDist, std::abs((i + 1UL)/n - cdf)); } return maxDist; } template double ADTest1D::testStat(const Numeric* data, const unsigned long lenData, const bool dataIsSorted) const { if (!lenData) throw std::invalid_argument( "In npstat::ADTest1D::testStat: no data provided"); npstat_UnbinnedGOFTests1D_get_data_sorted; long double sum = 0.0L; for (unsigned long i = 0; icdf(sorted[i]); const long double cdf2 = distro_->cdf(sorted[lenData - 1UL - i]); if (cdf1 == 0.0L || cdf1 == 1.0L || cdf2 == 0.0L || cdf2 == 1.0L) return DBL_MAX; - sum += (2UL*i + 1)*logl(cdf1*(1.0L - cdf2)); + sum += (2UL*i + 1UL)*logl(cdf1*(1.0L - cdf2)); } - return -sum/lenData - static_cast(lenData); + const long double len = static_cast(lenData); + return -sum/len - len; + } + + template + double CvMTest1D::testStat(const Numeric* data, const unsigned long lenData, + const bool dataIsSorted) const + { + if (!lenData) throw std::invalid_argument( + "In npstat::CvMTest1D::testStat: no data provided"); + + npstat_UnbinnedGOFTests1D_get_data_sorted; + + const long double twon = 2.0L*static_cast(lenData); + long double sum = 0.0L; + for (unsigned long i = 0; icdf(sorted[i]); + sum += del*del; + } + return 1.0L/6.0L/twon + sum; } }