435,619 Members | 1,712 Online + Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,619 IT Pros & Developers. It's quick & easy.

c++ Newton-Raphson problem

 P: n/a Let double NR( double x, double(*)(const double&) f ) be the signature of a Newton-Raphson function NR. Here, f is a function which returns a double and accepts a const double&. The aim of the game is to find a zero of this function f (the point at which f crosses the x-axis). This zero-of-f which solves our problem is the double which NR returns. It remains to explain what the "double x" represents. This is the starting-guess that is required in Newton-Raphson implementations. In my case, I have the following amended Newton-Raphson situation. I have a function of the form double MyFunc(double x1, double x2, double x3, double x4, double x5) I want to solve the following problem: Fix x1, x2, x3, and x4. Then use Newton Raphson to return the double y such that MyFunc(x1, x2, x3, x4, y) = 0. I was unable to find a way of using the ready-made function NR because it assumes f accepts 1 double and returns 1 double, whereas My Func accepts 5 doubles and returns 1 double. My very-inelegant solution was to copy-paste the NR code and adapt it so that the pointer-to-function parameter was of the type I needed. Is there a more elegant approach that calls on the NR function already present? Thank for your help. Paul Epstein Nov 15 '08 #1
6 Replies

 P: n/a pa**********@att.net wrote: Let double NR( double x, double(*)(const double&) f ) be the signature of a Newton-Raphson function NR. Here, f is a function which returns a double and accepts a const double&. The aim of the game is to find a zero of this function f (the point at which f crosses the x-axis). This zero-of-f which solves our problem is the double which NR returns. It remains to explain what the "double x" represents. This is the starting-guess that is required in Newton-Raphson implementations. In my case, I have the following amended Newton-Raphson situation. I have a function of the form double MyFunc(double x1, double x2, double x3, double x4, double x5) I want to solve the following problem: Fix x1, x2, x3, and x4. Then use Newton Raphson to return the double y such that MyFunc(x1, x2, x3, x4, y) = 0. I was unable to find a way of using the ready-made function NR because it assumes f accepts 1 double and returns 1 double, whereas My Func accepts 5 doubles and returns 1 double. My very-inelegant solution was to copy-paste the NR code and adapt it so that the pointer-to-function parameter was of the type I needed. Is there a more elegant approach that calls on the NR function already present? I would change NR into a template: template < typename Float, typename Func > Float find_zero ( Float initial_guess, Func f ); Then, you could use bind() from c++0x or Boost to fix the first four arguments and pass the resulting function object into the template. Best Kai-Uwe Bux Nov 15 '08 #2

 P: n/a On Nov 15, 9:53*am, pauldepst...@att.net wrote: Let double NR( double x, double(*)(const double&) f ) *be the signature of a Newton-Raphson function NR. Here, f is a function which returns a double and accepts a const double&. The aim of the game is to find a zero of this function f (the point at which f crosses the x-axis). This zero-of-f which solves our problem is the double which NR returns. It remains to explain what the *"double x" represents. This is the starting-guess that is required in Newton-Raphson implementations. In my case, I have the following amended Newton-Raphson situation. *I have a function of the form double MyFunc(double x1, double x2, double x3, double x4, double x5) I want to solve the following problem: *Fix x1, x2, x3, and x4. *Then use Newton Raphson to return the double y such that MyFunc(x1, x2, x3, x4, y) = 0. I was unable to find a way of using the ready-made function NR because it assumes f accepts 1 double and returns 1 double, whereas My Func accepts 5 doubles and returns 1 double. That's because the interface to the existing NR function is very poorly designed. In C++, the "standard" solution for any callback would be: class NRCallBack { public: virtual ~NRCallBack() {} virtual double operator()( double ) const = 0 ; } ; So the signature of NR would be: double NR( double x, NRCallBack const& f ) ; Rather than providing a function, you then derive from NRCallBack, and define the appropriate operator. In your precise case, it's probably a bit wordy, because we don't have lambda classes, and you'd have to do something like: double NRforMyFunc( double x1, double x2, double x3, double x4 ) { class F : public NRCallBack { public: NRCallBack( double x1, double x2, double x3, double x4 ) : x1( x1 ) , x2( x2 ) , x3( x3 ) , x4( x4 ) { } virtual double operator()( double x ) const { return MyFunc( x1, x2, x3, x4, x ) ; } private: double x1 ; double x2 ; double x3 ; double x4 ; } ; return NR( 0.0, F() ) ; } If (as may be the case), NR is in fact a C function, and must be callable from C, the established convention is to pass an additional void* with user data, i.e.: double NR( double x, double (*f)( double, void* ), void* ) ; Again, you have to write a wrapper function which takes the additional, fixed values as a void*, move these values into an array, and pass the address of the array to NR. My very-inelegant solution was to copy-paste the NR code and adapt it so that the pointer-to-function parameter was of the type I needed. You may end up having to do this, if it's interface is broken. Is there a more elegant approach that calls on the NR function already present? Depending on the context of what you're doing, you may be able to use static variables and a wrapper function. IMHO, it's playing with fire, however, and you'd be better off rewriting the function to use one of the above interfaces, depending on whether it is pure C++, or it must be callable from C as well. -- James Kanze (GABI Software) email:ja*********@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 Nov 15 '08 #3

 P: n/a On Nov 15, 10:26*am, Kai-Uwe Bux * Float find_zero ( Float initial_guess, Func f ); Then, you could use bind() from c++0x or Boost to fix the first four arguments and pass the resulting function object into the template. This is a very elegant solution for a few special cases, but it results in an infection template; if the call to this function is in a function which receives the callback function as an argument, that function must be a template as well. And so on, add infitum; depending on the use pattern, you can very quickly end up with an unmanageable mess, where all of your functions are templates. (This might be workable if your compiler supports export, but not many do.) -- James Kanze (GABI Software) email:ja*********@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 Nov 15 '08 #4 