incomplete arguments to function pointers

I

Ian Malone

I've got a simple integration routine:
double integrate(double start, double end, double function(double));

Which integrates 'function' from start to end. I'm about to write
a (even more simplistic, since it takes independent limits)
2D version:

double integrate2d(double start[2], double end[2], double
function(double,double));

What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

Is this possible in C?
 
A

ajm

Hi Ian,
I've got a simple integration routine:
double integrate(double start, double end, double function(double));

Which integrates 'function' from start to end. I'm about to write
a (even more simplistic, since it takes independent limits)
2D version:

double integrate2d(double start[2], double end[2], double
function(double,double));

What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

first off some C details: define the third arg of "integrate" to be of
type

double (* function)(double)

and of integrate2d to be of type

double (* function)(double, double)

might be better to typedef some of these e.g.,

typedef double (*fn_2d_t ) (double, double)

and then use

double integrate2d(double start[2], double end[2], fn_2d_t my_function)

How precisely "integrate2d" invokes "integrate" is an algorithmic
question that really does not belong to this group (e.g., you use
evenly spaced points along one axis and approximate the cross section
function using interpolation, then pass then interpolated function to
"integrate" e.g., using Simpon's method or something - but there are
smarter ways e.g., suggest you read numerical receipes)

hth,
ajm.
 
A

Alexei A. Frounze

Ian Malone said:
I've got a simple integration routine:
double integrate(double start, double end, double function(double));

Which integrates 'function' from start to end. I'm about to write
a (even more simplistic, since it takes independent limits)
2D version:

double integrate2d(double start[2], double end[2], double
function(double,double));

What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

Is this possible in C?

Yes, but not very nice in terms of multithreading...
Here's the example of dumb integration in 1d and 2d (there are better
integration algorithms):

#include <stdio.h>
#include <math.h>

#define DELTAX 0.01
#define DELTAY 0.01

double My1DIntegrationFxn (double start, double end, double(*pFxn)(double
x))
{
double x, sum=0;
for (x=start; x<=end; x+=DELTAX)
sum += pFxn (x);
return sum * DELTAX;
}

static double _y;
static double(*_pFxn)(double x, double y);

static double WrapFxn (double x)
{
return _pFxn (x, _y);
}

double My2DIntegrationFxn (double start[2], double end[2],
double(*pFxn)(double x, double y))
{
double y, sum=0;
_pFxn = pFxn;
for (y=start[1]; y<=end[1]; y+=DELTAY)
{
_y = y;
sum += My1DIntegrationFxn (start[0], end[0], &WrapFxn);
}
return sum * DELTAY;
}

// returns the height of a cylinder;
// the height is 1/PI inside the circle of radius 10 and origin at x=y=0;
// the height is 0 elsewhere;
// the integral must equal to PI*(R**2) * (1/PI) = R**2 = 100
double My2DFxn (double x, double y)
{
double r = hypot (x, y);
if (r <= 10)
return 1. / 3.14159265359;
else
return 0;
}

int main()
{
double start[2] = {-10, -10};
double end[2] = {10, 10};
double res = My2DIntegrationFxn (start, end, &My2DFxn);
printf ("res: %10.3f\n", res);
return 0;
}

HTH
Alex
 
S

SM Ryan

# What I want to do is get it to call something like
# integrate(start[0],end[0], aux_function), where
# aux_function is the result of integrate on
# function(double,double) with one coordinate fixed.
#
# Is this possible in C?

C doesn't provide partial parameter lists. You can do this by
hand with a lot of extra work, but not automatically.
 
A

Alex Fraser

Ian Malone said:
I've got a simple integration routine:
double integrate(double start, double end, double function(double));

Which integrates 'function' from start to end. I'm about to write
a (even more simplistic, since it takes independent limits)
2D version:

double integrate2d(double start[2], double end[2], double
function(double,double));

What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

Is this possible in C?

Only by using global variables, eg:

double (*f)(double, double);
double d;

double aux_function(double x) {
return f(x, d);
}

Why not just use two nested loops in integrate2d()?

Alex
 
I

Ian Malone

ajm said:
Hi Ian,

I've got a simple integration routine:
double integrate(double start, double end, double function(double));

Which integrates 'function' from start to end. I'm about to write
a (even more simplistic, since it takes independent limits)
2D version:

double integrate2d(double start[2], double end[2], double
function(double,double));

What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

How precisely "integrate2d" invokes "integrate" is an algorithmic
question that really does not belong to this group (e.g., you use
evenly spaced points along one axis and approximate the cross section
function using interpolation, then pass then interpolated function to
"integrate" e.g., using Simpon's method or something - but there are
smarter ways e.g., suggest you read numerical receipes)

To clarify: my question is how to pass integrate the function pointer
it expects (taking one double) given a function pointer taking two
doubles (one of which is to be substituted by a constant).

For bonus points I then wanted to pass the resulting mess (a call to
integrate incorporating one set of limits and the magically retyped
function; now overall having one free parameter) to integrate again
(together with the second set of limits). Since it's only a quick
test to be run on particularly friendly functions it's simpler to
roll my own integrator here (using Simpson's rule).
 
I

Ian Malone

SM said:
# What I want to do is get it to call something like
# integrate(start[0],end[0], aux_function), where
# aux_function is the result of integrate on
# function(double,double) with one coordinate fixed.
#
# Is this possible in C?

C doesn't provide partial parameter lists. You can do this by
hand with a lot of extra work, but not automatically.

Okay, that's what I wanted to know, thanks.
 
I

Ian Malone

Alex said:
What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

Is this possible in C?


Only by using global variables, eg:

I thought that might be the case, thanks.
double (*f)(double, double);
double d;

double aux_function(double x) {
return f(x, d);
}

Why not just use two nested loops in integrate2d()?

Because then I'd have three separate copies of the integrator.

I think I'm going just to have make it recursive and
make integrate a call to integraten.
 
R

Richard Tobin

I've got a simple integration routine:
double integrate(double start, double end, double function(double));

Which integrates 'function' from start to end. I'm about to write
a (even more simplistic, since it takes independent limits)
2D version:

double integrate2d(double start[2], double end[2], double
function(double,double));

What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

Is this possible in C?

No, you can't "curry" functions in C.

You can of course package up the function and argument in a struct,
but the caller has to know what to do with it.

If your concern is to avoid duplicating integrate(), you could write a
function integrate_fn_or_closure() that's just like integrate() except
that it takes a struct containing either a function of one argument or
a function of two arguments and a value for one of them, along with a
flag to say which it is. The you would replace integrate() with a
wrapper that just calls integrate_fn_or_closure() with an appropriate
struct.

-- Richard
 
I

Ian Malone

Richard said:
I've got a simple integration routine:
double integrate(double start, double end, double function(double));

Which integrates 'function' from start to end. I'm about to write
a (even more simplistic, since it takes independent limits)
2D version:

double integrate2d(double start[2], double end[2], double
function(double,double));

What I want to do is get it to call something like
integrate(start[0],end[0], aux_function), where
aux_function is the result of integrate on
function(double,double) with one coordinate fixed.

Is this possible in C?


No, you can't "curry" functions in C.

You can of course package up the function and argument in a struct,
but the caller has to know what to do with it.

If your concern is to avoid duplicating integrate(), you could write a
function integrate_fn_or_closure() that's just like integrate() except
that it takes a struct containing either a function of one argument or
a function of two arguments and a value for one of them, along with a
flag to say which it is. The you would replace integrate() with a
wrapper that just calls integrate_fn_or_closure() with an appropriate
struct.

Thanks for your response. As it was I ended up doing writing the
function explicitly. I typically ask questions like this when I
come up against a minor problem with the aim of learning a new
technique. I like the struct suggestion, and 'curry' is a useful
keyword.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top