İstatistiksel hesaplama için C ++ kütüphaneleri


23

C / C ++ 'ya taşımak istediğim belirli bir MCMC algoritması var. Pahalı hesaplamanın çoğu zaten Cython üzerinden C cinsindendir, ancak tüm örnekleyiciyi derlenmiş bir dilde yazmayı istiyorum, böylece Python / R / Matlab / için herhangi bir paketleyici yazabilirim.

Etrafı dürttükten sonra C ++ 'a yaslanıyorum. Tanıdığım birkaç kitaplık Armadillo (http://arma.sourceforge.net/) ve Scythe (http://scythe.wustl.edu/). Her ikisi de, çok sevdiğim öğrenme eğrisini kolaylaştırmak için R / Matlab'ın bazı yönlerini taklit etmeye çalışıyor. Tırpan, yapmak istediklerimle kareleri biraz daha iyi sanırım. Özellikle, RNG'si, Armadillo'nun sadece tek biçimli / normal olduğu, uygun olmayan birçok dağılımını içerir. Armadillo oldukça aktif bir gelişme gösteriyor gibi gözüküyor, Scythe ise 2007'deki son sürümünü gördü.

Bu yüzden merak ettiğim şey, herhangi birinin bu kütüphanelerle - ya da neredeyse kesin olarak özlediğim - başkalarıyla deneyimleyip istemediği ve eğer öyleyse, Python / R / Matlab'ı çok iyi tanıyan bir istatistikçi için başkalarına tavsiye edecek bir şey olup olmadığı. ama daha az derlenmiş dillerle (tamamen cahil değil, tam olarak yeterli değil ...).

Yanıtlar:


18

Rcpp paketimizi kullanarak C ++ 'dan R' ye (ve bu konuda geri döndüğümüzü) daha kolay bir şekilde sarmak için biraz zaman harcadık .

Ve lineer cebir zaten böyle bir iyi anlaşılmış ve kodlanmış-için sahada olduğu için Armadillo , templated, küçük, iyi-documted bir akım, modern ve hoş, ... kütüphane ilk genişletilmiş sarmalayıcı için çok doğal bir uyum oldu: RcppArmadillo .

Bu, diğer MCMC kullanıcılarının da dikkatini çekti. Geçen yaz Rochester U İşletme Okulu'nda bir günlük bir çalışma yaptım ve MidWest'teki başka bir araştırmaya benzer keşifler için yardım ettim. Ver RcppArmadillo bir deneyin - bu aktif korunur, iyi çalışıyor ve desteklenen (yeni Armadillo salıvermeli 1.1.4 bugün, yeni bir sonraki RcppArmadillo yapacak).

Ve bu örneği çok fazla lm()aştığım için , dönen katsayı ve std.errors'un hızlı bir "hızlı" versiyonu :

extern "C" SEXP fastLm(SEXP ys, SEXP Xs) {

  try {
    Rcpp::NumericVector yr(ys);                 // creates Rcpp vector 
    Rcpp::NumericMatrix Xr(Xs);                 // creates Rcpp matrix 
    int n = Xr.nrow(), k = Xr.ncol();

    arma::mat X(Xr.begin(), n, k, false);       // avoids extra copy
    arma::colvec y(yr.begin(), yr.size(), false);

    arma::colvec coef = arma::solve(X, y);      // fit model y ~ X
    arma::colvec res = y - X*coef;              // residuals

    double s2 = std::inner_product(res.begin(), res.end(), 
                                   res.begin(), double())/(n - k);
                                            // std.errors of coefficients
    arma::colvec std_err = 
           arma::sqrt(s2 * arma::diagvec( arma::pinv(arma::trans(X)*X) ));  

    return Rcpp::List::create(Rcpp::Named("coefficients") = coef,
                              Rcpp::Named("stderr")       = std_err,
                              Rcpp::Named("df")           = n - k);

  } catch( std::exception &ex ) {
      forward_exception_to_r( ex );
  } catch(...) { 
      ::Rf_error( "c++ exception (unknown reason)" ); 
  }
  return R_NilValue; // -Wall
}

Son olarak, 'kodlama zamanı' daha hızlı hale getirebilecek satır içi üzerinden de anında prototip oluyorsunuz .


Teşekkürler Dirk - Er ya da geç cevap verecek bir cevap verdim :). Kod istediğim göz önüne alındığında başka bir yazılımdan (çoğunlukla Python, ama Matlab da) arayabilirim, belki de iyi bir iş akışı Rcpp / RcppArmadillo'da prototip yapmak ve sonra "düz" Armadillo'ya geçmek olabilir. Sözdizimi vb. Çok benzer görünüyor.
JMS

1
Umarım yararlı buldunuz.
Dirk Eddelbuettel

2. sorudaki düzenlemeyi tekrar yazın: Tabii. Armadillo, az ya da bizim durumumuzda, R'den başka hiçbir şeye bağlı değildir. Rcpp / RcppArmadillo, bağımsız olarak ya da daha sonra ekleyebileceğiniz bir Python ve Matlab sarmalayıcıları ile tekrar kullanılabilecek prototip kodları aramanıza ve test etmenize yardımcı olacaktır. Conrad bir şey için işaretçiler içerebilir; Python veya Matlab için elimde yok.
Dirk Eddelbuettel

Halıyı çıkarttığım için üzgünüm :) Enter tuşunun satır başı yapmasını istiyorum, ancak yorumumu yerine getiriyor. Her neyse, yardımın için sağol - Bugün bütün gün Rcpp posta listesine göz atma ve kazma işinin tadını çıkarıyorum.
JMS

8

Şuna bir göz atmanızı RCppve RcppArmadillopaketlemenizi şiddetle tavsiye ederim R. Temel olarak, paketleyicileri zaten "dahil" olduklarından endişelenmenize gerek yoktur. Ayrıca, sözdizimsel şeker gerçekten tatlıdır (punto amaçlanmıştır).

Bir yan açıklama olarak, JAGSMCMC'yi yapan ve kaynak kodunu C ++ 'da gösteren bir göz atmanızı öneririm .


2
Bunu ikinci olarak istiyorum. Hızlı ve kolay bir yol arıyorsanız, R ile kod derlenmiş arayüze Rcppsahip RcppArmadillogitmek için bir yoldur. Düzenleme: Rcpp'i kullanarak, R'nin altındaki C kodunda yer alan tüm RNG'lere de erişebilirsiniz
fabians

güven oyu için teşekkürler. Ben de aynısını önermek
üzereydim

7

Boost Rastgele Boost C ++ kütüphanelerinden sizin için uygun olabilir. Pek çok RNG türüne ek olarak, çekileceği gibi çeşitli farklı dağılımlar sunar.

  • Üniforma (gerçek)
  • Düzgün (birim küre veya rastgele boyut)
  • Bernoulli
  • iki terimli
  • Cauchy
  • Gama
  • Poisson
  • Geometrik
  • Üçgen
  • Üstel
  • Normal
  • lognormal

Ek olarak, Boost Math , pek çok dağıtımın sayısız yoğunluk işleviyle örnekleyebileceğiniz yukarıdaki dağıtımları tamamlar. Aynı zamanda birkaç düzgün yardımcı işlevi vardır; Sadece sana bir fikir vermek için:

students_t dist(5);

cout << "CDF at t = 1 is " << cdf(dist, 1.0) << endl;
cout << "Complement of CDF at t = 1 is " << cdf(complement(dist, 1.0)) << endl;

for(double i = 10; i < 1e10; i *= 10)
{
   // Calculate the quantile for a 1 in i chance:
   double t = quantile(complement(dist, 1/i));
   // Print it out:
   cout << "Quantile of students-t with 5 degrees of freedom\n"
           "for a 1 in " << i << " chance is " << t << endl;
}

Boost kullanmaya karar verdiyseniz, çeşitli farklı matris türleri ve işlemleri içeren UBLAS kitaplığını da kullanabilirsiniz.


Bahşiş için teşekkürler. Boost küçük tırnağım için büyük bir çekiç gibi görünüyor ama olgun ve bakımlı.
JMS

Boot :: math :: binomial_distribution'ın R binom.test () two-sided'de aynı fonksiyonla aynı olduğundan emin değilim. Referansa baktım ve bu işlevi bulamadım. Bunu uygulamaya çalıştım ve önemsiz değil!
Kemin Zhou,

1

Dışarıda çok sayıda C / C ++ kütüphanesi var, çoğu (örneğin PDE çözücülerinin) belirli bir problem alanına odaklanıyor. Özellikle yararlı bulabileceğinizi düşündüğüm iki kapsamlı kitaplık var çünkü C dilinde yazılmışlar ancak zaten yazılmış mükemmel Python sarmalayıcıları var.

1) IMSL C ve PyIMSL

2) trilinos ve pirolinler

İşlevsellik temel olarak sayısal analiz yöntemlerinde olduğu için trilino'ları hiç kullanmadım, ancak istatistiksel çalışmalar için PyIMSL'i çok kullanıyorum (ve önceki bir çalışma hayatında da yazılımı geliştirdim).

RNG'lerle ilgili olarak, IMSL'deki C ve Python'dakiler:

AYRIK

  • random_binomial: Bir binom dağılımından sözderandom binom sayıları üretir.
  • random_geometric: Geometrik bir dağılımdan sözde rasgele sayılar üretir.
  • random_hypergeometric: Hipergeometrik bir dağılımdan sözde rasgele sayılar üretir.
  • random_logarithmic: Bir logaritmik dağılımdan sözde rasgele sayılar üretir.
  • random_neg_binomial: Negatif bir binom dağılımından sözde rasgele sayılar üretir.
  • random_poisson: Bir Poisson dağılımından yalancı ve sayıları üretir.
  • random_uniform_discrete: Ayrık bir üniform dağılımdan sözde rasgele sayılar üretir.
  • random_general_discrete: Bir takma yöntem veya isteğe bağlı olarak bir tablo arama yöntemi kullanarak genel bir kesikli dağılımdan sahte sayılar üretir.

UNIVARIATE SÜREKLİ DAĞITIMLAR

  • random_beta: Bir beta dağılımından sözde rasgele sayılar üretir.
  • random_cauchy: Bir Cauchy dağılımından sözde rasgele sayılar üretir.
  • random_chi_squared: Ki kare dağılımından sözde rasgele sayılar üretir.
  • random_exponential: Standart bir üstel dağılımdan sözde rasgele sayılar üretir.
  • random_exponential_mix: Standart bir üstel dağılımdan sahte karışık sayılar üretir.
  • random_gamma: Standart bir gama dağılımından sözde rasgele sayılar üretir.
  • random_lognormal: Lognormal dağılımından sözde rasgele sayılar üretir.
  • random_normal: Standart bir normal dağılımdan sözde rasgele sayılar üretir.
  • random_stable: Genel bir ayrık dağılımdan sözde rasgele sayılar üretmek için bir tablo oluşturur.
  • random_student_t: Bir öğrencinin t dağılımından sözde rasgele sayılar oluşturur.
  • random_triangular: Üçgen bir dağılımdan sözde rasgele sayılar üretir.
  • random_uniform: Üniforma (0, 1) dağılımından sözde rasgele sayılar üretir.
  • random_von_mises: Bir von Mises dağılımından sözde rasgele sayılar üretir.
  • random_weibull: Bir Weibull dağılımından sözde rasgele sayılar üretir.
  • random_general_continuous: Genel bir sürekli dağılımdan sözde rasgele sayılar üretir.

ÇOKLU ORTAMLARDA SÜREKLİ DAĞITIMLAR

  • random_normal_multivariate: Çok değişkenli normal dağılımdan sözde rasgele sayılar üretir.
  • random_orthogonal_matrix: Bir sözderandom ortogonal matris veya bir korelasyon matrisi oluşturur.
  • random_mvar_from_data: Belirli bir örnekten belirlenen çok değişkenli bir dağılımdan sözde rasgele sayılar üretir.
  • random_multinomial: Multinomial bir dağılımdan sözde rasgele sayılar üretir.
  • random_sphere: Bir birim daire veya K boyutlu küre üzerinde sözderandom noktaları oluşturur.
  • random_table_twoway: Bir sahte ve iki yönlü tablo oluşturur.

SİPARİŞ İSTATİSTİKLERİ

  • random_order_normal: Standart bir normal dağılımdan sözde sıra dizisi istatistikleri üretir.
  • random_order_uniform: Üniforma (0, 1) dağılımından sözde sıra dizisi istatistikleri üretir.

STOKASTİK SÜREÇLER

  • random_arma: Sahte ve ARMA işlem numaralarını üretir.
  • random_npp: Homojen olmayan bir Poisson işleminden sahte ve sayıları üretir.

ÖRNEKLER VE İZİNLER

  • random_permutation: Bir sözderandom permütasyonu üretir.
  • random_sample_indices: Basit bir sözde rasgele indeks örneği oluşturur.
  • random_sample: Sonlu bir popülasyondan basit bir psödorandom örneği oluşturur.

KULLANIM FONKSİYONLARI

  • random_option: Tek biçimli (0, 1) çarpımsal eşlenik yalancı sayı üreteci seçer.
  • random_option_get: Tek biçimli (0, 1) çarpımsal eş anlamlı yalancı sayı üretecini alır.
  • random_seed_get: IMSL random sayı üreteçlerinde kullanılan tohumun mevcut değerini alır.
  • random_substream_seed_get: Eş zamanlı olmayan 100.000 sayıdan başlayarak rasgele sayılar üretecek eşlenik üretmeyen üreticiler için bir tohum alır.
  • random_seed_set: IMSL rasgele sayı üreteçlerinde kullanılmak üzere rastgele bir tohum başlatır.
  • random_table_set: Karışık oluşturucuda kullanılan geçerli tabloyu ayarlar.
  • random_table_get: Karışık oluşturucuda kullanılan geçerli tabloyu alır.
  • random_GFSR_table_set: GFSR jeneratöründe kullanılan güncel tabloyu ayarlar.
  • random_GFSR_table_get: GFSR jeneratöründe kullanılan güncel tabloyu alır.
  • random_MT32_init: Bir diziyi kullanarak 32 bit Mersenne Twister jeneratörünü başlatır.
  • random_MT32_table_get: 32 bit Mersenne Twister jeneratöründe kullanılan geçerli tabloyu alır.
  • random_MT32_table_set: 32 bit Mersenne Twister jeneratöründe kullanılan geçerli tabloyu ayarlar.
  • random_MT64_init: Bir dizi kullanarak 64-bit Mersenne Twister jeneratörünü başlatır.
  • random_MT64_table_get: 64-bit Mersenne Twister jeneratöründe kullanılan mevcut tabloyu alır.
  • random_MT64_table_set: 64-bit Mersenne Twister jeneratöründe kullanılan mevcut tabloyu ayarlar.

DÜŞÜK GELİŞİM DİZİ

  • faure_next_point: Karışık bir Faure dizisini hesaplar.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.