Nested function pointers or function composition - c

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?

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);

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

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 *.

Related

Passing another type to a function that takes a void pointer argument

I'm using the GNU Scientific Library which has functions that use void pointers as input. Example:
struct my_f_params { double a; double b; double c; };
double
my_f (double x[], size_t dim, void * p) {
struct my_f_params * fp = (struct my_f_params *)p;
if (dim != 2)
{
fprintf (stderr, "error: dim != 2");
abort ();
}
return fp->a * x[0] * x[0]
+ fp->b * x[0] * x[1]
+ fp->c * x[1] * x[1];
}
gsl_monte_function F;
struct my_f_params params = { 3.0, 2.0, 1.0 };
F.f = &my_f;
F.dim = 2;
F.params = &params;
I understand this to be defining my_f as a function that takes three arguments, one of which is the void pointer *p. My problem is instead of *p, I want to use a single variable which ranges from -5 to +5. The obvious thing to do is to use a for loop, but the following doesn't run:
float phi;
for (phi = -5.0; phi < 4.5; phi += 0.5) {
gsl_monte_function G = { &integrator, dim, phi };
[some code to tell the integrator to integrate]
}
The compiler complains that phi isn't a void pointer. The closest I got to fixing this was to try to convert the type, e.g. with *(float*)phi instead of phi, but it doesn't work - it returns an error saying "invalid cast from type ‘float’ to type ‘float*’". I tried Googling for this but nobody seems to have had this exact problem. What can I do other than repeat the code one time for each value of phi (which works but is very inelegant)?
I understand this to be defining my_f as a function that takes three arguments, one of which is the void pointer *p. My problem is instead of *p , I want to use a single variable which ranges from -5 to +5.
You must realize one thing: What *p is is a struct of 3 doubles, regardless of what you send. Look at your function definition. It is treated as a struct holding 3 doubles. This would be similar to something like this: double m[3]; as it would get casted properly to what you need.
So obviously just sending in phi as a float isn't going to cut it. The way to send it in as a parameter properly with casting is the following: (void *)&phi.
Here's a little example code to help you understand: Sample

Is it possible to write a function which returns a pointer to a function different from the function in its argument?

I have recently stumbled on this curious thought while handling a C code.
I have written a function which returns a double and takes in as argument the pointer to a function and a certain number of parameters, namely
double template_1(double (*)(double),...);
this function correctly identifies a certain property of a real function
double f(double );
represented as a pointer in template_1, in order to maketemplate_1 valid for every real function I might plug-in.
Now I had to write another function, let it be:
double derivative(double (*)(double),double);
double derivative(double (*f)(double),double x){
double epsilon = ...;
return ( f(x+epsilon)-f(x-epsilon) )/(2.0*epsilon);
}
again with f in the argument to make it work for every f.
My question is: since I would like to use derivative in template_1 without modifying it, is it possible to write a function which takes derivative and spits out something that has the form of double (*)(double ) ?
My idea was to define typedef double (*real_function)(double);
and then to define
real_function g(double (*derivative)(double (*)(double),double ) )
which I'd like it to spit out something like: double derivative_2(double x); so that I could define something like g(derivative) = double (*h)( double); directly in template_1 argument
unfortunately I don't have the faintest idea of how to make this work, or even if it can work.
There are a couple ways to do anonymous functions in C. As the comments said, they aren't portable. But depending on the use case you may find this useful: Anonymous functions using GCC statement expressions
A couple of people have seemed to have similar issues, not sure how portable they are but they may be resourceful:
https://github.com/graphitemaster/lambdapp
https://github.com/Leushenko/C99-Lambda
Basically, if there's a way to architect your program in a way that doesn't require anonymous functions, then do it that way. If you have no other option, then I would give one of these a shot.
Warning: I am a C++ developer with little C knowledge so everything that follows is likely unidiomatic C.
As KerrekSB said, you would need to carry some state with your function. This is not possible with raw functions but you can define a struct that carries the state and add a function that works with this struct. This obviously has the drawback of losing the nice function call syntax. I whipped up an example:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef double (*raw_fptr)(double);
struct real_function;
typedef double (*evaluate_function)(struct real_function*, double);
struct real_function {
evaluate_function evaluate;
};
typedef struct real_function real_function;
double evaluate(real_function *f, double x) {
if(f) {
return f->evaluate(f, x);
}
return NAN;
}
struct raw_real_function {
real_function real_function_base;
raw_fptr raw_function;
};
typedef struct raw_real_function raw_real_function;
double evaluate_raw_real_function(real_function *f_base, double x) {
if(f_base) {
raw_real_function *f = (raw_real_function*)f_base;
return f->raw_function(x);
}
return NAN;
}
raw_real_function make_raw_real_function(raw_fptr function) {
raw_real_function result;
result.raw_function = function;
result.real_function_base.evaluate = evaluate_raw_real_function;
return result;
}
struct derive_real_function {
real_function real_function_base;
real_function *function_to_derive;
};
typedef struct derive_real_function derive_real_function;
double derive(real_function *f_base, double x) {
derive_real_function *f = (derive_real_function*)f_base;
double epsilon = 1e-3;
double upper = evaluate(f->function_to_derive, x+epsilon);
double lower = evaluate(f->function_to_derive, x-epsilon);
double result = (upper - lower)/(2.0*epsilon);
return result;
}
derive_real_function make_derivative(real_function * function_to_derive) {
derive_real_function result;
result.real_function_base.evaluate = derive;
result.function_to_derive = function_to_derive;
return result;
}
double x_cubed(double x) {
return x * x * x;
}
int main(int argc, char **argv) {
raw_real_function x_cubed_wrapped = make_raw_real_function(x_cubed);
derive_real_function derived = make_derivative(&x_cubed_wrapped.real_function_base);
derive_real_function derived_twice = make_derivative(&derived.real_function_base);
double x = atof(argv[1]);
double derivative = evaluate(&derived.real_function_base, x);
double second_derivative = evaluate(&derived_twice.real_function_base, x);
printf("derivative of x^3 at %f = %f\n", x, derivative);
printf("second derivative of x^3 at %f = %f\n", x, second_derivative);
return 0;
}
See (a slight variaton, due to input limitations) running here.
How does it work? I faked some inheritance with the structs real_function, raw_real_function and derive_real_function to generate virtual function calls. The struct real_function serves as the container of a virtual function table consisting of only the entry evaluate. This function pointer points to the "derived" structs' relevant evaluate function:
raw_real_function instances point to evaluate_raw_real_function (as initialized in make_raw_real_function. derive_real_function instances point evaluate to derive (as initialized in make_derivative).
When calling evaluate on the real_function_base member, it will call the associated evaluation function, which casts the real_function* to it's associated struct pointer and does what is needed with that information.
Since everything is just a real_function*, we can chain them at will but need to convert "normal" functions into the real_function format, that's what make_raw_real_function does.
If you have a function my_fancy_function:
double my_fancy_function (double x) { return sin(x) + cos(x); }
Then, you can use a helper macro that creates the derived function for you.
#define DEFINE_DERIVATIVE_OF(FUNC) \
double derivative_of_ ## FUNC (double x) { \
return derivative(FUNC, x); \
}
DEFINE_DERIVATIVE_OF(my_fancy_function)
You then pass this newly defined function to your template.
template_1(derivative_of_my_fancy_function, x, y, z);

C Why function pointer as parameter instead of just a function?

I have been reading about having functions with functions as parameters, and particulary in C, they use function pointers. Let's suppose I want to implement the newton raphson method (in a simple way) for computing zeros in non linear equations.
double derivative(double f(double), double x)
{
double h = 1e-9;
return (f(x + h) - f(x)) / h;
}
double newton_raphson(double f(double), double x0, double tol)
{
double xk, diff;
do
{
xk = x0 - f(x0) / derivative(f, x0);
diff = fabs(xk - x0);
x0 = xk;
} while (diff >= tol);
return xk;
}
So, to compute an approximation for derivative I need a function that returns a double and takes a double as an argument. Same for computing a root of the function, given the other parameters. My question is, why is this different from declaring function parameters as function pointers? For instance declaring the input parameter f as a function pointer instead of just a function...
The parameter f is a pointer-to-function in both derivative and newton_raphson.
double derivative(double f(double), double x) { ... }
is exactly equivalent to
double derivative(double (*f)(double), double x) { ... }
Only, the former looks nicer - usually when you can omit parentheses, you should probably do so. After all both of them are equivalent to
double ((((derivative)))(double (((*(f))))(double ((trouble))), double ((x)))) { ... }
That I hope will only ever be used in IOCCC.
However, if you're declaring, defining a variable (not a function parameter), you need to use
double (*f)(double);
as
double f(double);
is just a function declaration.
6.7.6.3 Function declarators (including prototypes) of C11 draft n1570 says:
A declaration of a parameter as ‘‘function returning
type
’’ shall be adjusted to ‘‘pointer to
function returning
type
’’, as in 6.3.2.1.
And
6.9.1 Function definitions further says that
[...] the type of each parameter is adjusted as described in 6.7.6.3 for a parameter type list; the resulting type shall be a complete object
type.
additionally it has the following example:
EXAMPLE 2
To pass one function to another, one might say
int f(void);
/* ... */
g(f);
Then the definition of g might read
void g(int (*funcp)(void))
{
/* ... *
(*funcp)(); /* or funcp(); ... */
}
or, equivalently,
void g(int func(void))
{
/* ... */
func(); /* or (*func)(); ... */
}
Like normal data pointers, a function pointer can be passed as an argument and can also be returned from a function. A function’s name holds the address of function.
My question is, why is this different from declaring function parameters as function pointers? For instance declaring the input parameter f as a function pointer instead of just a function...
The answer is that both forms will be treated as same by compiler.
But for readibility of your code, go with the kind of declaration that your example code has, i.e.,
double derivative(double f(double), double x) { ... }
Even in C, the function definitions given below will be interpreted as same-
void foo(int a[]) // or int a[10]
{
...
}
void foo(int *a)
{
...
}

Using a scalar C function on a numpy vector

I have a library of C functions for scalars, e.g.
double f(double x, double y, double z) {
result = x + 2*y - 3*z;
return result;
}
I'd like to use these functions over numpy arrays, but would like to vectorise the operation somehow and avoid several C calls to f for each array element. Most examples that I have found are for functions that already support arrays (f(double *x) or f(double x[])).
What is the right approach here? Rewrite f to support arrays? (There are a lot of functions in the library.) Write a C wrapper, maybe using function pointers? Or do ctypes, cython, etc. offer a simpler alternative?
This has probably been asked hundreds of times, so even just a pointer to the appropriate documentation would be helpful.
Personally I'd say rewriting the functions to use arrays is the best and cleanest way to go. However, an alternative would be the already mentioned wrapper, but with using the original function as an inline function, e. g.
// Function
inline double f(double x, double y, double z) {
return x + 2*y - 3*z;
}
// Wrapper
void fWrapper(double *x, double *y, double *z, double *ret, int N) {
int i;
for (i = 0; i < N; i++) {
ret[i] = f(x[i], y[i], z[i]);
}
}
Now the compiler should replace the function call with the code of the function.

Function Arguments in C

I'm totally new to C. Here's the question:
Write the function
fzero(double f(double),double x1, double x2)
as we did in class and use it to find all the solutions of
sin( pi*x / (1+x^2) ) = 0.25.
Now, I don't want you to solve the this. I'd missed this lecture and only want to understand what means
double f(double);
In that context, it means that f is a function pointer to a function to that takes one double argument, and returns a double.
As an example:
void foo(double f(double))
{
double y = f(3.0); // Call function through function pointer
printf("Output = %f\n", y); // Prints "Output = 9.0000"
}
double square(double x)
{
return x*x;
}
int main(void)
{
foo(&square); // Pass the address of square()
}
Note that there are two syntaxes for function pointers:
void foo(double f(double))
void foo(double (*f)(double))
These are equivalent.

Resources