[R] compile error with C code and standalone R math C library
Faheem Mitha
faheem at email.unc.edu
Sun Dec 14 01:44:46 CET 2003
Dear People,
I just went back to an old piece of C code. On trying to compile it with
the R math standalone C library I got the following error. Can anyone
enlighten me what I am doing wrong, if anything? C file (rr-sa.c) follows.
I'm on Debian sarge. I'm running R version 1.8.1. Gcc is version
3.3.1.
Thanks in advance.
Faheem.
**********************************************************************
faheem ~/co/rr/trunk>gcc -o rr rr-sa.c -lRmath -lm
/usr/lib/gcc-lib/i486-linux/3.3.2/../../../libRmath.so: undefined
reference to `Rlog1p'
collect2: ld returned 1 exit status
**********************************************************************
rr-sa.c
**********************************************************************
#include <stdio.h>
#include <assert.h>
#define T 3
#define INITVAL 1
#define MATHLIB_STANDALONE
#define THETA 2
#include <Rmath.h>
#include <time.h>
void advance(double *node, int *current_pos, double newval);
void retreat(double *node, int *current_pos);
double new_val(double *node, double theta, int current_pos);
double accept_prob(double *node, double theta, int current_pos);
double accept_prob_fn(double a, double y);
int main()
{
int currentpos = 0;
int i;
double newval, node[T+2], theta = THETA, p, u;
set_seed(time(NULL), clock());
node[0]=0;
for(i=1;i<=T;i++)
node[i]= INITVAL; /* for simplicity choose all values the same */
node[T+1]=0;
for(i=0; currentpos < T; i++)
{
u = unif_rand();
newval = new_val(node, theta, currentpos);
p = accept_prob(node, theta, currentpos);
printf("current position is %u\n",currentpos);
printf("uniform random variable determining acceptance/rejection is %g\n",u);
printf("value of acceptance probability is %g\n",p);
printf("value of proposed new variable is %g\n",newval);
if(u < p)
advance(node,¤tpos,newval);
else
retreat(node, ¤tpos);
}
for(i=1;i <= T; i++)
printf("value of node %u is %g\n",i,node[i]);
return 0;
}
/* function that moves chain one step forward in the event of an
acceptance */
void advance(double *node, int *current_pos, double newval)
{
*current_pos = *current_pos + 1;
node[*current_pos] = newval;
}
/* function that moves the chain backwards in the event of a rejection*/
void retreat(double *node, int *current_pos)
{
/* need special handling for small values of current_pos */
if(*current_pos >= 1)
*current_pos = *current_pos - 1;
else if(*current_pos == 0)
; /* do nothing, already at beginning */
}
/* generate new candidate value with appropriate distribution */
double new_val(double *node, double theta, int current_pos)
{
double a, u, y;
u = unif_rand();
a = node[current_pos] + node[current_pos+2];
if (a != 0)
y = (1/a)*log( ( exp(a*theta) - exp(-a*theta) )*u + exp(-a*theta) );
else /* degenerate case (for a=0) is Unif[-theta,theta] */
y = 2*theta*u - theta;
return y;
}
/* generate acceptance probabilities for candidates*/
/* NB: This assumes:
(a) That all the initial values of the starting state are set to -1
(b) That theta > 1.
*/
double accept_prob(double *node, double theta, int current_pos)
{
double a, p, y, num, denom, leftval, rtval;
a = node[current_pos + 1];
y = node[current_pos] + node[current_pos+2];
num = accept_prob_fn(a, y);
leftval = accept_prob_fn(a, -theta + node[current_pos+2]);
rtval = accept_prob_fn(a, theta + node[current_pos+2]);
denom = fmax2(leftval, rtval); /* function in Rmath which returns
max of two doubles */
p = num/denom;
assert(p>=0 && p <=1);
return p;
}
/* auxilary function for accept_prob */
double accept_prob_fn(double a, double y)
{
double f;
if(y != 0)
f = (exp(y) - exp(-y))/(y*exp(a*y));
else
f = 2;
return f;
}
More information about the R-help
mailing list