
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
(_1 * _1, 2 * _1)); //constructs a new math_function... similar to previous line. Alternatively, if it is in a class: template
> 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@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users