RE:Integral of a one-dimensional function as a template function
Posted by RGProlog on Dec 09, 2002; 1:19am
URL: http://quantlib.414.s1.nabble.com/RE-Integral-of-a-one-dimensional-function-as-a-template-function-tp2313.html
Hi, Quantlib,
The following is a proposal for the templated SegmentIntegral class, which, I hope, is still on the to do list:
template<class Arg, class Res>
class PFunctor : public std::unary_function<Arg, Res>{
typedef result_type (*QL_ATOR_TYP)(argument_type);
protected:
PFunctor(QL_ATOR_TYP f) : f_(f) {}
QL_ATOR_TYP f_;
};
template<class Arg, class Res>
class SegmentIntegral : public PFunctor<Arg, Res>{
public:
SegmentIntegral(QL_ATOR_TYP f) : PFunctor<Arg, Res>(f) {}
result_type operator()(Size, argument_type, argument_type) const;
};
template<class Arg, class Res>
SegmentIntegral<Arg, Res>::result_type
SegmentIntegral<Arg, Res>::operator()(Size intervals,
argument_type a,
argument_type b) const {
QL_REQUIRE(intervals > 3,
"at least 4 intervals needed, given only "+
IntegerFormatter::toString(intervals));
QL_REQUIRE(a < b,
"to compute an integral on [a,b] it must be a<b; a="+
DoubleFormatter::toString(a)+" b="+
DoubleFormatter::toString(b));
argument_type dx = (b - a) / intervals;
result_type sum = (f_(a + 0.5 * dx) + f_(b - 0.5 * dx)) * dx / 2;
for(argument_type x = a + 1.5 * dx; x < b - 0.5 * dx; x += dx)
sum += f_(x) * dx;
return sum;
}
Unlike the SegmentIntegral class' nontemplated version, the templated version of the class takes a function pointer as its ctors' only argument, which, I believe, is a natural way to tie a function to its integral over an interval. The number of subintervals of the segment is an argument to the SegmentIntegral::operator()(). The following is an example of the class' usage:
double f(double x) (...)
int main(int argc, char* argv[]) {
..........................................................
SegmentIntegral<double , double> segmentIntegral(f);
for(int i = 4; i < 40; ++i)
std::cout << segmentIntegral(i, 3, 5) << std::endl;
..........................................................
return 0;
}
Using the present non templated vesion of the SegmentIntegral class one would have to create 37 instances of the class to have the same print-out. I believe the proposed arrangement is natural, efficient, flexible, and user-friendly.
The general design of the templated SegmentIntegral class was done in the spirit of ATL, where inheritance is widwly used
as means of enhancing a class' functionality.with minimal changes to the class itself.
Roman Gitlin