I have a C question, which looks very easy, but no one here seems to
know an easy answer.
I have a function "powell" (from Numerical Recipes) which takes an
argument of the type
"double (*f)(float[])"
But I want to be able to pass a
"double (*f)(float[], double)"
instead, where minimization is with respect to the the first argument
and
the second argument is a parameter.
Below is a very easy version of the problem.
// Problem: Minimize function with additional parameters
// function you want to minimize, example below is trivial
// and 1 dimensional
double g(float x[],double a)
{ return (x[1]+a)*(x[1]+a); }
// so minimization should result in x[1]=-a.
int main (void)
{
//define other parameters required for the function powell
int n=1;
float *p,**xi;
p=vector(1,n);
p[1]=0.2;
xi=matrix(1,n,1,n);
xi[1][1]=1;
float ftol=0.000001;
int iter=0;
float fret;
double a=(double) rand();
//How to pass the parameter a into the minimization function powell.
//While the parameter a is defined during the running time.
//i.e., one likes to enter g(.,a) in te function
powell(p,xi,n,ftol,&iter,&fret, );
//where the last argument should be a function of the required form
}
Any help is appreciated.
Martin 6 2131
In article <11*********************@m38g2000cwc.googlegroups. com>,
Martin Bootsma <ma***********@gmail.comwrote:
> I have a function "powell" (from Numerical Recipes) which takes an argument of the type
"double (*f)(float[])"
But I want to be able to pass a
"double (*f)(float[], double)"
.... for example:
>double g(float x[],double a) { return (x[1]+a)*(x[1]+a); }
Change powell() to make it accept a parameter which it
will pass to the function f.
Therefore, let:
typedef double (*ObjFunc)(float[], double *);
and change powell's declaration to:
int powell(whaterver, ObjFunc f, double param);
Then within the definition of powell(), change all calls to
f(x) to f(x, param).
Now you can call powell() as:
powell(whatever, g, 3.14);
--
Rouben Rostamian
Martin Bootsma wrote:
I have a C question, which looks very easy, but no one here seems to
know an easy answer.
I have a function "powell" (from Numerical Recipes) which takes an
argument of the type
"double (*f)(float[])"
But I want to be able to pass a
"double (*f)(float[], double)"
instead, where minimization is with respect to the the first argument
and
the second argument is a parameter.
Below is a very easy version of the problem.
// Problem: Minimize function with additional parameters
// function you want to minimize, example below is trivial
// and 1 dimensional
double g(float x[],double a)
{ return (x[1]+a)*(x[1]+a); }
// so minimization should result in x[1]=-a.
int main (void)
{
//define other parameters required for the function powell
int n=1;
float *p,**xi;
p=vector(1,n);
p[1]=0.2;
xi=matrix(1,n,1,n);
xi[1][1]=1;
float ftol=0.000001;
int iter=0;
float fret;
double a=(double) rand();
//How to pass the parameter a into the minimization function powell.
//While the parameter a is defined during the running time.
//i.e., one likes to enter g(.,a) in te function
powell(p,xi,n,ftol,&iter,&fret, );
//where the last argument should be a function of the required form
}
Do you mean something like this ...
float lastArg(float fa[], double d)
{
...
}
float (*func)(float [], double) = lastArg;
powell(p, xi, n, ftol, iter, fret, func);
--
==============
Not a pedant
==============
"Martin Bootsma" <ma***********@gmail.comwrote in message
news:11*********************@m38g2000cwc.googlegro ups.com...
>I have a C question, which looks very easy, but no one here seems to
know an easy answer.
I have a function "powell" (from Numerical Recipes) which takes an
argument of the type
"double (*f)(float[])"
But I want to be able to pass a
"double (*f)(float[], double)"
instead, where minimization is with respect to the the first argument
and the second argument is a parameter.
You can't do that without modifying the "powell" function to accept the
value of the extra parameter, to have the correct function pointer type
parameter, and to pass the extra parameter to the function.
A common, generic solution for functions that have a function pointer
parameter is for them to have an additional parameter of type void *, which
is passed to the callback function (often as the first argument). For
example:
void powell(/* ..., */ double (*f)(void *, float *), void *vp) {
/* ... */
f(vp, pointer_to_float);
/* ... */
}
double g(void *vp, float *x) {
double *pa = vp;
double a = *pa;
return (x[1] + a) * (x[1] + a);
}
In the calling code:
double a = some_value;
powell(/* ..., */ g, &a);
Without modifying the "powell" function, your only option is to use a
global, eg:
double a;
double g(float *x) {
return (x[1] + a) * (x[1] + a);
}
Then do:
a = some_value;
powell(/* ..., */ g);
Alex
Thanks all, I was hoping there was some kind of function that would
produce the equivalent of the mathematical notation
f(.)=g(.,a)
so that I could call powell with the function f in it, but according to
the reactions, there is no clever way to arrange this. I am going to
change the powell code to make the minimization possible.
Martin Bootsma wrote:
Thanks all, I was hoping there was some kind of function that would
produce the equivalent of the mathematical notation
f(.)=g(.,a)
so that I could call powell with the function f in it, but according to
the reactions, there is no clever way to arrange this. I am going to
change the powell code to make the minimization possible.
One other possibility, not especially attractive but
perhaps expedient, is to pass the "parameter" to f() by
storing its value in a static variable:
static double fake_param;
double f(float vector[]) {
return vector[0] + vector[1] * fake_param;
}
...
fake_param = a;
powell (f);
...
--
Eric Sosman es*****@acm-dot-org.invalid
In article <11**********************@m79g2000cwm.googlegroups .com>,
Martin Bootsma <ma***********@gmail.comwrote:
>Thanks all, I was hoping there was some kind of function that would produce the equivalent of the mathematical notation
f(.)=g(.,a)
so that I could call powell with the function f in it, but according to the reactions, there is no clever way to arrange this. I am going to change the powell code to make the minimization possible.
The equivalent of setting f(.)=g(.,a) is a central feature
of functional programming languages such as Lisp, where the
process of creating the function f out g is known as "currying".
Unfortunately currying is not possible in the current version
of C where functions do not have first class object status.
Let's hope that in some future version of C this will become
possible.
--
Rouben Rostamian This discussion thread is closed Replies have been disabled for this discussion. Similar topics
220 posts
views
Thread by Brandon J. Van Every |
last post: by
|
2 posts
views
Thread by Pernell Williams |
last post: by
|
1 post
views
Thread by Xiangliang Meng |
last post: by
|
3 posts
views
Thread by notme |
last post: by
|
36 posts
views
Thread by Peng Jian |
last post: by
|
53 posts
views
Thread by Jeff |
last post: by
|
30 posts
views
Thread by questions? |
last post: by
|
6 posts
views
Thread by pookiebearbottom |
last post: by
|
4 posts
views
Thread by Belebele |
last post: by
| | | | | | | | | | |