Help 2 Update old C-Routine


C

Chris Lupus

Hi,

in a book I found an old C-Routine that I would like to run:
#v+
/* C-Program for kernel density estimation
* Interface : fun = kernel function
* data = vector of observations
* n = number of observations
* grid = vector with gridpoints
* fh = vector with estimates
* kernel = number of kerneltype between 1 and 6
* 1 = Uniform , 2 = Triangle
* 3 = Epanechnikov , 4 = Quartic
* 5 = Triweight , 6 = Gaussian
* 7 = Cosinus
* h = bandwidth of the kernel estimation
* points = number of gridpoints where the
* estimation should be calculated
* range = minimum and maximum of data */

#include <stdio.h>
#include <math.h>
static void *func;
/* pointer for the R-function */

kernelestimation(fun,data,n,grid,fh,kernel,h,points,range)
void **fun;
double *data,*grid,*fh,*h,*range;
long *n,*kernel,*points;
/* Note the use of void **, since we have sent a list to C */
{
double gridmin,step,nh;
long i,j,k1,k2;
nh=h[0]*(double)n[0];
func=fun[0];

/* left of boundary of grid */

gridmin=range[0]-h[0];

/* interval between two following points on the grid */

step=(2.0*h[0]+range[1]-range[0])/(double)(points[0]-1);

/* grid */

for (j=0;j<points[0];j++)
{
grid[j]=gridmin+step*(double)j;
}

/* now the kernel function is set around each gridpoint */

if (kernel[0]==6)
{
for(i=0;i<n[0];i++)
{
for (j=0;j<points[0];j++)
{
fh[j]+=sfun((grid[j]-data)/h[0])/nh;
}
}
}
else
/* Except for the Gaussian kernel (kernel[0]=6)
* the kernel weights are only positive in an
* interval fixed by the indices k1 and k2 */

{
for (i=0;i<n[0];i++)
{
k1=ceil((data-h[0]-gridmin)/step);
k2=floor((data+h[0]-gridmin)/step);
for (j=k1;j<(k2+1);j++)
{
fh[j]+=sfun((grid[j]-data)/h[0])/nh;
} /* endj */
} /* endi */
} /* endif */
return(0);
} /* end */

/* The following part contains the call of our R-function */

static double sfun(z)
double z;
{
void *args[1],*values[1];
double zz[1],*result;
char *mode[1];
long length[1];
mode[0]="double";
length[0]=1;
args[0]=(void *)(zz);
zz[0]= z;

call_R(func, 1L, args, mode,length,0,1L,values);
result=(double *)values[0];
return(result[0]);
}
#v-
I used on gcc4.1.3:
gcc -lm -shared -o kde.so kde.c
and got the following errors:
kde.c:82: error: typs in conflict for »sfun«
kde.c:56: error: Implicit declaration of »sfun« was here

ANY IDEAS?

My major R function is
#v+
kde <- function(data,kernel,h,points)
{
# kernel density estimation use C-code
# which employs selected R-function
# select function
switch(kernel,
fun <- uniform,
fun <- triangle,
fun <- epanechnikov,
fun <- quartic,
fun <- triweight,
fun <- gaussian,
fun <- cosinus)
data <- data[!is.na(data)]
n <- length(data)
dyn.load("kde.so")
#Use list() to send a function to C
result <- .C("kernelestimation",
list(fun),
as.double(data),
as.integer(n),
double(points),
double(points),
as.integer(kernel),
as.double(h),
as.integer(points),
as.double(range(data))
final.result <- matrix(c(result[[4]], result[[5]]),points,2)
final.result
}
#v-
and here is a link to a call_R-article:
http://www.stat.berkeley.edu/classes/s243/call_R.pdf

Hope that someone can help.

Ciao
Chris
 
Ad

Advertisements

S

Stephen Sprunk

Chris said:
Hi,

in a book I found an old C-Routine that I would like to run:
...
fh[j]+=sfun((grid[j]-data)/h[0])/nh;
...
fh[j]+=sfun((grid[j]-data)/h[0])/nh;
...
static double sfun(z)
double z;
{
...
}
#v-
I used on gcc4.1.3:
gcc -lm -shared -o kde.so kde.c
and got the following errors:
kde.c:82: error: typs in conflict for »sfun«
kde.c:56: error: Implicit declaration of »sfun« was here

ANY IDEAS?


The problem that gcc is complaining about is that the implicit
declaration of sfun() disagrees with the explicit declaration. You have
an implicit declaration because you used the function before you
declared it. The simple solution is to add this line near the top of
the file:

static double sfun(double z);


S
 
K

Kaz Kylheku

Hi,

in a book I found an old C-Routine that I would like to run:

It's a good idea to structure C programs such that function definitions precede
their uses. This way you don't have to waste effort by writing redundant
forward declarations.

I.e like this:

void function(void)
{
}

int main(void)
{
function(); /* above defintion declares the function */
return 0;
}

Not like this:

void function(void); /* necessary, but wasteful redundancy */

int main(void)
{
function(); /* depends on declaration above, not defintion below */
return 0;
}

void function(void)
{
}

If you forget the declaration, then the function call is still allowed without
a required diagnostic (in the 1990 standard C dialect that is still in
predominant use). The 1999 version of the C standard requires a diagnostic, and
you got one from gcc.

Whether or not you get a diagnostic for this, the behavior is still undefined
if the implicit declaration does not match the function.

If we forget the declaration that precedes main, then the call

function();

means ``assume that the function is: int function(void) ''.

The assumption about the number of parameters is correct, but the assumption
about the return type is not. The function in fact returns nothing. So the
call is mismatched with the definition---oops!

You should fix this program to use modern C declarations (and by modern I mean
newer than the middle 1980's, when ANSI C started to be used!) and structure it
so that every function is defined prior to calls to that function.

Use -Wall -ansi -pedantic when compiling your program with gcc, and fix every
diagnostic.
 
C

Chris Lupus

Thank you all for your advices!
It's working fine now. Also the dynamic loading
of the C-Routine into R incl. R_call from C works.
Thanx god because the original code was S. There are
also some slight differences to R that I had to work on.
Yeah, the code from the book is really old
-- nearly 20 years. But for me it was the easiest way
to plot my kde. Thanks again.

Ciao
Chris
 
Ad

Advertisements

Ad

Advertisements


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

Top