[phoenix][lambda] lambda to phoenix translation: get sig (signature) from actor

hi, what is the translation of boost.lambda typename LambdaExp::template sig<tuple<InputType> >::type in Boost.Phoenix? my best try was: actor<LambdaExp>::result< vector<InputType> >::type but it doesn't compile. Thank you, Alfredo

On 5/30/2010 8:35 AM, alfC wrote:
hi, what is the translation of boost.lambda
typename LambdaExp::template sig<tuple<InputType> >::type
in Boost.Phoenix?
my best try was: actor<LambdaExp>::result< vector<InputType> >::type
but it doesn't compile.
I'm not sure if it's a good idea to go beyond the documented features. The more you do this, the more work you'll have to do in porting it to Phoenix-3. What is it you are trying to do? Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon

I'm not sure if it's a good idea to go beyond the documented features. The more you do this, the more work you'll have to do in porting it to Phoenix-3. What is it you are trying to do?
thank you for the advise. What I am trying to do mixes boost.units with lambda/phoenix expressions I had a function that worked well with lambda and I am trying to make it work with phoenix. In a previous post I asked how to translate the argument, which is done, of the following function (called qawc) and now I am trying to translate the result type. template<class LambdaExp, class UnitIntegrandDomain> typename multiply_typeof_helper< \ typename divide_typeof_helper< \ quantity<typename LambdaExp::template sig<tuple<quantity<UnitIntegrandDomain> > >::type::unit_type>, \ quantity<UnitIntegrandDomain> \ >::type, \ quantity<UnitIntegrandDomain> \ >::type qawc( lambda_functor<lambda_functor_base< arithmetic_action<divide_action>, tuple< lambda_functor<// LambdaExp >,// lambda_functor<lambda_functor_base< arithmetic_action<minus_action>, tuple< lambda_functor< placeholder<1> >, quantity<UnitIntegrandDomain> const > > > > > > f_expr, boost::numeric::interval<quantity<UnitIntegrandDomain> > const& iv ){ typedef RET_TYPE ret_type; double const c = get<1>(get<1>(f_expr.args).args).value(); double ret = gsl::integration::qawc( bind( &LambdaExp::template sig<tuple<quantity<UnitIntegrandDomain> >
::type::value, get<0>(f_expr.args) (bind(&quantity<UnitIntegrandDomain>::from_value, _1)) ), boost::numeric::interval<double>( lower(iv).value() , upper(iv).value() ), c ); return ret_type::from_value(ret); }

On 5/30/2010 9:48 AM, alfC wrote:
I'm not sure if it's a good idea to go beyond the documented features. The more you do this, the more work you'll have to do in porting it to Phoenix-3. What is it you are trying to do?
thank you for the advise. What I am trying to do mixes boost.units with lambda/phoenix expressions I had a function that worked well with lambda and I am trying to make it work with phoenix. In a previous post I asked how to translate the argument, which is done, of the following function (called qawc) and now I am trying to translate the result type.
I am not sure if this is the best way to do it in either Lambda nor Phoenix (I'm pretty sure that even with lambda, you are going beyond the documentation, no?). However, I am not knowledgeable enough of the domain you are involved with, nor do I know what qawc means. Anyway... In Phoenix (see Actors In Detail at: http://tinyurl.com/24wlduz), a lambda is always an: actor<Eval> The return type deduction of Eval are (given varying arguments): typename apply_actor<eval_type, basic_environment<> >::type typename apply_actor<eval_type, basic_environment<T0> >::type typename apply_actor<eval_type, basic_environment<T0, T1> >::type ... typename apply_actor<eval_type, basic_environment<T0, T1, ... TN> >::type So, assuming you know your lambda-eval-type, and your arguments, you can get the return type. The documented "result" protocol for Eval is: T::result<Env>::type where Env is your environment (See the link I provided above). Typically, for client use, the environment is just basic_environment<...>. HTH. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon

I am not sure if this is the best way to do it in either Lambda nor Phoenix (I'm pretty sure that even with lambda, you are going beyond the documentation, no?).
I guess that extracting subexpressions (and subexpression types) of an expression goes beyond Lambda and Phoenix documentation. and yes that is what I am trying to do.
However, I am not knowledgeable enough of the domain you are involved with, nor do I know what qawc means.
qawc is an interface to http://tinyurl.com/gslqwac now you can imagine what I a trying to do, basically extract the function information from a lambda expression.
In Phoenix (see Actors In Detail at:http://tinyurl.com/24wlduz), a lambda is always an:
actor<Eval> The documented "result" protocol for Eval is:
T::result<Env>::type
where Env is your environment (See the link I provided above). Typically, for client use, the environment is just basic_environment<...>.
well I tried this and didn't work typename actor<LambdaExp>::result<basic_environment<quantity<UnitIntegrandDomain>
::type
now my closest guess is typename actor<LambdaExp>::template result<actor<LambdaExp>(quantity<UnitIntegrandDomain>)>::type which is almost the type I am trying to generate but it is of 'const&' (const reference) type which is a problem for a return type because of 'returning reference to temporary'. Thank you, Alfredo

On 5/30/10 11:26 AM, alfC wrote:
I am not sure if this is the best way to do it in either Lambda nor Phoenix (I'm pretty sure that even with lambda, you are going beyond the documentation, no?).
I guess that extracting subexpressions (and subexpression types) of an expression goes beyond Lambda and Phoenix documentation. and yes that is what I am trying to do.
However, I am not knowledgeable enough of the domain you are involved with, nor do I know what qawc means.
qawc is an interface to http://tinyurl.com/gslqwac now you can imagine what I a trying to do, basically extract the function information from a lambda expression.
In Phoenix (see Actors In Detail at:http://tinyurl.com/24wlduz), a lambda is always an:
actor<Eval> The documented "result" protocol for Eval is:
T::result<Env>::type
where Env is your environment (See the link I provided above). Typically, for client use, the environment is just basic_environment<...>.
well I tried this and didn't work typename actor<LambdaExp>::result<basic_environment<quantity<UnitIntegrandDomain>
::type
now my closest guess is typename actor<LambdaExp>::template result<actor<LambdaExp>(quantity<UnitIntegrandDomain>)>::type
which is almost the type I am trying to generate but it is of 'const&' (const reference) type which is a problem for a return type because of 'returning reference to temporary'.
Perhaps just remove ref if you want the value? Anyway, I think I need to look more closely. But right now, I'm quite full. It seems you have it working anyway, no? If so, can we get back to this later so I can offer a better library solution? I'm very interested with this and how we can do better with the current Phoenix-3 rewrite. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

which is almost the type I am trying to generate but it is of 'const&' (const reference) type which is a problem for a return type because of 'returning reference to temporary'.
Perhaps just remove ref if you want the value?
yes, I did that typename remove_reference<typename actor<LambdaExp>::template result<actor<LambdaExp>(quantity<UnitIntegrandDomain>)>::type>::type but the syntax is becoming difficult.
Anyway, I think I need to look more closely. But right now, I'm quite full. sorry if I made you waste your time, and thank you for your help so far.
It seems you have it working anyway, no?
yes and no, the argument and the return type are fully translated from lambda to phoenix the final result is: typename remove_reference< typename actor<LambdaExp>::template result<actor<LambdaExp>(quantity<UnitIntegrandDomain>)>::type>::type qawc(actor<composite< divides_eval, vector< LambdaExp, composite< minus_eval, vector< argument<0>, boost::phoenix::value< quantity<UnitIntegrandDomain> > > > > > > f_expr, boost::numeric::interval<boost::units::quantity<UnitIntegrandDomain>
const& iv ){
Now the problem is to translate the body of the function, the original Boost.Lambda version was bind( &LambdaExp::template sig<tuple<quantity<UnitIntegrandDomain> >
::type::value, get<0>(f_expr.args) (bind(&quantity<UnitIntegrandDomain>::from_value, _1)) ), which I can not translate into boost.phoenix, my best try is boost::phoenix::bind( &remove_reference<typename actor<LambdaExp>::template result<actor<LambdaExp>(quantity<UnitIntegrandDomain>)>::type>::type::value, actor<LambdaExp>(at_c<0>(f_expr))( boost::phoenix::bind( &quantity<UnitIntegrandDomain>::from_value, boost::phoenix::arg_names::arg1 ) ) ); which does not compile ("no match for call to ‘(actor<argument<0> >) (actor<composite ... )")
On one hand Phoenix seems more powerful than BLL but BLL is more intuitive to go into the internal works.
If so, can we get back to this later so I can offer a better library solution? I'm very interested with this and how we can do better with the current Phoenix-3 rewrite.
Sure, glad you are interested. Let me know if you need more details, what I am doing now is an experimental code to interface GSL routines from C++ that uses lambda expression. Experimental in the sense that I want to see how far I can get with Phoenix in terms of building a natural (mathematical) language interface to numerical routines. In this experimental code I am trying to make the functions smart enough to recognize *simple* patterns in the expression. In this example, it recognizes the singularity (at 3.) in the integral integral( f( _1 )/(_1 - 3.) , interval(2., 4.)); other simple expressions are solve( f(_1) == 2.); just to give you an idea. I am not sure if am repeating someone else's work but when I see expression templates in C++ I see numerical and symbolic mathematics converge into the perfect language to do scientific computing. Of course the patterns do not need to be necessarily *simple* in the future, once we master Phoenix we can go beyond to write transformation rules for expression, in order to do that I must gain complete access to the internal subexpressions and subexpression types. Thank you, Alfredo

On 5/30/2010 10:50 PM, alfC wrote: <snip>
Sure, glad you are interested. Let me know if you need more details, what I am doing now is an experimental code to interface GSL routines from C++ that uses lambda expression. Experimental in the sense that I want to see how far I can get with Phoenix in terms of building a natural (mathematical) language interface to numerical routines. In this experimental code I am trying to make the functions smart enough to recognize *simple* patterns in the expression. In this example, it recognizes the singularity (at 3.) in the integral
integral( f( _1 )/(_1 - 3.) , interval(2., 4.));
other simple expressions are
solve( f(_1) == 2.);
just to give you an idea. I am not sure if am repeating someone else's work but when I see expression templates in C++ I see numerical and symbolic mathematics converge into the perfect language to do scientific computing. Of course the patterns do not need to be necessarily *simple* in the future, once we master Phoenix we can go beyond to write transformation rules for expression, in order to do that I must gain complete access to the internal subexpressions and subexpression types.
In that case, I think your best bet is to build your own DSEL using Proto. Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news. The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions. Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting. -- Eric Niebler BoostPro Computing http://www.boostpro.com

In that case, I think your best bet is to build your own DSEL using Proto.
that is the point, I don't want to build another DSEL (and wouldn't know how to do it with proto), C++ language as a DSEL is enough to experiment with the expressions right know, and that is the reason I ended up using phoenix.
Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news.
The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions.
well that would be perfect. I don't imagine how (just because I still don't understand proto) but in any case I should be able to do it for the current phoenix, ... in principle. or I'll rather wait for Phoenix3.
Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting.
sure. I am surprised that I am using phoenix in a way that was not intended for. What are expression for if not to take them appart and analyse piece by piece? Thank you, Alfredo

On 5/31/2010 11:35 AM, Eric Niebler wrote:
On 5/30/2010 10:50 PM, alfC wrote: <snip>
Sure, glad you are interested. Let me know if you need more details, what I am doing now is an experimental code to interface GSL routines from C++ that uses lambda expression. Experimental in the sense that I want to see how far I can get with Phoenix in terms of building a natural (mathematical) language interface to numerical routines. In this experimental code I am trying to make the functions smart enough to recognize *simple* patterns in the expression. In this example, it recognizes the singularity (at 3.) in the integral
integral( f( _1 )/(_1 - 3.) , interval(2., 4.));
other simple expressions are
solve( f(_1) == 2.);
just to give you an idea. I am not sure if am repeating someone else's work but when I see expression templates in C++ I see numerical and symbolic mathematics converge into the perfect language to do scientific computing. Of course the patterns do not need to be necessarily *simple* in the future, once we master Phoenix we can go beyond to write transformation rules for expression, in order to do that I must gain complete access to the internal subexpressions and subexpression types.
In that case, I think your best bet is to build your own DSEL using Proto. Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news.
The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions.
Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting.
Indeed very timely. See also: http://tinyurl.com/37mguzo "phoenix domain language (to write mathematical formulas)" (Cc'ing the author) This is not the first time Phoenix has been used this way. Yet one of the reasons why I insist on a simple extension interface. I think we're on the right track, Eric. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon

Incidentally, your message is very timely. Joel and I have just been discussing off-list the possibilities opened up by giving users access to Phoenix expressions at this level. It's really very exciting.
Indeed very timely. See also:http://tinyurl.com/37mguzo "phoenix domain language (to write mathematical formulas)"
right, since C++ is "mathematical enough" (or as mathematical as it can be with the small set of available symbols [+,-,/,*,==]) then phoenix is mathematical enough, creating a mathematical DSEL on proto probably won't be better than phoenix [except for very specific mathematical area, e.g. tensor manipulation] this discussion is very nice, and now that you know the context maybe I can recast the question: I am extracting a subexpression (don't know the exact name in phoenix jargon) called LambdaExp, by recognizing the pattern actor<composite< divides_eval, vector< LambdaExp, composite< minus_eval, vector< argument<0>, boost::phoenix::value< quantity<UnitIntegrandDomain> > > > > > > f_expr now I want to use this LambdaExp (extracted as at_c<0>(f_expr)) applied to a bind expression, and subsecuently binded. ie in a composition of this kind, with the functions 'value' and 'from_value'. value( LambdaExp (from_value( x) ) ) (this in the context of boost.units is necesary to adimensionalize an expression, apply a normal function and then restore de dimension), this is the closest I got but doesn't work: bind( &result_type::value, actor<LambdaExp>(at_c<0>(f_expr))( // Question: what goes here? to apply the subexpr. bind( &quantity<UnitIntegrandDomain>::from_value, arg_names::arg1 ) ) // end here ); Thank you, Alfredo

alfC wrote:
creating a mathematical DSEL on proto probably won't be better than phoenix [except for very specific mathematical area, e.g. tensor manipulation]
I'll shamelessly point you to my workon such a topic tha I presented a Boost'Con 2010: http://www.filetolink.com/188d42d9

On 5/31/2010 4:18 PM, alfC wrote:
(this in the context of boost.units is necesary to adimensionalize an expression, apply a normal function and then restore de dimension), this is the closest I got but doesn't work:
bind( &result_type::value, actor<LambdaExp>(at_c<0>(f_expr))( // Question: what goes here? to apply the subexpr. bind( &quantity<UnitIntegrandDomain>::from_value, arg_names::arg1 ) ) // end here );
What are the args to LambdaExp? Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon

bind( &result_type::value, actor<LambdaExp>(at_c<0>(f_expr))( // Question: what goes here? to apply the subexpr. bind( &quantity<UnitIntegrandDomain>::from_value, arg_names::arg1 ) ) // end here );
What are the args to LambdaExp?
f_expr can be any phoenix expression taking one argument the integration variable, and returning a quantity. the object of LambdaExp type can be any phoenix subexpression of f_expr, typically should represent another function that takes one argument the integration variable (e.g. quantity) and returns another quantity to give you an example: if f_expr was "(boost::phoenix::arg_names::_1 * 0.2 )/ (boost::phoenix::arg_names::_1-wp)" (wp is a constant) the type of LambdaExp is composite<multiplies_eval, vector<argument<0>, value<double> > if f_expr was "(boost::phoenix::arg_names::_1)/ (boost::phoenix::arg_names::_1-wp)" then the type LambdaExp is argument<0> fi f_expr was "wp/(boost::phoenix::arg_names::_1-wp)" then the type LambdaExp is value<boost::units::quantity<...> > note that LambdaExp is the numerator in the fraction. the question is how to apply whatever is represented by at_c<0>(f_expr) to another phoenix expression. Thank you, Alfredo

On May 31, 3:07 am, Joel de Guzman <j...@boost-consulting.com> wrote:
What are the args to LambdaExp?
ok, I think I simplified the code as much as possible to its bare bones, here it is a compilable example of what I need. as you see first there is a lambda version which is concise and works, then follows the phoenix attempt. I have and expression template _1 + 1. or arg1 + 1. and I am trying to compose it with two free functions (sq and div2). Take _1 + 1. or arg1 + 1. as black box (this is an example of what the subexpression that the pattern matching recognizes in the full example). The precise question is what is the phoenix translation of the lambda "bind(&div2, (_1+1.)(bind(&sq, _1) ) )" ? [ _1+1. is just an example, in the real code is some argument passed and can be any expression, in other words "(_1+1.)" must remain there, so (bind(&div2, (bind(&sq,arg1) ) + 1. ) is not the answer I am looking for]. the full minimal example is below: #include<boost/function.hpp> #include<boost/spirit/home/phoenix.hpp> #include<boost/lambda/lambda.hpp> #include<boost/lambda/bind.hpp> double sq(double x){return x*x;} double div2(double x){return x/2.;} using namespace std; int main(){ {// first with lambda using namespace boost::lambda; double const dos = 2.; boost::function<double(double)> f( bind(&div2, (_1+1.)(bind(&sq, _1) ) ) ); cout<< f(dos) << endl; // returns 2.5 } {// second with phoenix using namespace boost::phoenix; using namespace boost::phoenix::arg_names; double const dos = 2.; // boost::function<double(double)> f( (bind(&div2, (arg1+1.) (bind(&sq,arg1) ) ) )); //doesn't work, what goes here?? // cout<< f(dos) << endl; // should return 2.5 } return 0; }; I tried all sorts of things, I am starting to think that Phoenix is not designed for this (although it is supposed to be a generalization of BLL.) Thank you, Alfredo

On 6/2/10 5:03 PM, alfC wrote:
On May 31, 3:07 am, Joel de Guzman<j...@boost-consulting.com> wrote:
What are the args to LambdaExp?
ok, I think I simplified the code as much as possible to its bare bones, here it is a compilable example of what I need. as you see first there is a lambda version which is concise and works, then follows the phoenix attempt. I have and expression template _1 + 1. or arg1 + 1. and I am trying to compose it with two free functions (sq and div2). Take _1 + 1. or arg1 + 1. as black box (this is an example of what the subexpression that the pattern matching recognizes in the full example).
The precise question is what is the phoenix translation of the lambda "bind(&div2, (_1+1.)(bind(&sq, _1) ) )" ? [ _1+1. is just an example, in the real code is some argument passed and can be any expression, in other words "(_1+1.)" must remain there, so (bind(&div2, (bind(&sq,arg1) ) + 1. ) is not the answer I am looking for].
the full minimal example is below:
#include<boost/function.hpp> #include<boost/spirit/home/phoenix.hpp> #include<boost/lambda/lambda.hpp> #include<boost/lambda/bind.hpp>
double sq(double x){return x*x;} double div2(double x){return x/2.;} using namespace std; int main(){ {// first with lambda using namespace boost::lambda; double const dos = 2.; boost::function<double(double)> f( bind(&div2, (_1+1.)(bind(&sq, _1) ) ) ); cout<< f(dos)<< endl; // returns 2.5 } {// second with phoenix using namespace boost::phoenix; using namespace boost::phoenix::arg_names; double const dos = 2.; // boost::function<double(double)> f( (bind(&div2, (arg1+1.) (bind(&sq,arg1) ) ) )); //doesn't work, what goes here?? // cout<< f(dos)<< endl; // should return 2.5 } return 0; };
I tried all sorts of things, I am starting to think that Phoenix is not designed for this (although it is supposed to be a generalization of BLL.)
You are right. Phoenix is not designed to compose that way. I've taken note of this use case and it probably be incorporated into 3.0. However, take note that we do things differently in Phoenix. This use case is typically done using phoenix::functions and phoenix higher order functions called phoenix::lambda. Here's how I would write your code in Phoenix: 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]); divdoub is trivial to write. See attached for complete code. Things to note: * This is much more efficient than nested binds * It is polymorphic, bind is monomorphic * Client code is easier to read (I never really liked nested binds). * It is easier to compose: composition is just a function object like any other, wrapped in a phoenix::function. No messy introspection. * While there's more code to write, the extra code is typically part of a library. See phoenix algorithms and containers, for example, which wraps STL containers and algorithms as lazy functions. Hope that helps. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

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

On 6/5/2010 6:21 AM, alfC wrote:
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,
Great! <snip>
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: <snip>
To repeat: in Phoenix 3, this will be easier. Rather that writing your own custom pattern matching meta-program, you'll be able to use Proto grammars to find patterns in Phoenix expressions, and you'll use Proto transforms to modify the expressions however you want. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 5/31/2010 3:39 AM, Joel de Guzman wrote:
On 5/31/2010 11:35 AM, Eric Niebler wrote:
On 5/30/2010 10:50 PM, alfC wrote: <snip>
Of course the patterns do not need to be necessarily *simple* in the future, once we master Phoenix we can go beyond to write transformation rules for expression, in order to do that I must gain complete access to the internal subexpressions and subexpression types.
In that case, I think your best bet is to build your own DSEL using Proto. Proto will let you define placeholders and will build expressions for you. It will *also* give you the tools to access, analyze and transform subexpressions in the ways you describe. In essence, you'll need to implement your own mini-Phoenix. That's the bad news.
The good news is: in the (near!) future, Phoenix will be built on top of Proto so that you'll be able to use Proto to access, analyze and transform Phoenix expressions. <snip>
Indeed very timely. See also: http://tinyurl.com/37mguzo "phoenix domain language (to write mathematical formulas)"
(Cc'ing the author)
This is not the first time Phoenix has been used this way. Yet one of the reasons why I insist on a simple extension interface. I think we're on the right track, Eric.
The "phoenix domain language" thread argues for a simple extension interface, but that this thread argues for powerful expression introspection and transformation facilities: two separate things, both of which will be nicely addressed by our current working design. Yes, we're on the right track. Finally. -- Eric Niebler BoostPro Computing http://www.boostpro.com
participants (4)
-
alfC
-
Eric Niebler
-
Joel de Guzman
-
Joel Falcou