|
Hello Quantlib,
Here 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(QL_ATOR_TYP));
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 in the existing version, here SegmentIntegral ctor takes a function pointer as its singular argument, while the number of intervals becomes and argument to the operator(), which allowes to use the same class object for arbitrarily refined calculations, and which, I believe, makes this class more user friendly. Also, the SegmentIntegral proposed design provides good economy, modularity, extensibility, and encapsulation.
Roman Gitlin
|