cmmnn
cmmnn

Reputation: 325

Pointer to function with some, but not all arguments fixed

I want to use Brents method as present in the Numerical Recepies Book to minimize a function. The signature of the minimzation routine essentially looks like this:

float brent(float (*f)(float), float *xmin, "other parameters not relevant to question")

As you can guess brent returns the minimum value of f and stores its argument in xmin. However, the exact form of the function I want to minimize depends on additional parameters. Say

float minimize_me(float x, float a, float b)

Once I decided on the values of a and b I want to minimize it with respect to x.

I could simply add additional arguments to all functions called, all the way down to brent, thus changing its signature to

float brent(float (*f)(float,float,float),float a ,float b , float *xmin, ...)

and consequently call (*f)(x,a,b) inside brent every time. This, however, seems not really elegant to me since I would now have to pass not only the pointer to minimize_me, but also two additional parameters down a whole chain of functions.

I suspect there could be a more elegant solution, like creating a pointer to a version of the function with a and b as fixed values.

Even if it is a really obscure solution, please don't keep it from me, since I feel it could improve my overall understanding of the language.

Upvotes: 5

Views: 343

Answers (3)

Nefrin
Nefrin

Reputation: 338

A viable way of achieving this is to use a struct to store all the values and pass a pointer to that to the function.

struct parameters{
    int valueA;
    int valueB;
};

int function(void* params){
    parameters* data = (parameters*) params;
    return data->valueA + data->valueB; // just an example
}

int main(){
    parameters myData;
    myData.valueA = 4;
    myData.valueB = 2;
    function(&myData);
    return 0;
}

Upvotes: 6

Jean-Baptiste Yunès
Jean-Baptiste Yunès

Reputation: 36441

What you need is currying, say for example:

given a function of three variables f(x,y,z) and two values a and b, construct the function g of one variable such that g(z)=f(a,b,z).

Alas C language is not able to let you currying. Such a construction is available to functional languages only and C is not one. This doesn't mean that you really can't do it, but there is no given construction for it in the language. So you need to reconstruct the mechanism by yourself. See Currying/binding with ISO C99 or Is there a way to do currying in C? for examples.

Upvotes: 5

Uprooted
Uprooted

Reputation: 971

GCC's local functions extension is a pure joy to use (use -std=gnu11):

float brent(float (*f)(float), float *xmin);

float minimize_me(float x, float a, float b);

int main() {
   ...
   float min_me_local(float x) { return minimize_me(x, 1, 2); }
   brent(min_me_local, xmin);
   ...
}

I wish it was standard, but it isn't. So prefer answer from @Nefrin when aiming at portability.

Upvotes: 1

Related Questions