On Fri, Apr 8, 2011 at 10:56 AM, Karsten Ahnert <karsten.ahn...@ambrosys.de> wrote: >>>> If you need to compute intermediate values, you can use a transform to >>>> build a parallel structure. >>> >>> Do you mean to build an entire new tree, or just to replace some nodes? >> >> If only some nodes have associated intermediate result, then you could >> just replace some nodes. > > Ok, this is a clear hint. > >>> In my current algorithm I use callable contexts to do the work. I think >>> this is more favorable since I have to evaluate the tree N times to >>> obtain >>> the result. >> >> Why does that matter? Transforms are almost always a better choice. >> >>> I think it would be nice to replace some nodes and customizing >>> the evaluation context, such that these nodes can be used to store the >>> intermediates. >> >> If you're doing calculation *and* tree transformation, then drop the >> callable contexts. They can't do the job. > > First I do tree transformation and then calculation. A Callable context > will not do the job, since one only gets the tag of the current node, but > not the node itself. So I have to implement my own context. > > I am not sure if transforms can do that job. It is definitely not possible > to obtain the full tree for 10th derivative. Maybe some other tricks are > possible with transforms. At the moment I don't understand them in detail, > but I will try to change this. Thanks for your advice.
Why not just write a transform that calculates one derivative and call it N times to get the Nth derivative? Something like: struct derivative : proto::or_< proto::when< proto::plus<derivative, derivative> , proto::_make_plus<derivative(proto::_left), derivative(proto::_right)> > proto::when< proto::multiplies<derivative, derivative> , proto::_make_plus< proto::_make_multiplies<derivative(proto::_left), proto::_right> ,proto::_make_multiplies<proto::_left, derivative(proto::_right)> > > > /* add more derivation rules*/ {}; template <int N> struct derive_impl { template <typename Sig> struct result; template <typename This, typename Expr> struct result<This(Expr)> { typedef typename boost::result_of<derivative(Expr)>::type first_derivative; typedef typename boost::result_of<derive_impl<N-1>(first_derivative)>::type type; }; template <typename Expr> typename result<derive_impl(Expr const&)>::type operator()(Expr const & expr) const { return derive_impl<N-1>(derivative()(expr)); } }; template <> struct derive_impl<0> { template <typename Sig> struct result; template <typename This, typename Expr> struct result<This(Expr)> : result<This(Expr const &)> {}; template <typename This, typename Expr> struct result<This(Expr &)> { typedef Expr type; }; template <typename Expr> typename result<derive_impl(Expr const&)>::type operator()(Expr const & expr) const { return expr; } }; template <int N, typename Expr> typename boost::result_of<derive_impl<N>(Expr const &)>::type derive(Expr const & expr) { return derive_impl()(expr); } _______________________________________________ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto