The code below uses a recursive function called interp, but I cannot find a way to avoid using global variables for iter and fxInterpolated. The full code listing (that performs N-dimensional linear interpolation) compiles straightforwardly with:
gcc NDimensionalInterpolation.c -o NDimensionalInterpolation -Wall -lm
The output for the example given is 2.05. The code works fine but I want to find alternatives for the global variables. Any help with this would be greatly appreciated. Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int linearInterpolation(double *, double **, double *, int);
double ** allocateDoubleMatrix(int, int);
double * allocateDoubleVector(int);
void interp(int, int, double *, double *, double *);
double mult(int, double, double *, double *);
/* The objectionable global
variables that I want to get rid of! */
int iter=0;
double fxInterpolated=0;
int main(int argc, char *argv[]){
double *fx, **a, *x;
int dims=2;
x=allocateDoubleVector(dims);
a=allocateDoubleMatrix(dims,2);
fx=allocateDoubleVector(dims*2);
x[0]=0.25;
x[1]=0.4;
a[0][0]=0;
a[0][1]=1;
a[1][0]=0;
a[1][1]=1;
fx[0]=1;
fx[1]=3;
fx[2]=2;
fx[3]=4;
linearInterpolation(fx, a, x, dims);
printf("%f\n",fxInterpolated);
return (EXIT_SUCCESS);
}
int linearInterpolation(double *fx, double **a, double *x, int dims){
double *b, *pos;
int i;
b=allocateDoubleVector(dims);
pos=allocateDoubleVector(dims);
for (i=0; i<dims;i++)
b[i] = (x[i] - a[i][0]) / (a[i][1] - a[i][0]);
interp(0,dims,pos,fx,b);
return (EXIT_SUCCESS);
}
void interp(int j, int dims, double *pos, double *fx, double *b) {
int i;
if (j == dims){
fxInterpolated+=mult(dims,fx[iter],pos,b);
iter++;
return;
}
for (i = 0; i < 2; i++){
pos[j]=(double)i;
interp(j+1,dims,pos,fx,b);
}
}
double mult(int dims, double fx, double *pos, double *b){
int i;
double val=1.0;
for (i = 0; i < dims; i++){
val *= fabs(1.0-pos[i]-b[i]);
}
val *= fx;
printf("mult val= %f fx=%f\n",val, fx);
return val;
}
double ** allocateDoubleMatrix(int i, int j){
int k;
double ** matrix;
matrix = (double **) calloc(i, sizeof(double *));
for (k=0; k< i; k++)matrix[k] = allocateDoubleVector(j);
return matrix;
}
double * allocateDoubleVector(int i){
double *vector;
vector = (double *) calloc(i,sizeof(double));
return vector;
}
Thanks for the comments so far. I want to avoid the use of static. I have removed the global variable and as suggested tried parsing with the iter variable. But no joy. In addition I am getting a compile warning: "value computed is not used" with reference to *iter++; What am I doing wrong?
void interp(int j, int dims, double *pos, double *fx, double *b, int *iter) {
int i;
if (j == dims){
fxInterpolated+=mult(dims,fx[*iter],pos,b);
*iter++;
return;
}
for (i = 0; i < 2; i++){
pos[j]=(double)i;
interp(j+1,dims,pos,fx,b,iter);
}
}
There are two approaches I would consider when looking at this problem:
Keep the state in a parameter
You could use one or more variables that you pass to the function (as a pointer, if necessary) to keep the state across function calls.
For instance,
int global = 0;
int recursive(int argument) {
// ... recursive stuff
return recursive(new_argument);
}
could become
int recursive(int argument, int *global) {
// ... recursive stuff
return recursive(new_argument, global);
}
or sometimes even
int recursive(int argument, int global) {
// ... recursive stuff
return recursive(new_argument, global);
}
Use static variables
You can also declare a variable in a function to be preserved across function calls by using the static
keyword:
int recursive(int argument) {
static int global = 0;
// ... recursive stuff
return recursive(argument);
}
Note that because of the static
keyword, global = 0
is only set when the program starts, not every time the function is called, as it would be without the keyword. This means that if you alter the value of global
, it would keep this value the next time the function is called.
This method can be used if you only use your recursive function once during your program; if you need to use it multiple times, I recommend that you use the alternative method above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With