adventures in root finding

Hi! :)

The following Numerical Recipes code provides a structure that returns the value of function and its derivative by overloading 'operator()'.
1
2
3
4
5
6
7
8
struct funcD {
	double operator() (const double x) {
                return f=f(x);
        }
				
	double df(const double x){		
		return df=fx(x);
}

An instance of the structure is used in a root finding routine that iteratively calls it.
1
2
3
4
5
6
7
8
9
double rtnewt(&funcd,...) {
       ...
       for (Int j=0;j<jMax; j++) {
              double f=func(rtn)
              double df=func.df(rtn)
              ...
              rtn=...
       }
}


I want to use quantities that I compute in the calculation of f to be available in the computation of df, while keeping the efficiency of the above code. I tried to using a function, funcd, (instead of a structure) in which I update an instance of a structure with structure elements struct.f and struct.df upon each call. I got stuck with a compiler error (http://www.cplusplus.com/forum/beginner/57273/ didn't get an answer) so I thought I'd ask around to see if it's worth pursuing that or if there's a better way. I'm kinda new at this but I thought I'd put this post here instead of in the beginners section because the content is non-beginner.

Thanks!

Max
Presumably the quantities computed when calculating f() which are to be made available to the calculation of df() must be for the same function argument?

You could just put the quantities in the funcD structure but this is very poor and introduces a nasty order dependency in that you must call f() first with the same argument before you call df()

A clean way would be to introduce a third function 'f_n_df' which provides you with both values. but this is kind of ugly in its own way.

If the algorithm always calls for df() as well as f(), I would be inclined to make df() take no parameter, then f(x) can set all the state it wants, and df() returns the derivative at the same point. Eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct funcD {
  double operator() ( const double x ) {
    a = x+1;
    b = x - 1;
    current_x = x;
    return f(x);
  };

  double df(void) {
    // use a and b here etc
    return fx(current_x);
  }

  private:
    double a, b, current_x;
};


Alternatively, if df(x) is used more often than f(x), then flip the parameters around.
Last edited on
Topic archived. No new replies allowed.