【问题标题】:running embedded R in C在 C 中运行嵌入式 R
【发布时间】:2013-09-01 02:42:57
【问题描述】:

我编写了一段 C 代码,它声明了一个大小为 4x4 的方阵。然后,它从 R 中 GeneralizedHyperbolic 包中名为 rgig 的采样函数中采样。它使用 gnu 中的 gsl 库对矩阵进行逆运算并输出结果。这是从 C 调用 R 的练习。

#include <stdio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stddef.h>

// for gsl
#include <gsl/gsl_machine.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_cdf.h>
#include <gsl/gsl_cblas.h>
#include <gsl/gsl_sf_gamma.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_linalg.h>

// for R embedding in C
#include <Rinternals.h>
#include <Rdefines.h>
#include <Rembedded.h>
#include <R_ext/Parse.h>

void gsl_square_matrix_inverse (gsl_matrix *, gsl_matrix *, int);
SEXP get_rInvGauss(void);

int main(void)
{
    // Define the dimension n of the matrix
    // and the signum s (for LU decomposition)
    int s, i, j, n = 4;
    // Define all the used matrices
    gsl_matrix * m = gsl_matrix_alloc (n, n);
    gsl_matrix * inverse = gsl_matrix_alloc (n, n);

    // R embedding in C
    char *localArgs[] = {"R", "--no-save","--silent"};
    SEXP rInvGauss;

    // init R embedding
    Rf_initEmbeddedR(3, localArgs);

    printf("\n Printing matrix m before set. size %d by %d... \n", n, n);
    for(i=0; i<n; i++){
        printf("\n");
        for(j=0; j<n; j++){
            printf(" %f ", gsl_matrix_get(m, i, j));
        }
    }

    // set diagonal elements of matrix m from Inverse Gaussian Random samples
    for(i=0; i<n; i++){
        rInvGauss = get_rInvGauss();
        gsl_matrix_set(m, i, i, *REAL(rInvGauss));
    }

    Rf_endEmbeddedR(0); // end the R embedding in C

    printf("\n Printing matrix m ..... \n");
    for(i=0; i<n; i++){
        printf("\n");
        for(j=0; j<n; j++){
            printf(" %f ", gsl_matrix_get(m, i, j));
        }
    }

    // inverse of matrix m
    gsl_square_matrix_inverse (m, inverse, n);

    printf("\n Printing inverse of matrix m ..... \n");
    for(i=0; i<n; i++){
        printf("\n");
        for(j=0; j<n; j++){
            printf(" %f", gsl_matrix_get(inverse, i, j));
        }
    }

    return 0;
}


SEXP get_rInvGauss(void) {
    SEXP e, s, t, tmp, result;
    int errorOccurred, n=1;
    double chi=5, psi=4, lambda=0.5;

    // create and evaluate 'require(GeneralizedHyperbolic)'
    PROTECT(e = lang2(install("require"), mkString("GeneralizedHyperbolic")));
    R_tryEval(e, R_GlobalEnv, &errorOccurred);
    if (errorOccurred) {
        // handle error
        printf("\n Error loading library GeneralizedHyperbolic:");
    }
    UNPROTECT(1);


    // Create the R expressions using a paired list
    // rgig(n = 1, chi = 5, psi = 4, lambda = 0.5) with the R API.
    PROTECT(t = s = allocVector(LANGSXP, 5));
    // could also be done by: PROTECT(t = s = allocList(5)); SET_TYPEOF(s, LANGSXP);

    tmp = findFun(install("rgig"), R_GlobalEnv);
    if(tmp == R_NilValue) {
        printf("No definition for function rgig.\n");
        UNPROTECT(1);
        exit(1);
        }
    SETCAR(t, tmp); t = CDR(t);
    SETCAR(t,  ScalarInteger(n)); SET_TAG(t, install("n")); t= CDR(t);
    SETCAR(t,  ScalarReal(chi)); SET_TAG(t, install("chi")); t= CDR(t);
    SETCAR(t,  ScalarReal(psi)); SET_TAG(t, install("psi")); t= CDR(t);
    SETCAR(t,  ScalarReal(lambda)); SET_TAG(t, install("lambda")); t= CDR(t);
    PROTECT(result = R_tryEval(VECTOR_ELT(s, 0), R_GlobalEnv, NULL));
    UNPROTECT(2);

    return(result);

}

void gsl_square_matrix_inverse (gsl_matrix *m, gsl_matrix *inverse, int n){

    int s, i, j;
    gsl_permutation * perm = gsl_permutation_alloc (n);
    // Make LU decomposition of matrix m
    gsl_linalg_LU_decomp (m, perm, &s);
    // Invert the matrix m
    gsl_linalg_LU_invert (m, perm, inverse);

}

我使用以下代码编译了代码:

R CMD SHLIB -lgsl -lgslcblas embedR_matinv.c

带输出:

gcc -arch x86_64 -std=gnu99 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/x86_64 -DNDEBUG  -I/usr/local/include    -fPIC  -g -O2  -c embedR_matinv.c -o embedR_matinv.o
gcc -arch x86_64 -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -o embedR_matinv.so embedR_matinv.o -lgsl -lgslcblas -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation

当我提交时:

R CMD embedR_matinv

它给出了错误:

/Library/Frameworks/R.framework/Resources/bin/Rcmd: line 62: exec: embedR_matinv: not found

我做错了什么?

我还将main() 更改为test() 并将共享对象设为

R CMD SHLIB -lgsl -lgslcblas embedR_matinv.c -o embedR_matinv 

输出:

gcc -arch x86_64 -std=gnu99 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/x86_64 -DNDEBUG  -I/usr/local/include    -fPIC  -g -O2  -c embedR_matinv.c -o embedR_matinv.o

如果我在 R Studio 中执行 dyn.load("embedR_matinv.so"),代码会在没有任何终止的情况下运行,即挂起!

对代码中的错误有什么建议吗?

【问题讨论】:

  • 编译embedR_matinv.c时会生成什么?你确定你必须发出R CMD embedR_matinv,而不是R CMD embedR_matinv.oR CMD embedR_matinv.so吗?也许您应该指定生成文件的完整路径?
  • 代码在哪里挂起?闻起来像是卡在嵌入式 R 代码中的 R 解释器中。

标签: c r s-expression


【解决方案1】:

您使用的是 Mac OSX 系统吗?

试试这个:

sudo cp /Library/Frameworks/R.framework/Resources/library/Rserve/libs/x86_64/Rserve-bin.so\ /Library/Frameworks/R.framework/Resources/bin/Rserve

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多