|
Boost Users : |
Subject: Re: [Boost-users] Extending boost::function for mathematics?
From: Russell L. Carter (rcarter_at_[hidden])
Date: 2009-01-25 19:10:21
jesseperla wrote:
>> Do you require that a math_function object be callable?
>
> It is a good question, and one I have wrestled with. The short answer
> is that the algorithms you might use it with are for these is in
> scientific processing with an incredibly high number of executions.
> So for the same reason you might want to write function objects that
> directly implement operator() and have typedef result_type for
> adaptation, you would want a similar option when designing generic
> algorithms. If you don't use math_function, you can inline.. if you
> do, then it will use boost::function dispatching for its underlying
> object.
>
> I think that part of the design question here is whether this is a
> (type erasure) wrapper class that implements the concept of a
> differentiable function, and what that concept looks like. For
> example, here is what I am thinking for a root finder:
This discussion is very interesting.
Probably you know this already but if not, given an f smooth over
the desired interval, this paper has a technique for making the calculation
of the derivatives generic:
http://homepage.mac.com/sigfpe/paper.pdf
Russell
>
> template <class F>
> double find_root(F f, double initial_value)
> {
> //implement newton's method executing f(x) and f.gradient(x) to
> find the zero
> //This might want to do a dynamic or static assertion that the
> function has some sort of single_crossing trait associated with
> it.... For later, but this is why I think those traits are useful.
> }
>
> struct square {double operator()(double x){return x*x;} double
> gradient(double x){return 2 * x;} }; //quadratic differentiable
> function
> struct scaled_square {double operator()(double x, double a){a * x *
> x;} double gradient(double x, double a){return 2 * a * x;} }; //
> scaled quadratic
> double zero= find_root(square(), .1); //inlines everything.
> double zero = find_root(math_bind(scaled_square, _1, 1.0)); //Would
> uses the dynamic dispatching in boost::function since the math_bind
> creates a math_function object which has a boost::function
> double zero = find_root(math_function<double (double)>(_1 * _1, 2 *
> _1)); //constructs a new math_function... similar to previous line.
>
> Alternatively, if it is in a class:
> template <class F = math_function<double (double)> >
> class newton_root_finder
> {
> F f_;
>
> template<class G>
> newton_root_finder(const G& f) : f_(f) //Here it will construct
> the underlying object as required.
>
> double solve() { implement newton's method using f() and
> f.gradient() }
> };
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net