Index: trunk/tests/test_GaussHermiteQuadrature.cc =================================================================== --- trunk/tests/test_GaussHermiteQuadrature.cc (revision 588) +++ trunk/tests/test_GaussHermiteQuadrature.cc (revision 589) @@ -1,121 +1,136 @@ #include #include #include "UnitTest++.h" #include "test_utils.hh" #include "npstat/nm/GaussHermiteQuadrature.hh" #include "npstat/nm/SemiInfGaussianQuadrature.hh" using namespace npstat; using namespace std; namespace { struct Xsquared : public Functor1 { long double operator()(const long double& x) const {return x*x;} }; struct X11 : public Functor1 { long double operator()(const long double& x) const {return powl(x, 11);} }; struct X41 : public Functor1 { long double operator()(const long double& x) const {return powl(x, 41);} }; struct Expl : public Functor1 { inline explicit Expl(long double k) : k_(k) {} long double operator()(const long double& x) const {return expl(k_*x);} private: Expl(); long double k_; }; TEST(GaussHermiteQuadrature) { const unsigned nsup[] = {16, 32, 64, 100, 128, 256}; for (unsigned icycle=0; icycle(1.0L)); CHECK_CLOSE(sqrt(M_PI/2.0), v, 1.e-15); - v = quad.integrate(ConstValue1(1.0L)); + v = quad.integrateProb(sigma, ConstValue1(1.0L)); + CHECK_CLOSE(1.0, v, 1.e-15); + + v = quad.integrate(Xsquared()); CHECK_CLOSE(sqrt(M_PI/2.0), v, 1.e-15); + + v = quad.integrateProb(sigma, Xsquared()); + CHECK_CLOSE(49.0, v, 1.e-14); if (nsup[icycle] > 5) { v = quad.integrate(X11()); CHECK_CLOSE(3840.0, v, 3840.0*1.e-15); + + const double expected = 6.058285362824890442e12; + v = quad.integrateProb(sigma, X11()); + CHECK_CLOSE(expected, v, expected*1.e-15); } if (nsup[icycle] > 20) { - const double expected = 2.55108265612582846464e24; + double expected = 2.55108265612582846464e24; v = quad.integrate(X41()); CHECK_CLOSE(expected, v, expected*1.e-15); + + expected = 9.071607099602855847e58; + v = quad.integrateProb(sigma, X41()); + CHECK_CLOSE(expected, v, expected*1.e-15); } } bool thrown = false; try { SemiInfGaussianQuadrature quad(1234567U); } catch (std::invalid_argument& e) { thrown = true; } CHECK(thrown); } } Index: trunk/npstat/nm/SemiInfGaussianQuadrature.icc =================================================================== --- trunk/npstat/nm/SemiInfGaussianQuadrature.icc (revision 588) +++ trunk/npstat/nm/SemiInfGaussianQuadrature.icc (revision 589) @@ -1,28 +1,54 @@ #include #include #include namespace npstat { template inline long double SemiInfGaussianQuadrature::integrate( const Functor1& function) const { if (buf_.size() != npoints_) buf_.resize(npoints_); std::pair* results = &buf_[0]; FcnArg a; long double v; for (unsigned i=0; i(a_[i]); v = w_[i]*static_cast(function(a)); results[i].first = std::abs(v); results[i].second = v; } std::sort(buf_.begin(), buf_.end()); v = 0.0L; for (unsigned i=0; i + long double SemiInfGaussianQuadrature::integrateProb( + const long double sigma, + const Functor1& function) const + { + if (sigma <= 0.L) throw std::invalid_argument( + "In npstat::SemiInfGaussianQuadrature::integrateProb: " + "sigma must be positive"); + if (buf_.size() != npoints_) + buf_.resize(npoints_); + std::pair* results = &buf_[0]; + FcnArg a; + long double v; + for (unsigned i=0; i(sigma*a_[i]); + v = w_[i]*static_cast(function(a)); + results[i].first = std::abs(v); + results[i].second = v; + } + v = 0.0L; + for (unsigned i=0; i #include #include "npstat/nm/SimpleFunctors.hh" namespace npstat { /** // Quadrature for functions of the type f(x) exp(-x^2/2) on [0, Infinity] */ class SemiInfGaussianQuadrature { public: /** // At the moment, the following numbers of points are supported: // 4, 8, 16, 24, 32. // // If an unsupported number of points is given in the // constructor, std::invalid_argument exception will be thrown. */ explicit SemiInfGaussianQuadrature(unsigned npoints); /** Return the number of quadrature points */ inline unsigned npoints() const {return npoints_;} /** // Get the abscissae for the integration points. // The buffer length should be at least npoints. */ void getAbscissae(long double* abscissae, unsigned len) const; /** // Get the weights for the integration points. // The buffer length should be at least npoints. */ void getWeights(long double* weights, unsigned len) const; /** Perform the quadrature */ template long double integrate(const Functor1& fcn) const; + /** + // Perform the quadrature f(x) Sqrt[2/Pi]/sigma Exp[-(x/sigma)^2/2] + // (the weight is normalized to unit integral on [0, Infinity]) + */ + template + long double integrateProb(long double sigma, + const Functor1& fcn) const; + /** Check if the rule with the given number of points is supported */ static bool isAllowed(unsigned npoints); /** The complete set of allowed rules, in the increasing order */ static std::vector allowedNPonts(); /** // Minimum number of points, among the supported rules, which // integrates a polynomial with the given degree exactly (with // the appropriate weight). Returns 0 if the degree is out of range. */ static unsigned minimalExactRule(unsigned polyDegree); private: SemiInfGaussianQuadrature(); const long double* a_; const long double* w_; mutable std::vector > buf_; unsigned npoints_; #ifdef SWIG public: inline std::vector abscissae2() const { return std::vector(a_, a_+npoints_); } inline std::vector weights2() const { return std::vector(w_, w_+npoints_); } #endif }; } #include "npstat/nm/SemiInfGaussianQuadrature.icc" #endif // NPSTAT_SEMIINFGAUSSIANQUADRATURE_HH_ Index: trunk/npstat/nm/GaussHermiteQuadrature.icc =================================================================== --- trunk/npstat/nm/GaussHermiteQuadrature.icc (revision 588) +++ trunk/npstat/nm/GaussHermiteQuadrature.icc (revision 589) @@ -1,68 +1,68 @@ #include #include #include namespace npstat { template inline long double GaussHermiteQuadrature::integrate( const Functor1& function) const { if (buf_.size() != npoints_) buf_.resize(npoints_); std::pair* results = &buf_[0]; const unsigned halfpoints = npoints_/2; FcnArg a; long double v; for (unsigned i=0; i(a_[i]); v = w_[i]*static_cast(function(a)); results[2*i].first = std::abs(v); results[2*i].second = v; a = static_cast(-a_[i]); v = w_[i]*static_cast(function(a)); results[2*i+1].first = std::abs(v); results[2*i+1].second = v; } std::sort(buf_.begin(), buf_.end()); v = 0.0L; for (unsigned i=0; i inline long double GaussHermiteQuadrature::integrateProb( const long double mean, const long double sigma, const Functor1& function) const { const long double sqr2 = 1.41421356237309504880168872421L; - if (buf_.size() != npoints_) - buf_.resize(npoints_); if (sigma <= 0.L) throw std::invalid_argument( "In npstat::GaussHermiteQuadrature::integrateProb: " "sigma must be positive"); + if (buf_.size() != npoints_) + buf_.resize(npoints_); std::pair* results = &buf_[0]; const unsigned halfpoints = npoints_/2; FcnArg a; long double v; for (unsigned i=0; i(mean + delta); v = w_[i]*static_cast(function(a)); results[2*i].first = std::abs(v); results[2*i].second = v; a = static_cast(mean - delta); v = w_[i]*static_cast(function(a)); results[2*i+1].first = std::abs(v); results[2*i+1].second = v; } std::sort(buf_.begin(), buf_.end()); v = 0.0L; for (unsigned i=0; i dereference for some member). Version 2.0.0 - June 15 2013, by I. Volobouev * Updated to use "Geners" version 1.3.0. A few interfaces were changed (API for the string archives was removed because Geners own string archive facilities are now adequate) so the major version number was bumped up. Version 1.6.0 - June 12 2013, by I. Volobouev * Updated some documentation. * Updated fitCompositeJohnson.icc to use simplified histogram constructors. * Bug fix in the "minuitLocalQuantileRegression1D" function. * Changed the "quantileBinFromCdf" function to use unsigned long type for array indices. * Added "weightedLocalQuantileRegression1D" function (namespace npsi) for local regression with single predictor on weighted points. Version 1.5.0 - May 23 2013, by I. Volobouev * Added interfaces to LAPACK routines DSYEVD, DSYEVR, and corresponding single precision versions. * Added the "symPSDefEffectiveRank" method to the Matrix class for calculating effective ranks of symmetric positive semidefinite matrices. * Added converting constructor and assignment operator to the Matrix class. * Run the Gram-Schmidt procedure twice when orthogonal polynomials are derived in order to improve orthogonality. Version 1.4.0 - May 20 2013, by I. Volobouev * Added the "append" method to the AbsNtuple class. Version 1.3.0 - May 10 2013, by I. Volobouev * Added the code for Hermite polynomial series. * Improved random number generator for the 1-d Gaussian distribution. * Added a framework for discrete 1-d distributions as well as two concrete distribution classes (Poisson1D, DiscreteTabulated1D). * Added functions "readCompressedStringArchiveExt" and "writeCompressedStringArchiveExt" which can read/write either compressed or uncompressed string archives, distinguished by file extension. Version 1.2.1 - March 22 2013, by I. Volobouev * Improved CmdLine.hh in the "examples/C++" directory. * Added class QuantileTable1D. * Added classes LeftCensoredDistribution and RightCensoredDistribution. Version 1.2.0 - March 13 2013, by I. Volobouev * Added convenience "fill" methods to work with the ntuples which have small number of columns (up to 10). * Fixed a bug in AbsRandomGenerator for univariate generators making multivariate points. * Added LOrPEMarginalSmoother class. Version 1.1.1 - March 11 2013, by I. Volobouev * Added utility function "symbetaLOrPEFilter1D" which creates 1-d LOrPE filters using kernels from the symmetric beta family (and the Gaussian). * Added high level driver function "lorpeSmooth1D". * Allowed variables with zero variances for calculation of correlation coefficients in "MultivariateSumsqAccumulator". Such variables will have zero correlation coefficients with all other variables. * Added rebinning constructor to the HistoND class. Version 1.1.0 - March 8 2013, by I. Volobouev * Changed NUHistoAxis::fltBinNumber method to produce correct results with interpolation degree 0. It is not yet obvious which method would work best for higher interpolation degrees. * Added functions for converting between StringArchive and python bytearray. They have been placed in a new header: wrap/stringArchiveToBinary.hh. * Added methods "exportMemSlice" and "importMemSlice" to ArrayND. These methods allow for filling array slices from unstructured memory buffers and for exporting array slices to such memory buffers. * Added "simpleColumnNames" function (header file AbsNtuple.hh) to generate trivial column names when ntuple column names are not important. * Added functions "neymanPearsonWindow1D" and "signalToBgMaximum1D". They are declared in a new header npstat/neymanPearsonWindow1D.hh. Version 1.0.5 - December 17 2012, by I. Volobouev * Flush string archives before writing them out in stringArchiveIO.cc. * Added class TruncatedDistribution1D. Version 1.0.4 - November 14 2012, by I. Volobouev * Added utilities for reading/writing Geners string archives to files. * Added BinSummary class. * Doxygen documentation improved. Every header file in stat, nm, rng, and interfaces now has a brief description. Version 1.0.3 - September 27 2012, by I. Volobouev * Fixed some bugs related to moving StorableMultivariateFunctor code from "nm" to "stat". Version 1.0.2 - August 6 2012, by I. Volobouev * Added converting copy constructor to the "LinInterpolatedTableND" class. * Added StorableMultivariateFunctor class (together with the corresponding reader class). * Added StorableInterpolationFunctor class which inherits from the above and can be used with interpolation tables. * Added StorableHistoNDFunctor class which inherits from StorableMultivariateFunctor and can be used to interpolate histogram bins. * Added "transpose" method to HistoND class. * Created DualAxis class. * Created DualHistoAxis class. * Added conversion functions between histogram and grid axes. * Added "mergeTwoHistos" function for smooth merging of two histograms. * Added "ProductSymmetricBetaNDCdf" functor to be used as weight in merging histograms. * Added CoordinateSelector class. Version 1.0.1 - June 29 2012, by I. Volobouev * Implemented class LinInterpolatedTableND with related supporting code.