Re: c++ Newton-Raphson problem
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:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34