Index: trunk/npstat/stat/OrthoPolyGOFTest.icc =================================================================== --- trunk/npstat/stat/OrthoPolyGOFTest.icc (revision 734) +++ trunk/npstat/stat/OrthoPolyGOFTest.icc (revision 735) @@ -1,141 +1,118 @@ #include #include #include #include #include "npstat/nm/truncatedInverseSqrt.hh" #include "npstat/nm/sumOfSquares.hh" namespace npstat { template OrthoPolyGOFTest::OrthoPolyGOFTest( const Quadrature& q, const AbsClassicalOrthoPoly1D& poly, - const unsigned i_maxdeg, - const double* importanceWeights, - const unsigned nWeights) + const unsigned i_maxdeg) : poly_(poly.clone()), - importanceWeights_(i_maxdeg+1U, 1.0), buf_((i_maxdeg+1U)*(i_maxdeg+2U)/2U - 1U), statBuf_(2U*i_maxdeg), maxdeg_(i_maxdeg) { - if (nWeights) - { - if (nWeights != i_maxdeg + 1U) throw std::invalid_argument( - "In npstat::OrthoPolyGOFTest constructor: " - "inconsistent number of importance weights"); - assert(importanceWeights); - for (unsigned i=0; i void OrthoPolyGOFTest::calculateNormalizingMatrix( const Quadrature& q, Matrix* result) const { assert(result); const unsigned maxdegP1 = maxdeg_ + 1U; const unsigned nRows = maxdegP1*(maxdegP1+1U)/2U - 1U; Matrix covmat(nRows, nRows); unsigned iRow = 0; for (unsigned i=0; i<=maxdeg_; ++i) { - const long double prod_i = importanceWeights_[i]; for (unsigned k=i ? i : 1U; k<=maxdeg_; ++k, ++iRow) { assert(iRow < nRows); const double k_del_ik = k == i ? 1.0 : 0.0; - const long double prod_k = prod_i*importanceWeights_[k]; - unsigned iCol = 0; for (unsigned j=0; j<=maxdeg_; ++j) { - const long double prod_j = prod_k*importanceWeights_[j]; for (unsigned m=j ? j : 1U; m<=maxdeg_; ++m, ++iCol) { if (iCol >= iRow) { assert(iCol < nRows); - const long double prod_m = prod_j*importanceWeights_[m]; const double k_del_jm = j == m ? 1.0 : 0.0; double cov = poly_->jointAverage(q, i, k, j, m) - k_del_ik*k_del_jm; if (i == j && k == m && cov < 0.0) cov = 0.0; - covmat[iRow][iCol] = cov*prod_m; + covmat[iRow][iCol] = cov; } } } assert(iCol == nRows); } } assert(iRow == nRows); iRow = 0; for (unsigned i=0; i<=maxdeg_; ++i) { for (unsigned k=i ? i : 1U; k<=maxdeg_; ++k, ++iRow) { unsigned iCol = 0; for (unsigned j=0; j<=maxdeg_; ++j) { for (unsigned m=j ? j : 1U; m<=maxdeg_; ++m, ++iCol) if (iCol < iRow) covmat[iRow][iCol] = covmat[iCol][iRow]; } } } truncatedInverseSqrt(covmat, 2U*maxdeg_, 0.0, result); assert(result->nRows() == 2U*maxdeg_); } template void OrthoPolyGOFTest::normalizedDeviations( const Numeric* data, const unsigned long lenData, double* deviations, const unsigned lenDeviations) const { const unsigned twomaxdeg = 2U*maxdeg_; assert(lenData); assert(data); assert(lenDeviations >= twomaxdeg); assert(deviations); const Matrix& unnorm = poly_-> sampleProductAverages( data, lenData, maxdeg_); double* buf = const_cast(&buf_[0]); unsigned iRow = 0; for (unsigned i=0; i<=maxdeg_; ++i) for (unsigned k=i ? i : 1U; k<=maxdeg_; ++k, ++iRow) - buf[iRow] = (unnorm[i][k] - (i == k ? 1.0 : 0.0))* - importanceWeights_[i]*importanceWeights_[k]; + buf[iRow] = unnorm[i][k] - (i == k ? 1.0 : 0.0); assert(iRow == buf_.size()); invsqr_.timesVector(buf, iRow, deviations, twomaxdeg); const double sqrlen = std::sqrt(static_cast(lenData)); for (unsigned i=0; i double OrthoPolyGOFTest::testStatistic( const Numeric* data, const unsigned long lenData) const { double* statbuf = const_cast(&statBuf_[0]); normalizedDeviations(data, lenData, statbuf, statBuf_.size()); return sumOfSquares(statbuf, statBuf_.size()); } } Index: trunk/npstat/stat/OrthoPolyGOFTest.hh =================================================================== --- trunk/npstat/stat/OrthoPolyGOFTest.hh (revision 734) +++ trunk/npstat/stat/OrthoPolyGOFTest.hh (revision 735) @@ -1,63 +1,63 @@ #ifndef NPSTAT_ORTHOPOLYGOFTEST_HH_ #define NPSTAT_ORTHOPOLYGOFTEST_HH_ /*! // \file OrthoPolyGOFTest.hh // // \brief Orthogonal polynomial goodness-of-fit test // // Author: I. Volobouev // // November 2020 */ #include #include #include "npstat/nm/Matrix.hh" #include "npstat/nm/AbsClassicalOrthoPoly1D.hh" namespace npstat { class OrthoPolyGOFTest { public: template OrthoPolyGOFTest(const Quadrature& q, const AbsClassicalOrthoPoly1D& poly, - unsigned maxdeg, - const double* importanceWeights=0, - unsigned nWeights=0); + unsigned maxdeg); inline unsigned maxDegree() const {return maxdeg_;} inline unsigned numDeviations() const {return 2U*maxdeg_;} - /** Get the value of the test statistic */ + /** + // Get the value of the test statistic with all + // terms weighted equally + */ template double testStatistic(const Numeric* data, unsigned long lenData) const; /** // Get individual normalized deviations from which // the test statistic is constructed */ template void normalizedDeviations( const Numeric* data, unsigned long lenData, double* deviations, unsigned lenDeviations) const; private: template void calculateNormalizingMatrix(const Quadrature& q, Matrix* m) const; std::shared_ptr poly_; Matrix invsqr_; - std::vector importanceWeights_; std::vector buf_; std::vector statBuf_; unsigned maxdeg_; }; } #include "npstat/stat/OrthoPolyGOFTest.icc" #endif // NPSTAT_ORTHOPOLYGOFTEST_HH_