2012-10-22 10 views
6

मैंने सी में एक फ़ंक्शन "foo" लिखा है जिसे मैं एक आर प्रोग्राम से कॉल करना चाहता हूं। फ़ंक्शन इनपुट मैट्रिक्स के रूप में कार्य करता है और इसमें कुछ ऑपरेशन करता है, (प्रत्येक तत्व में 1 जोड़ें) कहें। हालांकि यहआर सी इंटरफ़ेस: बहु-आयामी सरणी पास करना

.C("foo", n=as.integer(5), x=as.double(rnorm(5))) 

foo के साथ के रूप में एक वेक्टर के लिए आसान है

void foo(int *nin, double *x) 
{ 
int n = nin[0]; 

int i; 

for (i=0; i<n; i++) 
    x[i] = x[i] * x[i]; 
} 

मैं एक दो आयामी सरणी में कैसे पारित करना रूप में लागू किया? अगर मैं "डबल * एक्स" को "डबल ** एक्स" में बदलता हूं तो यह सेगमेंटेशन गलती देता है। किसी भी संकेतक की सराहना की।

उत्तर

7

इस तरह सीधे-आगे मैनिप्लेशंस के लिए .C पर छोड़ने की आवश्यकता नहीं है। याद रखें कि आर में एक मैट्रिक्स एक वेक्टर + आयाम है। इसी तरह सी में, इसलिए मैट्रिक्स और इसके आयामों को पारित करें, और मैट्रिक्स के तत्वों को वेक्टर में उपयुक्त ऑफसेट के रूप में एक्सेस करें।

void cplus1(double *x, int *dim) 
{ 
    for (int j = 0; j < dim[1]; ++j) 
     for (int i = 0; i < dim[0]; ++i) 
      x[j * dim[0] + i] += 1; 
} 

की तरह कुछ तो एक अच्छा पार्टी चाल

library(inline) 
sig <- signature(x="numeric", dim="integer") 
body <- " 
    for (int j = 0; j < dim[1]; ++j) 
     for (int i = 0; i < dim[0]; ++i) 
      x[j * dim[0] + i] += 1; 
" 

cfun <- cfunction(sig, body=body, language="C", convention=".C") 

plus1 <- function(m) { 
    m[] = cfun(as.numeric(m), dim(m))$x 
    m 
} 
+0

'.C' सी कार्यक्रम के लिए परम कॉपी करने की भूमि के ऊपर समय कहते हैं तो परिणाम वापस कॉपी लक्ष्य वस्तु से पारित कर दिया _modify_ रहा है, जबकि' .Call' @transang नहीं – transang

+0

करता है आर, तो आप _must_ इसे सी में कॉपी करें; आप 'सी() 'के साथ स्वचालित रूप से और सुरक्षित रूप से प्रतिलिपि बना सकते हैं, या मैन्युअल रूप से और'Call()' के साथ त्रुटि की उच्च संभावना के साथ कर सकते हैं। आरसीपीपी तरीके को डिर्क के जवाब में 'आरसीपीपी :: क्लोन (एम)' कथन में मेमोरी कॉपी की भी आवश्यकता होती है। निश्चित रूप से आरसीपीपी गंभीर सी-स्तर के विकास के लिए शानदार है। –

8

.C() पर छोड़ दें और .Call() पर स्विच करें जो आपको पूरे आर ऑब्जेक्ट्स को SEXP ऑब्जेक्ट्स के रूप में जाने देता है।

आप आर के सीपीआई के माध्यम से या आरसीपीपी के माध्यम से (जो हम सोचते हैं) अच्छे उच्च स्तरीय abstractions के माध्यम से उन कठिन तरीकों का विश्लेषण कर सकते हैं।

R> library(inline) # use version 0.3.10 for rcpp() wrapper 
R> 
R> addMat <- rcpp(signature(ms="numeric"), body=' 
+ Rcpp::NumericMatrix M(ms); 
+ Rcpp::NumericMatrix N = Rcpp::clone(M); 
+ for (int i=0; i<M.nrow(); i++) 
+  for (int j=0; j<M.ncol(); j++) 
+   N(i,j) = M(i,j) + 1; 
+ return(N); 
+ ') 
R> addMat(matrix(1:9,3,3)) 
    [,1] [,2] [,3] 
[1,] 2 5 8 
[2,] 3 6 9 
[3,] 4 7 10 
R> 
0

.C के साथ के रूप में inline उपयोग कर, आप @Martin मॉर्गन के जवाब के रूप में अतिरिक्त पैरामीटर द्वारा मैट्रिक्स आयाम पारित करने के लिए की है।

साथ .Call

SEXP foo(SEXP mat){ 
    SEXP dims = getAttttrib(mat, R_DimSymbol); 
    int nrow = INTEGER(dims)[0]; 
    int ncol = INTEGER(dims)[1]; 
    //... 
} 
+0

उस मैट्रिक्स को कॉपी करना न भूलें! –

संबंधित मुद्दे