Skander J.
Skander J.

Reputation: 33

Nested function pointers or function composition

I am working on C implementations of calculus operations (such as derivatives, integrals, etc...). As an example, here's the template definition of my derivative function:

double derivative(double (*f)(double), double x);

Let's say I want to compute the derivative of exp at 1, the call would then be: derivative(exp, 1);

Pretty basic stuff. Now my question is, how would I go about (if it is even possible) to pass a composition to my derivative function? I tried passing exp(cos) which got me

error: passing 'double (double)' to parameter of incompatible type 'double'.

How would I do it? Is it even possible?

Upvotes: 0

Views: 279

Answers (3)

Ian Abbott
Ian Abbott

Reputation: 17438

If you want some sort of run-time control over the composition, you could write a function that evaluates an array of function pointers as a composition:

// calls functions in reverse order
double compose(size_t n, double (* const fc[])(double), double x)
{
    while (n--)
    {
        x = fc[n](x);
    }
    return x;
}

This could be called from another version of your derivative function:

double derivative_composed(size_t n, double (* const fc[])(double), double x)
{
    // Example implementation for illustrative purpose only.
    double fx, fxh, h;
    h = x / 1e10;
    if (h == 0)
    {
        h = 1e-10;
    }
    fx = compose(n, fc, x);
    fxh = compose(n, fc, x + h);
    return (fxh - fx) / h;
}

To avoid repeated code, your original derivative function could be changed to be a wrapper that calls derivative_composed with a single function:

double derivative(double (* const f), double x)
{
    return derivative_composed(1, &f, x);
}

Example usage:

int main(void)
{
    double (* const fc[2])(double) = { exp, cos };
    double x = 1.0;
    double xprime = derivative_composed(2, fc, x);
    printf("x = %f, xprime = %f\n", x, xprime);
}

Output:

x = 1.000000, xprime = -1.444407

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 223264

C does not have any operation for function composition. To compute the derivative of exp∘cos, you can define a function expcos:

double expcos(double x) 
{
    return exp(cos(x));
}

and take the derivative of that.

For a more general solution, you could modify your derivative routine to take both a function pointer and a const void * to forward to the function. The function would take the const void * as a parameter, convert it to a pointer to a const structure of a type particular to that function, and take data from that structure. Then function composition can be implemented with a compose function that uses a structure containing two function pointers. However, it would mean you would need to use proxy routines for ordinary functions like exp and cos that accept but ignore the const void *.

Upvotes: 1

ikegami
ikegami

Reputation: 386331

I think you're asking for this:

double composition(double x) {
   return exp(cos(x));
}

derivative(composition, 1);

Many languages allow you to do something like the following, but C doesn't have anon functions:

derivative(x => exp(cos(x)), 1);

Upvotes: 2

Related Questions