Index: trunk/npstat/stat/DensityOrthoPoly1D.cc =================================================================== --- trunk/npstat/stat/DensityOrthoPoly1D.cc (revision 699) +++ trunk/npstat/stat/DensityOrthoPoly1D.cc (revision 700) @@ -1,172 +1,175 @@ #include #include "npstat/nm/FejerQuadrature.hh" #include "npstat/stat/DensityOrthoPoly1D.hh" namespace npstat { DensityOrthoPoly1D::DensityOrthoPoly1D(const AbsDistribution1D& distro, const unsigned maxDegree, const unsigned nIntegPoints, const OrthoPolyMethod m) : distro_(distro.clone()), wsum_(0.0L), maxdeg_(maxDegree) { if (!nIntegPoints) throw std::invalid_argument( "In npstat::DensityOrthoPoly1D constructor: the number of " "integration points must be positive"); const FejerQuadrature quad(nIntegPoints); const DensityFunctor1D weight(distro); const std::vector& measure = quad.weightedIntegrationPoints( weight, distro_->quantile(0.0), distro_->quantile(1.0)); assert(measure.size() == nIntegPoints); for (unsigned i=0; i& measure, const OrthoPolyMethod m) { rCoeffs_.clear(); rCoeffs_.reserve(maxdeg_ + 1); switch (m) { case OPOLY_STIELTJES: calcRecurrenceStieltjes(measure); break; case OPOLY_LANCZOS: calcRecurrenceLanczos(measure); break; default: throw std::runtime_error( "In npstat::DensityOrthoPoly1D::calcRecurrenceCoeffs: " "incomplete switch statement. This is a bug. Please report."); } assert(rCoeffs_.size() == maxdeg_ + 1); } void DensityOrthoPoly1D::calcRecurrenceStieltjes(const std::vector& measure) { long double prevSprod = 1.0L; for (unsigned deg=0; deg<=maxdeg_; ++deg) { const std::pair ip = monicInnerProducts(measure, deg); rCoeffs_.push_back(Recurrence(ip.first/ip.second, ip.second/prevSprod)); prevSprod = ip.second; } } void DensityOrthoPoly1D::calcRecurrenceLanczos(const std::vector& measure) { typedef long double Real; const unsigned mSize = measure.size(); std::vector dmem(mSize*2U); Real* p0 = &dmem[0]; for (unsigned i=0; i DensityOrthoPoly1D::monicInnerProducts(const std::vector& measure, const unsigned degree) const { long double sum = 0.0L, xsum = 0.0L; const unsigned mSize = measure.size(); for (unsigned i = 0; i < mSize; ++i) { const long double x = measure[i].first; const long double p = monicpoly(degree, x); const long double pprod = p*p*measure[i].second; sum += pprod; xsum += x*pprod; } return std::pair(xsum/wsum_, sum/wsum_); } long double DensityOrthoPoly1D::monicpoly(const unsigned degree, const long double x) const { long double polyk = 1.0L, polykm1 = 0.0L; for (unsigned k=0; k DensityOrthoPoly1D::recurrenceCoeffs(const unsigned deg) const { const Recurrence& r = rCoeffs_.at(deg); return std::pair(r.alpha, r.sqrbeta); } DensityOrthoPoly1D::DensityOrthoPoly1D(const DensityOrthoPoly1D& r) : distro_(r.distro_->clone()), rCoeffs_(r.rCoeffs_), wsum_(r.wsum_), maxdeg_(r.maxdeg_) { } DensityOrthoPoly1D& DensityOrthoPoly1D::operator=(const DensityOrthoPoly1D& r) { if (&r != this) { distro_ = CPP11_auto_ptr(r.distro_->clone()); rCoeffs_ = r.rCoeffs_; wsum_ = r.wsum_; maxdeg_ = r.maxdeg_; } return *this; } }