سؤال

ما هي أفضل طريقة للاستفادة من مكتبة C ++ في R، نأمل الحفاظ على هياكل البيانات C ++. أنا لست مستخدم C ++، لذلك أنا لست واضحا بشأن المزايا النسبية للنهج المتاحة. يبدو أن دليل R ret يقترح التفاف كل وظيفة C ++ في C. ومع ذلك، فإن ما لا يقل عن أربع أو خمس وسيلة أخرى لإدماج C ++ موجودة.

طريقتان عبارة عن حزم W / سلالة مماثلة، RCPP (تحتفظ بها Dirk Dirk Eddelbuettel RCPPETEL) وحزم RCPPTEMPLATE (كلاهما على Cran)، ما هي الاختلافات بين الاثنين؟

حزمة أخرى، RCPPBBind المتاحة، على ص يدعي أنها تدعي أن تأخذ نهجا مختلفا إلى ربط C ++ و R (أنا لست على دراية أن أقول).

الحزمة المضمنة المتاحة على Cran، مطالبات السماح بما يتندد في C / C ++ لست متأكدا من أن هذا يختلف من الوظيفة المدمجة، جانبا للسماح للرمز بأن تكون مضمنة W / R.

وأخيرا Rswig الذي يبدو أنه في البرية ولكن من غير الواضح كيف دعمها، كما صفحة المؤلف لم يتم تحديثه لسنوات.

سؤالي هو، ما هي المزايا النسبية لهذه الأساليب المختلفة. والتي هي الأكثر المحمولة والقوية، والتي هي أسهل تنفيذها. إذا كنت تخطط لتوزيع حزمة على Cran أي من الأساليب ستستخدمها؟

هل كانت مفيدة؟

المحلول

أولا، إخلاء المسؤولية: أنا استخدم RCPP. طوال الوقت. في الواقع، عندما تم (بعد إعادة تسميتها بحلول الوقت من RCPP) قد تعتزم RCPPTEMPLATE بالفعل وبدون تحديثات لمدة عامين، بدأت في الحفاظ عليها بموجب اسمها الأولي ل RCPP (الذي ساهم فيه rquantlib.). كان ذلك منذ حوالي عام، وقد قدمت بعض التغييرات الإضافية التي يمكنك العثور عليها موثقة في سجل التغيير.

الآن أعد RCPPTEMPLATE مؤخرا بعد خمسة وثلاثين شهرا دون أي تحديث أو إصلاح. يحتوي على رمز جديد مثير للاهتمام، ولكن يبدو أنه لا يتوافق مع الوراء لذلك لن أستخدمه حيث استخدمت بالفعل RCPP.

rcppbind. لم يتم الحفاظ عليها بنشاط كبير كلما راجعت. Whit Armstrong لديه أيضا حزمة واجهة TEMPLATED تسمى حصاد.

في النسق هو شيء مختلف تماما: إنه يخفف دورة Compile / Link عن طريق "تضمين" برنامجك كسلسلة حرف R ثم يتم تجميعها، مرتبطة، وتحميلها. لقد تحدثت إلى Oleg عن وجود دعم مضمون RCPP الذي سيكون لطيفا.

جرعة كبيرة مثيرة للاهتمام أيضا. قام جو وانغ بعمل رائع هناك وملفوف كل من Quantlib ل R. ولكن عندما جربته آخر مرة، لم يعد يعمل بسبب بعض التغييرات في R Interales. وفقا لشخص من فريق Swig، قد لا يزال جو العمل عليه. هدف Swig مكتبة أكبر على أي حال. ربما يمكن لهذا المشروع أن يفعل إحياء لكنه ليس دون تحديات تقنية.

يجب أن يذكر آخر الذهاب إلى رديء الذي يعمل مع RCPP ويتيح لك تضمين R داخل تطبيقات C ++.

لذلك لتلخيصه: RCPP. يعمل بشكل جيد بالنسبة لي، خاصة بالنسبة لمشاريع استكشافية صغيرة حيث تريد فقط إضافة وظيفة أو اثنين. إنه التركيز سهولة الاستخدام، ويسمح لك ب "إخفاء" بعض المخادتين غير المرح دائما للعمل معها. أنا أعرف عددا من المستخدمين الآخرين الذين ساعدتهم في البريد الإلكتروني وإيقافها عبر البريد الإلكتروني. لذلك أود أن أقول الذهاب لهذا واحد.

لديك "مقدمة إلى HPC مع R" دروس دروس بعض الأمثلة على RCPP و Rinside و مضمنة.

يحرر: لذلك دعونا نلقي نظرة على مثال ملموس (مأخوذة من "HPC مع الشرائح" المقدمة من RETHEN MILBOROR من أخذها من القرن الأدوات القديمة و Ripley). المهمة هي تعداد جميع المجموعات الممكنة من تحديد مصفوفة 2x2 التي تحتوي على أرقام واحدة فقط في كل موضع. يمكن القيام بذلك بطريقة ذكية من Vectored (نظرا لأننا نناقشها في الشرائح التعليمية) أو عن طريق القوة الغاشمة على النحو التالي:

#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. حول مواقع رأسها ومكتبة. بمجرد البناء، يمكننا تحميل واستخدام هذا من R كما يلي:

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

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

بنفس الطريقة، يمكنك إرسال ناقلات، Matrics، ... من مختلف أنواع البيانات R و C ++ إلى الوراء في النهاية بسهولة. آمل أن يساعد هذا إلى حد ما.

تحرير 2 (بعد حوالي خمسة + بعد سنوات):

لذلك حصلت هذه الإجابة على الرسوم الفصحية وبالتالي، في قائمة انتظاري. أ كثيرا الوقت قد مرت منذ أن كتبت ذلك، وقد حصلت RCPP كثير أكثر ثراء في الميزات. لذلك كتبت بسرعة جدا هذا

#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() مولد الأكواد
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top