
On May 31, 3:07 am, Joel de Guzman<j...@boost-consulting.com> wrote: First, I'll start with a phoenix function taking in a higher order phoenix function: _1+1.
boost::function<double(double)> f = divdoub(_1, lambda[_1+1.0]);
Hi Joel DG., Eric N. and Steven W., thank you so much for your help after all these posts I can call my little experiment a success, a nice mashup between, numeric libraries (not from Boost), Boost.Units, Boost.Interval and Boost.Phoenix (Boost.Lambda didn't make it to the end). It can be resumed in this actual line of code cout << qawc( _1 / (_1 - 3.*si::hertz), interval(2.*si::hertz, 4.*si::hertz)) << endl; //outputs 2 hertz let me explain what it does (in can be a nice case study for Boost.Phoenix3), 1) it takes a phoenix expression [e.g. _1/(_1-3.*si::hertz)], and singles out the denominator which has a singularity at 3.*si::hertz this qawc function stores the numerator and the singular point, it does that by a sort of pattern matching in the function argument: actor<composite< divides_eval, vector< LambdaExp, composite< minus_eval, vector< argument<0>, boost::phoenix::value< quantity<UnitIntegrandDomain> > > > > > > qawc can accept any expression as long as it has a denominator with the form (_1 - c) [singular at c] 2) then it generates an adimensional version of the lambda expression (numerator) that doesn't involves units in its input or output, this is obtained by a generic adimensionalizer of lambda... sorry phoenix expressions: namespace boost{namespace units{ template<class UnitDomain> struct adimensionalized_{ template <typename T, typename F> struct result{ typedef T type; }; template <typename T,typename F> T operator()(T x, F f) const{ quantity<UnitDomain,T> no_temporary = quantity<UnitDomain,T>::from_value(x); return f(no_temporary).value(); } //use as: // boost::phoenix::function<adimensionalized_<si::length> > const adimensionalized = adimensionalized_<si::length>(); // boost::function<double(double)> fadd = adimensionalized(arg1, lambda[arg1*arg1]); }; }} 3) once a function object that is not dimensional is generated it is plugged in into an small interface to the GNU GSL which does a so called "principal value" integration around the sigular point. double ret = gsl::integration::qawc( fad, //adimensionalized function boost::numeric::interval<double>( lower(iv).value() , upper(iv).value() ), //adim interval c //singular point ); 4) the result is returned with the correct dimensionality (units) converted from the adimensional result of the integral conclusion: a modest symbolic capability is achievable with Boost.Phoenix, depending on the expression pattern, one or other numerical integration routine can be called. dimensional quantities and expression can be used. BTW, Joel, since you are taking notes, it would be interesting if dummy named variables can be introduced in this "functional" type programming: so something like, integration( _1*_1/(_1 - 2.), 1., 3.) can be expressed as dummy x; //or dummy<double> x; for extra control of usage. ... integration(x*x/(x-2.), x, 1.,3.); // hey! this is GNU Maxima syntax! Thank you, Alfredo