[R] the use of the .C function

Katharine Mullen kate at few.vu.nl
Sat Oct 13 19:56:52 CEST 2007


Let me also comment that you are trying to interface to a function ported
to C++ from the Cephes library, which is in C.  You have not explained why
you are trying to interface to the function (is this an exercise, or do
you suspect a problem with digamma()?), but if you just want access to it
as implemented in Cephes, you may as well use the original C:
http://www.netlib.org/cephes/

On Sun, 14 Oct 2007, Duncan Temple Lang wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
>
>
> The code is C++ and so is compiled
> using the C++ compiler, not the C compiler.
> This is because the name of the file is .cpp
> (and you include iostream.h, but don't seem to make any use of it.)
> As a result, the names of the routines are "mangled"
> and so psi is not the actual name of the compiled routine,
> but something more like _Z3psid which encodes the
> types of the parameters in the name (to allow overloaded routines).
>
> To avoid the mangling, use
>
> #ifdef __cplusplus
> extern "C"
> #endif
> double psi(double)
>
> Alternatively, you can use the registration mechanism to
> associate a name with a routine directly for R.  See
> "Writing R Extensions" which would be a good thing to read
> as trying to get this sort of thing working by trial and
> error can be both very time consuming, and also very confusing
> to the point that you "unlearn" things.
>
> After that you will still need to make some changes
> to use the routine with the .C() interface.
> That expects inputs as pointers, i.e. the double
> should be a double * and you fetch the value from
> that. And a routine called by .C() should return nothing
> directly, but provide the results in space provided
> by the inputs
>
> So
> void R_psi(double *x)
> {
>    *x = psi(*x);
> }
>
> and make certain R_psi is not mangled.
>
>
> Also, you might want to upgrade to the latest version of R.
>
> Bernardo Lagos Alvarez wrote:
> > Dear All,
> > could someone please shed some light on the use of the .C  or .Fortran function:
> >
> >
> > I am trying load and running on R the  following function
> >
> > // psi.cpp -- psi function for real arguments.
> >
> > //      Algorithms and coefficient values from "Computation of Special
> >
> > //      Functions", Zhang and Jin, John Wiley and Sons, 1996.
> >
> > //
> >
> > //  (C) 2003, C. Bond. All rights reserved.
> >
> > //
> >
> > //  Returns psi function for real argument 'x'.
> >
> > //  NOTE: Returns 1e308 for argument 0 or a negative integer.
> >
> > //
> >
> > #include <iostream.h> // or <stdio.h>?
> >
> > #include <math.h>
> >
> > #define el 0.5772156649015329
> >
> >
> >
> > double psi(double x)
> >
> > {
> >
> >     double s,ps,xa,x2;
> >
> >     int n,k;
> >
> >     static double a[] = {
> >
> >         -0.8333333333333e-01,
> >
> >          0.83333333333333333e-02,
> >
> >         -0.39682539682539683e-02,
> >
> >          0.41666666666666667e-02,
> >
> >         -0.75757575757575758e-02,
> >
> >          0.21092796092796093e-01,
> >
> >         -0.83333333333333333e-01,
> >
> >          0.4432598039215686};
> >
> >
> >
> >     xa = fabs(x);
> >
> >     s = 0.0;
> >
> >     if ((x == (int)x) && (x <= 0.0)) {
> >
> >         ps = 1e308;
> >
> >         return ps;
> >
> >     }
> >
> >     if (xa == (int)xa) {
> >
> >         n = xa;
> >
> >         for (k=1;k<n;k++) {
> >
> >             s += 1.0/k;
> >
> >         }
> >
> >         ps =  s-el;
> >
> >     }
> >
> >     else if ((xa+0.5) == ((int)(xa+0.5))) {
> >
> >         n = xa-0.5;
> >
> >         for (k=1;k<=n;k++) {
> >
> >             s += 1.0/(2.0*k-1.0);
> >
> >         }
> >
> >         ps = 2.0*s-el-1.386294361119891;
> >
> >     }
> >
> >     else {
> >
> >         if (xa < 10.0) {
> >
> >             n = 10-(int)xa;
> >
> >             for (k=0;k<n;k++) {
> >
> >                 s += 1.0/(xa+k);
> >
> >             }
> >
> >             xa += n;
> >
> >         }
> >
> >         x2 = 1.0/(xa*xa);
> >
> >         ps = log(xa)-0.5/xa+x2*(((((((a[7]*x2+a[6])*x2+a[5])*x2+
> >
> >             a[4])*x2+a[3])*x2+a[2])*x2+a[1])*x2+a[0]);
> >
> >         ps -= s;
> >
> >     }
> >
> >     if (x < 0.0)
> >
> >         ps = ps - M_PI*cos(M_PI*x)/sin(M_PI*x)-1.0/x;
> >
> >         return ps;
> >
> > }
> >
> >
> > However, when applicated the codes
> >> digamma(-0.9)
> > [1] -9.312644  OK!
> >
> > But when
> >> dyn.load("psi.so")
> >> out<-.C("psi", as.double(-0.9))
> > Erro en .C("psi", as.double(-0.9)) : C symbol name "psi" not in load table
> >
> >> out
> > Error: objeto "out" no encontrado
> >
> > More information on OS:
> >> version
> >                _
> > platform       i486-pc-linux-gnu
> > arch           i486
> > os             linux-gnu
> > system         i486, linux-gnu
> > status
> > major          2
> > minor          4.1
> > year           2006
> > month          12
> > day            18
> > svn rev        40228
> > language       R
> > version.string R version 2.4.1 (2006-12-18)
> >
> >
> >
> > Many thanks for any insight or comments.
> >
> > Bernardo Lagos A.
> >
> > ______________________________________________
> > R-help at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.7 (Darwin)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iD8DBQFHEQMO9p/Jzwa2QP4RAiupAJ40LfoWt3Jm6dPXU0aYHe3gXPAhQgCdFAig
> VScTISDpaa4pzGw+eNkkxKY=
> =Kd5o
> -----END PGP SIGNATURE-----
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



More information about the R-help mailing list