Nori

include/nori/quad.h

Go to the documentation of this file.
00001 /*
00002     This file is part of Mitsuba, a physically based rendering system.
00003 
00004     Copyright (c) 2007-2011 by Wenzel Jakob and others.
00005 
00006     Mitsuba is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License Version 3
00008     as published by the Free Software Foundation.
00009 
00010     Mitsuba is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program. If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 #if !defined(__QUADRATURE_H)
00020 #define __QUADRATURE_H
00021 
00022 #include <nori/common.h>
00023 #include <boost/function.hpp>
00024 
00025 NORI_NAMESPACE_BEGIN
00026 
00027 /**
00028  * \brief Adaptively computes the integral of a multidimensional function using 
00029  * either a Gauss-Kronod (1D) or a Genz-Malik (>1D) cubature rule.
00030  *
00031  * This class is a C++ wrapper around the \c cubature code by Steven G. Johnson
00032  * (http://ab-initio.mit.edu/wiki/index.php/Cubature)
00033  *
00034  * The original implementation is based on algorithms proposed in
00035  *
00036  * A. C. Genz and A. A. Malik, "An adaptive algorithm for numeric integration
00037  * over an N-dimensional rectangular region," J. Comput. Appl. Math. 6 (4),
00038  * 295–302 (1980).
00039  *
00040  * and
00041  *
00042  * J. Berntsen, T. O. Espelid, and A. Genz, "An adaptive algorithm for the
00043  * approximate calculation of multiple integrals," ACM Trans. Math. Soft. 17
00044  * (4), 437–451 (1991).
00045  *
00046  * \ingroup libcore
00047  */
00048 class NDIntegrator {
00049 public:
00050         typedef boost::function<void (const double *, double *)>         Integrand;
00051         typedef boost::function<void (size_t, const double *, double *)> VectorizedIntegrand;
00052 
00053         enum EResult {
00054                 ESuccess = 0,
00055                 EFailure = 1
00056         };
00057 
00058         /**
00059          * Initialize the Cubature integration scheme
00060          *
00061          * \param fDim Number of integrands (i.e. dimensions of the image space)
00062          * \param nDim Number of integration dimensions (i.e. dimensions of the
00063          *      function domain)
00064          * \param maxEvals Maximum number of function evaluationn (0 means no 
00065          *      limit). The error bounds will likely be exceeded when the
00066          *      integration is forced to stop prematurely. Note: the actual 
00067          *      number of evaluations may somewhat exceed this value.
00068          * \param absError Absolute error requirement (0 to disable)
00069          * \param relError Relative error requirement (0 to disable)
00070          */
00071         NDIntegrator(size_t fDim, size_t dim,
00072                         size_t maxEvals, double absError = 0, double relError = 0);
00073 
00074         /**
00075          * \brief Integrate the function \c f over the rectangular domain 
00076          * bounded by \c min and \c max.
00077          *
00078          * The supplied function should have the interface
00079          *
00080          * <code>
00081          * void integrand(const double *in, double *out);
00082          * </code>
00083          *
00084          * The input array \c in consists of one set of input parameters
00085          * having \c dim entries. The function is expected to store the
00086          * results of the evaluation into the \c out array using \c fDim entries.
00087          */
00088         EResult integrate(const Integrand &f, const double *min, const double *max,
00089                         double *result, double *error, size_t *evals = NULL) const;
00090 
00091         /**
00092          * \brief Integrate the function \c f over the rectangular domain 
00093          * bounded by \c min and \c max.
00094          *
00095          * This function implements a vectorized version of the above
00096          * integration function, which is more efficient by evaluating
00097          * the integrant in `batches'. The supplied function should 
00098          * have the interface
00099          *
00100          * <code>
00101          * void integrand(int numPoints, const double *in, double *out);
00102          * </code>
00103          *
00104          * Note that \c in in is not a single point, but an array of \c numPoints points
00105          * (length \c numPoints x \c dim), and upon return the values of all \c fDim
00106          * integrands at all \c numPoints points should be stored in \c out 
00107          * (length \c fDim x \c numPoints). In particular, out[i*dim + j] is the j-th
00108          * coordinate of the i-th point, and the k-th function evaluation (k<fDim)
00109          * for the i-th point is returned in out[k*npt + i].
00110          * The size of \c numPoints will vary with the dimensionality of the problem;
00111          * higher-dimensional problems will have (exponentially) larger numbers,
00112          * allowing for the possibility of more parallelism. Currently, \c numPoints
00113          * starts at 15 in 1d, 17 in 2d, and 33 in 3d, but as the integrator
00114          * calls your integrand more and more times the value will grow. e.g. if you end
00115          * up requiring several thousand points in total, \c numPoints may grow to
00116          * several hundred.
00117          */
00118         EResult integrateVectorized(const VectorizedIntegrand &f, const double *min, 
00119                 const double *max, double *result, double *error, size_t *evals = NULL) const;
00120 protected:
00121         size_t m_fdim, m_dim, m_maxEvals;
00122         double m_absError, m_relError;
00123 };
00124 
00125 NORI_NAMESPACE_END
00126 
00127 #endif /* __QUADRATURE_H */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines