2009-11-12 23 views
14

आर ++ डेटा संरचनाओं का उपयोग करने के लिए आर ++ लाइब्रेरी का उपयोग करने का सबसे अच्छा तरीका क्या है, उम्मीद है कि सी ++ डेटा संरचनाओं को संरक्षित किया जाए। मैं बिल्कुल सी ++ उपयोगकर्ता नहीं हूं, इसलिए मैं उपलब्ध दृष्टिकोणों के सापेक्ष गुणों पर स्पष्ट नहीं हूं। आर-एक्सटी मैनुअल सी में सी ++ फ़ंक्शन को लपेटने का सुझाव देता है। हालांकि, सी ++ को शामिल करने के कम से कम चार या पांच अन्य साधन मौजूद हैं।आर पैकेज में सी ++ पुस्तकालयों का उपयोग

दो तरीके पैकेज w/समान वंशावली हैं, आरसीपीपी (प्रबल ओवरफ्लॉवर डिर्क एडडेलबुटेल द्वारा बनाए गए) और आरसीपीटी टेम्पलेट पैकेज (दोनों सीआरएएन पर), दोनों के बीच अंतर क्या हैं?

एक अन्य पैकेज, आरसीपीबीआईंड उपलब्ध है, आर फोर्ज पर जो बाध्यकारी सी ++ और आर (मुझे बताने के लिए जानकार नहीं है) के लिए एक अलग दृष्टिकोण लेने का दावा करता है।

सीआरएएन पर उपलब्ध पैकेज इनलाइन, इनलाइन सी/सी ++ की अनुमति देने का दावा करता है, मुझे यकीन नहीं है कि कोड अंतर्निहित कार्यक्षमता से अलग है, इसके अलावा कोड को इनलाइन w/R होना चाहिए।

और अंततः आरएसविग in the wild प्रतीत होता है लेकिन यह स्पष्ट नहीं है कि author's page को वर्षों से अपडेट नहीं किया गया है।

मेरा सवाल यह है कि, इन विभिन्न दृष्टिकोणों की सापेक्ष योग्यता क्या है। जो सबसे पोर्टेबल और मजबूत हैं, जो कार्यान्वित करने के लिए सबसे आसान हैं। यदि आप सीआरएएन पर एक पैकेज वितरित करने की योजना बना रहे थे तो आप किस तरीके का उपयोग करेंगे?

उत्तर

15

सबसे पहले, एक अस्वीकरण: मैं हर समय Rcpp का उपयोग करता हूं। वास्तव में, जब (आरसीपीपी से उस समय का नाम बदल दिया गया था) आरसीपीपी टेम्पलेट पहले ही अनाथ हो चुका था और दो साल के अपडेट के बिना, मैंने इसे आरसीपीपी के प्रारंभिक नाम के तहत बनाए रखा (जिसके तहत इसे RQuantLib में योगदान दिया गया था)। यह लगभग एक साल पहले था, और मैंने कुछ वृद्धिशील परिवर्तन किए हैं जिन्हें आप चेंजलॉग में दस्तावेज कर सकते हैं।

अब आरसीपीपीम्प्लेट हाल ही में बिना किसी अपडेट या फिक्स के पूर्ण पच्चीस महीने बाद वापस आ गया है। इसमें दिलचस्प नया कोड शामिल है, लेकिन ऐसा लगता है कि यह पीछे की तरफ संगत नहीं है इसलिए मैं इसका उपयोग नहीं करूँगा जहां मैंने पहले ही आरसीपीपी का उपयोग किया था।

Rcppbind जब भी मैंने चेक किया तो बहुत सक्रिय रूप से बनाए रखा नहीं गया था। व्हिट आर्मस्ट्रांग में एक टेम्पलेटेड इंटरफ़ेस पैकेज भी है जिसे rabstraction कहा जाता है।

Inline कुछ पूरी तरह से अलग है: यह आपके प्रोग्राम को 'एम्बेडिंग' द्वारा आर प्रोग्राम स्ट्रिंग के रूप में संकलित/लिंक चक्र को आसान बनाता है जो तब संकलित, लिंक और लोड हो जाता है। मैंने ओलेग से इनलाइन समर्थन आरसीपीपी के बारे में बात की है जो अच्छा होगा।

Swig भी दिलचस्प है। जो वैंग ने वहां बहुत अच्छा काम किया और आर के लिए क्वांटलिब को लपेट लिया। लेकिन जब मैंने आखिरी बार कोशिश की, तो यह आर इंटर्नल्स में कुछ बदलावों के कारण काम नहीं कर पाया। स्विग टीम के किसी के मुताबिक, जो अभी भी इस पर काम कर सकता है। स्विग का लक्ष्य वैसे भी बड़े पुस्तकालय है। यह परियोजना शायद पुनरुद्धार के साथ कर सकती है लेकिन यह तकनीकी चुनौतियों के बिना नहीं है।

एक और उल्लेख RInside पर जाना चाहिए जो आरसीपीपी के साथ काम करता है और आपको सी ++ अनुप्रयोगों के अंदर आर एम्बेड करने देता है।

तो इसे समेटने के लिए: Rcpp मेरे लिए अच्छा काम करता है, खासतौर पर छोटी खोजी परियोजनाओं के लिए जहां आप केवल एक समारोह या दो जोड़ना चाहते हैं। इसका ध्यान उपयोग की आसानी है, और यह आपको कुछ आर आंतरिकों को 'छिपाने' की अनुमति देता है जो हमेशा काम करने के लिए मजेदार नहीं होते हैं। मैं उन कई अन्य उपयोगकर्ताओं के बारे में जानता हूं जिन्हें मैंने ईमेल के माध्यम से और बंद करने में मदद की है। तो मैं कहूंगा कि इस के लिए जाओ।

मेरा 'परिचय एचपीसी के साथ आर' ट्यूटोरियल में आरसीपीपी, आरएनसाइड और इनलाइन के कुछ उदाहरण हैं।

संपादित करें: तो चलो एक ठोस उदाहरण (स्लाइड 'आर पहचान के साथ एचपीसी' से लिया और स्टीफन Milborrow जो इसे Venables और रिप्ले से ले लिया से उधार) को देखो। कार्य 2x2 मैट्रिक्स के निर्धारक के सभी संभावित संयोजनों को गिनना है जिसमें प्रत्येक स्थिति में केवल एक अंक होता है। इस चालाक vectorised तरीकों से किया जा सकता है या जानवर बल द्वारा (जैसा कि हम ट्यूटोरियल स्लाइड्स में चर्चा) इस प्रकार है:

#include <Rcpp.h> 

RcppExport SEXP dd_rcpp(SEXP v) { 
    SEXP rl = R_NilValue;  // Use this when there is nothing to be returned. 
    char* exceptionMesg = NULL; // msg var in case of error 

    try { 
    RcppVector<int> vec(v);  // vec parameter viewed as vector of ints 
    int n = vec.size(), i = 0; 
    if (n != 10000) 
     throw std::length_error("Wrong vector size"); 
    for (int a = 0; a < 9; a++) 
     for (int b = 0; b < 9; b++) 
     for (int c = 0; c < 9; c++) 
      for (int d = 0; d < 9; d++) 
      vec(i++) = a*b - c*d; 

    RcppResultSet rs;   // Build result set to be returned as list to R 
    rs.add("vec", vec);   // vec as named element with name 'vec' 
    rl = rs.getReturnList(); // Get the list to be returned to R. 
    } catch(std::exception& ex) { 
    exceptionMesg = copyMessageToR(ex.what()); 
    } catch(...) { 
    exceptionMesg = copyMessageToR("unknown reason"); 
    } 

    if (exceptionMesg != NULL) 
    Rf_error(exceptionMesg); 

    return rl; 
} 

आप के रूप में, कहते हैं, dd.rcpp.cpp इस बचाने के लिए और, Rcpp स्थापित होना तो बस

का उपयोग करते हैं साझा पुस्तकालय बनाने के लिए
PKG_CPPFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'` \ 
    PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'` \ 
    R CMD SHLIB dd.rcpp.cpp 

। हम Rscript (या r) का उपयोग अपने हेडर और लाइब्रेरी स्थानों के बारे में Rcpp पर पूछने के लिए करते हैं। एक बार बनाया, हम लोड और इस प्रकार आर से इस का उपयोग कर सकते हैं:

dyn.load("dd.rcpp.so") 

dd.rcpp <- function() { 
    x <- integer(10000) 
    res <- .Call("dd_rcpp", x) 
    tabulate(res$vec) 
} 

उसी तरह, आप वैक्टर, MATRICS, भेज सकते हैं विभिन्न आर के ... और सी ++ डेटा प्रकार वापस आसानी से आगे जाते हैं। उम्मीद है कि यह कुछ हद तक मदद करता है।

संपादित 2 (बाद में कुछ पाँच + वर्ष):

तो इस सवाल का जवाब सिर्फ एक वोट दें मिला और इसलिए मेरी कतार में बुलबुले। एक लॉट समय बीत चुका है क्योंकि मैंने इसे लिखा है, और आरसीपीपी को सुविधाओं में समृद्ध मिला है। तो मैं बहुत जल्दी में लिखा था इस

#include <Rcpp.h> 

// [[Rcpp::export]] 
Rcpp::IntegerVector dd2(Rcpp::IntegerVector vec) { 
    int n = vec.size(), i = 0; 
    if (n != 10000) 
     throw std::length_error("Wrong vector size"); 
    for (int a = 0; a < 9; a++) 
     for (int b = 0; b < 9; b++) 
      for (int c = 0; c < 9; c++) 
       for (int d = 0; d < 9; d++) 
        vec(i++) = a*b - c*d; 
    return vec; 
} 

/*** R 
x <- integer(10000) 
tabulate(dd2(x)) 
*/ 

जो के रूप में एक फ़ाइल में कोड के साथ इस प्रकार किया जा सकता है /tmp/dd.cpp

R> Rcpp::sourceCpp("/tmp/dd.cpp") # on from any other file and path 

R> x <- integer(10000) 

R> tabulate(dd2(x)) 
[1] 87 132 105 155 93 158 91 161 72 104 45 147 41 96 
[15] 72 120 36 90 32 87 67 42 26 120 41 36 27 75 
[29] 20 62 16 69 19 28 49 45 12 18 11 57 14 48 
[43] 10 18 7 12 6 46 23 10 4 10 4 6 3 38 
[57] 2 4 2 3 2 2 1 17 
R> 

मुख्य अंतर से कुछ हैं:

  • सरल निर्माण: बस sourceCpp() इसे; यहां तक ​​कि अंत में आर परीक्षण कोड निष्पादित
  • पूर्ण विकसित IntegerVector प्रकार
  • अपवाद हैंडलिंग स्वचालित रूप से sourceCpp() कोड जनरेटर से जोड़ा आवरण
+0

जवाब के लिए धन्यवाद! क्या आप आरसीपीटी टेम्पलेट में "दिलचस्प नया कोड" से क्या मतलब समझ सकते हैं। पैकेज आरसीपीपी से अलग कैसे है? मुझे सी ++ के बारे में लगभग कुछ नहीं पता है, ये पैकेज कैसे काम करते हैं? – Peter

+2

डिर्क, शायद यह सी ++ को आर के साथ काम करने के बारे में बात करने के बारे में बात करने के लिए समय है ... :(! – knguyen

+0

यह समझाना आसान नहीं है कि वे कैसे भिन्न हैं ... सी ++ में वे अलग हैं –

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