[R] Use of 'defineVar' and 'install' in .Call

Daniel Berg daniel at danielberg.no
Tue Mar 27 10:56:45 CEST 2007


Dear all,

[system and version information below]

I am trying to modify a C function for finding the root of an
expression. The function is to be called from R as .Call with input
parameters:

f: expression for which we will find the root
guesses: interval for the solution
stol: tolerance
rho: environment

The original functions I use are:

SEXP mkans(double x) {
  SEXP ans;
  PROTECT(ans = allocVector(REALSXP, 1));
  REAL(ans)[0] = x;
  UNPROTECT(1);
  return ans;
}
double feval(double x, SEXP f, SEXP rho) {
  defineVar(install("x"), mkans(x), rho);
  return(REAL(eval(f, rho))[0]);
}
SEXP zero(SEXP f, SEXP guesses, SEXP stol, SEXP rho) {
  double x0 = REAL(guesses)[0], x1 = REAL(guesses)[1], tol = REAL(stol)[0];
  double f0, f1, fc, xc;
  if(tol <= 0.0) error("non-positive tol value");
  f0 = feval(x0, f, rho); f1 = feval(x1, f, rho);
  if(f0 == 0.0) return mkans(x0);
  if(f1 == 0.0) return mkans(x1);
  if(f0*f1 > 0.0) error("x[0] and x[1] have the same sign");
  for(;;) {
    xc = 0.5*(x0+x1);
    if(fabs(x0-x1) < tol) return mkans(xc);
    fc = feval(xc, f, rho);
    if(fc == 0) return mkans(xc);
    if(f0*fc > 0.0) {
      x0 = xc; f0 = fc;
    }
    else {
      x1 = xc; f1 = fc;
    }
  }
}


This works great. However, I wish to make it more general, by
modifying 'feval'. Given that my problem involves a data set 'u', with
dimension (i x j), I need to assign values to 'u1', 'u2', ..., 'ui'
via defineVar(install(...)). I tried the following:

double feval(double x, double *u, int d, double v, SEXP f, SEXP rho) {
  int i;
  char *str1="u", str2[1001], *str3;
  defineVar(install("x"), mkans(x), rho);
  defineVar(install("y"), mkans(v), rho);
  for(i=0;i<d;i++) {
    sprintf(str2,"%d",i+1);
    str3 = (char *)malloc((strlen(str1)+strlen(str2)+1)*sizeof(char));
    strcpy(str3,str1);
    strcat(str3,str2);
    defineVar(install(str3), mkans(u[i]), rho);
  }
  free(str3);
  return(REAL(eval(f,rho))[0]);
}

My R-package still compiles without errors but R crashes due to the
defineVar command.

Any suggestions to how I can do the defineVar bit?

Thanks in advance.

Reagards,
Daniel Berg

--------------------------------------------
> R.Version()
$platform
[1] "i486-pc-linux-gnu"
$arch
[1] "i486"
$os
[1] "linux-gnu"
$system
[1] "i486, linux-gnu"
$status
[1] ""
$major
[1] "2"
$minor
[1] "3.1"
$year
[1] "2006"
$month
[1] "06"
$day
[1] "01"
$`svn rev`
[1] "38247"
$language
[1] "R"
$version.string
[1] "Version 2.3.1 (2006-06-01)"



More information about the R-help mailing list