用于统计计算的C ++库


23

我有一个特定的MCMC算法,我想移植到C / C ++。许多昂贵的计算已经通过Cython用C语言编写,但是我希望整个采样器都以编译语言编写,这样我就可以为Python / R / Matlab /任何东西编写包装器。

闲逛之后,我倾向于使用C ++。我知道的几个相关库是Armadillo(http://arma.sourceforge.net/)和Scythe(http://scythe.wustl.edu/)。两者都试图模仿R / Matlab的某些方面以简化学习曲线,这是我非常喜欢的。镰刀使我想做的事情变得更好。特别是,其RNG包含很多分布,其中Armadillo仅具有统一/正态分布,这很不方便。镰刀(Scythe)于2007年发布其最新版本时,犰狳似乎处于相当活跃的开发状态。

因此,我想知道的是,是否有人有使用这些库的经验,或者我几乎肯定会错过的其他库,如果是这样,对于非常熟悉Python / R / Matlab的统计学家,是否有什么值得推荐的?但是对于编译语言却不是这样(不是完全无知,但不是完全精通...)。

Answers:


18

我们已经花了一些时间通过我们的Rcpp包使从C ++到R包装变得容易(然后再返回)。

而且由于线性代数已经是一个易于理解和编码的领域,因此,Armadillo是当前,现代,令人愉悦,饱满,小巧,模板化的...库,非常适合我们的第一个扩展包装:RcppArmadillo

这也引起了其他MCMC用户的注意。去年夏天,我在罗切斯特大学商学院做了一天的工作,并通过类似的探索帮助了中西部的另一位研究人员。给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
希望对您有所帮助。
Dirk Eddelbuettel 2011年

重新输入您的第二个问题:确定。Armadillo几乎没有依赖,或者在我们的情况下,除了R. Rcpp / RcppArmadillo之外,什么都不会帮助您进行接口和测试原型代码,这些代码可以独立使用,也可以与以后添加的Python和Matlab包装器一起使用。康拉德可能对某事有指点。我没有适用于Python或Matlab的任何软件。
Dirk Eddelbuettel 2011年

抱歉,把地毯拉出来了:)我想输入回车键,以回车,但是它提交了我的评论。无论如何,感谢您的帮助-我一直很开心,整天都在自己整理和浏览Rcpp邮件列表。
JMS

8

我强烈建议您查看RCpp和的RcppArmadillo软件包R。基本上,您不必担心包装器,因为它们已经被“包含”了。此外,语法糖真的很甜(双关语意味深长)。

附带说明一下,我建议您先看一下JAGS,它使用MCMC进行操作,其源代码使用C ++。


2
我想第二次。如果你正在寻找一个快速简便的方法,接口编译的代码与R,RcppRcppArmadillo是要走的路。编辑:使用RCPP,你也可以访问所有的C代码底层R. implmented的随机数发生器
费边社

感谢您的信任投票。我将提出相同的建议;-)
Dirk Eddelbuettel

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库,该库具有多种不同的矩阵类型和运算。


谢谢你的提示。Boost看起来就像是我的小指甲的大锤子,但成熟且保持。
JMS

我不确定boot :: math :: binomial_distribution是否具有与R binom.test()双面实现的功能相同的功能。我调查了参考资料,但找不到此功能。我试图实现这一点,但这并不简单!
Kemin Zhou '18

1

有许多C / C ++库,其中大多数集中在特定的问题领域(例如PDE求解器)。我可以想到两个综合库,它们可能特别有用,因为它们是用C编写的,但是已经编写了出色的Python包装器。

1)IMSL CPyIMSL

2)trilinospytrilinos

我从未使用过trilinos,因为该功能主要用于数值分析方法,但是我在统计工作中经常使用PyIMSL(在以前的工作生涯中,我也开发了该软件)。

关于RNG,以下是IMSL中C和Python中的RNG

离散

  • random_binomial:从二项分布生成伪随机二项数。
  • random_geometric:根据几何分布生成伪随机数。
  • random_hypergeometric:从超几何分布生成伪随机数。
  • random_logarithmic:从对数分布生成伪随机数。
  • random_neg_binomial:从负二项分布生成伪随机数。
  • random_poisson:从泊松分布生成伪随机数。
  • random_uniform_discrete:从离散的均匀分布生成伪随机数。
  • random_general_discrete:使用别名方法或可选的表查找方法从常规离散分布生成伪随机数。

连续连续分布

  • random_beta:从beta分布生成伪随机数。
  • random_cauchy:从柯西分布中生成伪随机数。
  • random_chi_squared:从卡方分布中生成伪随机数。
  • random_exponential:根据标准指数分布生成伪随机数。
  • random_exponential_mix:从标准指数分布生成伪随机混合数。
  • random_gamma:从标准的gamma分布生成伪随机数。
  • random_lognormal:根据对数正态分布生成伪随机数。
  • random_normal:从标准正态分布生成伪随机数。
  • random_stable:设置一个表,以根据一般的离散分布生成伪随机数。
  • random_student_t:根据学生的t分布生成伪随机数。
  • random_triangular:从三角形分布生成伪随机数。
  • random_uniform:从均匀(0,1)分布生成伪随机数。
  • random_von_mises:从von Mises分布生成伪随机数。
  • random_weibull:从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序列。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.