統計計算用のC ++ライブラリ


23

C / C ++に移植したい特定のMCMCアルゴリズムがあります。高価な計算の多くは既にCythonを介してCで行われていますが、Python / R / Matlab / whateverのラッパーを書くことができるように、サンプラー全体をコンパイル済み言語で記述したいと思います。

いろいろと調べた後、私はC ++に傾いています。私が知っている関連ライブラリは、Armadillo(http://arma.sourceforge.net/)とScythe(http://scythe.wustl.edu/)です。どちらも、R / Matlabのいくつかの側面をエミュレートして、学習曲線を容易にすることを試みていますが、これはとても気に入っています。サイスは、私がやりたいと思うことで少し良くなります。特に、RNGには多くのディストリビューションが含まれており、Armadilloには均一/標準しかありませんが、これは不便です。Scytheは2007年に最後のリリースを見たが、Armadilloはかなり活発に開発されているようだ。

だから、私が疑問に思っているのは、誰かがこれらのライブラリの経験を持っているか、または私がほぼ間違いなく見逃している他の人ですか?しかし、コンパイルされた言語ではそれほどではありません(完全に無知ではありませんが、正確に堪能ではありません...)。

回答:


18

Rcppパッケージを使用して、C ++からRへのラッピング(およびその逆)を簡単に行えるようにするのに時間を費やしました。

そして、線形代数はすでに、このようなA、十分に理解し、コード化するためのフィールドであるため、アルマジロ、テンプレート、小さなよくdocumted現在、現代、plesant、...ライブラリは、私たちの最初の拡張ラッパーの非常に自然にフィットした:RcppArmadillo

これは、他のMCMCユーザーの注目を集めています。昨年の夏、ロチェスター大学ビジネススクールで1日の仕事をし、中西部の別の研究者に同様の調査を手伝いました。与えるRcppArmadilloに試して-それがうまく機能し、積極的に維持されている(今日新しいアルマジロのリリース1.1.4を、私は後で新しいRcppArmadilloを行います)およびサポートされています。

そして、私はこの例をとても気に入っているので、ここに、lm()戻りの係数とstd.errorsのクイック「高速」バージョンがあります。

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
}

最後に、インラインで即時にプロトタイピングを行うことで、「コード化の時間」を短縮できます。


Dirkに感謝します-後でよりも早く答えたいと思っていました:)。他のソフトウェア(主にPythonですが、Matlabも)から呼び出すことができるコードが必要な場合、Rcpp / RcppArmadilloでプロトタイプを作成してから「まっすぐな」Armadilloに移行するのが良いワークフローでしょうか。構文などは非常に似ています。
JMS

1
お役に立てば幸いです。
ダークエデルブエッテル

編集からの2番目の質問をもう一度:確かに。Armadilloは、R。Rcpp / RcppArmadillo以外にはほとんど依存していません。Rcpp/ RcppArmadilloは、スタンドアロンで、または後で追加できるPythonおよびMatlabラッパーで再利用できるプロトタイプコードのインターフェイスとテストに役立ちます。コンラッドには何かへのポインタがあります。PythonやMatlabには何もありません。
ダークエデルビュッテル

ラグを引き出してすみません:) Enterキーを押して復帰させたいのですが、代わりにコメントを送信します。とにかく、あなたの助けに感謝します-私は今日一日中Rcppメーリングリストをいじくり回して掘り返すのを楽しんでいます。
JMS

8

私は強くあなたが見ていることを示唆しているRCppRcppArmadilloのパッケージをR。基本的に、ラッパーは既に「含まれている」ので、心配する必要はありません。さらに、構文糖は本当に甘い(しゃれを意図している)。

副次的な発言として、JAGSMCMCを実行し、ソースコードがC ++であるをご覧になることをお勧めします。


2
これを二番目にしたいと思います。コンパイルされたコードをRとインターフェースするための高速で簡単な方法を探しているなら、Rcppwith RcppArmadilloが道です。編集:Rcppを使用すると、Rの基礎となるCコードに実装されているすべてのRNGにもアクセスできます
。– fabians

信頼の投票をありがとう。私は同じことを提案しようとしていました;-)
ダークエデルビュッテル

7

Boost C ++ライブラリのBoost Randomが最適です。多くのタイプのRNGに加えて、次のようなさまざまな異なる分布を利用できます。

  • ユニフォーム(本物)
  • 均一(単位球または任意の寸法)
  • ベルヌーイ
  • 二項
  • コーシー
  • ガンマ
  • ポアソン
  • 幾何学
  • 三角形
  • 指数関数
  • 普通
  • 対数正規

さらに、Boost Mathは、多くの分布の多数の密度関数を使用してサンプリングできる上記の分布を補完します。また、いくつかのきちんとしたヘルパー関数があります。あなたにアイデアを与えるために:

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を使用することにした場合は、さまざまなマトリックスタイプと操作を備えたUBLASライブラリも使用できます。


ヒントをありがとう。ブーストは、私の小さな爪には一種の大きなハンマーのように見えますが、成熟しており、維持されています。
JMS

boot :: math :: binomial_distributionがR binom.test()two-sidedで実装されているのと同じ機能を持っているかどうかはわかりません。リファレンスを調べましたが、この関数が見つかりませんでした。これを実装しようとしましたが、簡単ではありません!
ケミン周

1

多くのC / C ++ライブラリがあり、そのほとんどが特定の問題ドメイン(PDEソルバーなど)に焦点を当てています。Cで書かれているのに優れたPythonラッパーが既に書かれているので、特に便利だと思う2つの包括的なライブラリがあります。

1)IMSL CおよびPyIMSL

2)トリリノピトリリノ

機能は主に数値解析法に基づいているため、トリリノを使用したことはありませんが、統計作業にはPyIMSLをよく使用します(以前の作業ではソフトウェアも開発しました)。

RNGに関して、IMSLのCおよびPythonのものを以下に示します。

離散

  • random_binomial:二項分布から疑似ランダム二項数を生成します。
  • random_geometric:幾何分布から擬似乱数を生成します。
  • random_hypergeometric:超幾何分布から擬似乱数を生成します。
  • random_logarithmic:対数分布から擬似乱数を生成します。
  • random_neg_binomial:負の二項分布から擬似乱数を生成します。
  • random_poisson:ポアソン分布から擬似乱数を生成します。
  • random_uniform_discrete:離散均一分布から擬似乱数を生成します。
  • random_general_discrete:エイリアスメソッドまたはオプションでテーブルルックアップメソッドを使用して、一般的な離散分布から擬似乱数を生成します。

連続的な分布

  • random_beta:ベータ分布から擬似乱数を生成します。
  • random_cauchy:コーシー分布から擬似乱数を生成します。
  • random_chi_squared:カイ2乗分布から擬似乱数を生成します。
  • random_exponential:標準の指数分布から擬似乱数を生成します。
  • random_exponential_mix:標準の指数分布から擬似乱数混合数を生成します。
  • random_gamma:標準のガンマ分布から擬似乱数を生成します。
  • random_lognormal:対数正規分布から擬似乱数を生成します。
  • random_normal:標準正規分布から擬似乱数を生成します。
  • random_stable:一般的な離散分布から擬似乱数を生成するテーブルを設定します。
  • random_student_t:スチューデントのt分布から擬似乱数を生成します。
  • random_triangular:三角分布から擬似乱数を生成します。
  • random_uniform:一様(0、1)分布から擬似乱数を生成します。
  • random_von_mises:フォンミーゼス分布から擬似乱数を生成します。
  • random_weibull:ワイブル分布から擬似乱数を生成します。
  • random_general_continuous:一般的な連続分布から擬似乱数を生成します。

多変量連続分布

  • random_normal_multivariate:多変量正規分布から擬似乱数を生成します。
  • random_orthogonal_matrix:擬似ランダム直交行列または相関行列を生成します。
  • random_mvar_from_data:与えられたサンプルから決定された多変量分布から擬似乱数を生成します。
  • random_multinomial:多項分布から擬似乱数を生成します。
  • random_sphere:単位円またはK次元の球上に擬似ランダムポイントを生成します。
  • random_table_twoway:擬似ランダムな双方向テーブルを生成します。

注文統計

  • random_order_normal:標準正規分布から擬似ランダムな順序統計を生成します。
  • random_order_uniform:一様(0、1)分布から擬似ランダムな順序統計を生成します。

確率過程

  • random_arma:擬似ランダムARMAプロセス番号を生成します。
  • random_npp:非均質ポアソン過程から擬似乱数を生成します。

サンプルと順列

  • random_permutation:擬似ランダム順列を生成します。
  • random_sample_indices:インデックスの単純な擬似ランダムサンプルを生成します。
  • random_sample:有限母集団から単純な擬似ランダムサンプルを生成します。

ユーティリティ機能

  • random_option:一様な(0、1)乗法的合同擬似乱数ジェネレーターを選択します。
  • random_option_get:均一な(0、1)乗法的合同擬似乱数ジェネレーターを取得します。
  • random_seed_get:IMSL乱数ジェネレーターで使用されているシードの現在の値を取得します。
  • random_substream_seed_get:シャッフルを行わない合同ジェネレーターのシードを取得し、さらに100,000個の数字から始まる乱数を生成します。
  • random_seed_set:IMSL乱数ジェネレーターで使用するランダムシードを初期化します。
  • random_table_set:シャッフルされたジェネレーターで使用される現在のテーブルを設定します。
  • random_table_get:シャッフルされたジェネレーターで使用されている現在のテーブルを取得します。
  • random_GFSR_table_set:GFSRジェネレーターで使用される現在のテーブルを設定します。
  • random_GFSR_table_get:GFSRジェネレーターで使用されている現在のテーブルを取得します。
  • random_MT32_init:配列を使用して32ビットMersenne Twisterジェネレーターを初期化します。
  • random_MT32_table_get:32ビットMersenne Twisterジェネレーターで使用されている現在のテーブルを取得します。
  • random_MT32_table_set:32ビットMersenne Twisterジェネレーターで使用される現在のテーブルを設定します。
  • random_MT64_init:配列を使用して64ビットMersenne Twisterジェネレーターを初期化します。
  • random_MT64_table_get:64ビットMersenne Twisterジェネレーターで使用されている現在のテーブルを取得します。
  • random_MT64_table_set:64ビットMersenne Twisterジェネレーターで使用される現在のテーブルを設定します。

低差別性シーケンス

  • faure_next_point:シャッフルされたFaureシーケンスを計算します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.