Thư viện C ++ để tính toán thống kê


23

Tôi đã có một thuật toán MCMC cụ thể mà tôi muốn chuyển sang C / C ++. Phần lớn tính toán đắt tiền đã có trong C qua Cython, nhưng tôi muốn có toàn bộ bộ lấy mẫu được viết bằng ngôn ngữ được biên dịch để tôi có thể viết các hàm bao cho Python / R / Matlab / bất cứ thứ gì.

Sau khi chọc ngoáy tôi đang nghiêng về C ++. Một vài thư viện có liên quan mà tôi biết là Armadillo (http://arma.sourceforge.net/) và Scythe (http://scythe.wustl.edu/). Cả hai đều cố gắng mô phỏng một số khía cạnh của R / Matlab để giảm bớt quá trình học tập, điều mà tôi rất thích. Scythe hình vuông tốt hơn một chút với những gì tôi muốn làm tôi nghĩ. Đặc biệt, RNG của nó bao gồm rất nhiều bản phân phối trong đó Armadillo chỉ có đồng phục / bình thường, điều này bất tiện. Armadillo dường như đang được phát triển khá tích cực trong khi Scythe thấy bản phát hành cuối cùng vào năm 2007.

Vì vậy, điều tôi băn khoăn là liệu có ai có kinh nghiệm với các thư viện này - hoặc những người khác mà tôi gần như chắc chắn đã bỏ lỡ - và nếu vậy, liệu có bất cứ điều gì để giới thiệu một người khác cho một thống kê rất quen thuộc với Python / R / Matlab nhưng ít hơn với các ngôn ngữ được biên dịch (không hoàn toàn không biết gì, nhưng không chính xác thành thạo ...).

Câu trả lời:


18

Chúng tôi đã dành một chút thời gian để việc gói từ C ++ thành R (và trở lại vấn đề đó) dễ dàng hơn rất nhiều thông qua gói Rcpp của chúng tôi .

Và bởi vì đại số tuyến tính đã là một lĩnh vực được hiểu và mã hóa như vậy, Armadillo , một thư viện hiện tại, hiện đại, đầy đủ, có tài liệu tốt, nhỏ, templated, ... rất phù hợp với trình bao bọc mở rộng đầu tiên của chúng tôi: RcppArmadillo .

Điều này cũng đã thu hút sự chú ý của những người dùng MCMC khác. Tôi đã cho một công việc một ngày tại trường kinh doanh U of Rochester vào mùa hè năm ngoái và đã giúp một nhà nghiên cứu khác ở MidWest với những chuyến thám hiểm tương tự. Hãy dùng thử RcppArmadillo - nó hoạt động tốt, được duy trì tích cực (bản phát hành Armadillo mới 1.1.4 hôm nay, tôi sẽ tạo RcppArmadillo mới sau) và được hỗ trợ.

Và bởi vì tôi chỉ thích ví dụ này rất nhiều, nên đây là phiên bản "nhanh" của lm()hệ số trả về và 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
}

Cuối cùng, bạn cũng có thể tạo mẫu ngay lập tức thông qua nội tuyến , điều này có thể khiến 'thời gian để mã hóa' nhanh hơn.


Cảm ơn Dirk - Tôi có cảm giác bạn sẽ trả lời sớm hơn là sau :). Cho rằng tôi muốn mã, tôi có thể gọi từ phần mềm khác (chủ yếu là Python, nhưng Matlab cũng vậy) có lẽ một quy trình làm việc tốt sẽ là nguyên mẫu trong Rcpp / RcppArmadillo và sau đó chuyển sang "Armadillo" thẳng? Cú pháp, vv trông rất giống nhau.
JMS

1
Hy vọng bạn tìm thấy nó hữu ích.
Dirk Eddelbuettel

Re câu hỏi thứ 2 của bạn từ chỉnh sửa: Chắc chắn. Armadillo phụ thuộc rất ít, hoặc trong trường hợp của chúng tôi, không có gì ngoài R. Rcpp / RcppArmadillo sẽ giúp bạn giao diện và kiểm tra mã nguyên mẫu có thể được sử dụng lại độc lập hoặc với trình bao bọc Python và Matlab bạn có thể thêm sau này. Conrad có thể có con trỏ cho một cái gì đó; Tôi không có bất kỳ cho Python hoặc Matlab.
Dirk Eddelbuettel

Xin lỗi để kéo tấm thảm ra :) Tôi muốn phím enter trả lại xe, nhưng nó sẽ gửi bình luận của tôi thay vào đó. Dù sao đi nữa, cảm ơn sự giúp đỡ của bạn - Tôi đã tận hưởng việc tự mày mò và tìm hiểu lại danh sách gửi thư Rcpp cả ngày hôm nay.
JMS

8

Tôi mạnh mẽ đề nghị bạn nên xem RCppRcppArmadillogói cho R. Về cơ bản, bạn sẽ không cần phải lo lắng về các trình bao bọc vì chúng đã được "bao gồm". Hơn nữa, đường cú pháp thực sự ngọt ngào (ý định chơi chữ).

Như một nhận xét phụ, tôi khuyên bạn nên xem JAGS, MCMC và mã nguồn của nó có trong C ++.


2
Tôi muốn thứ hai này. Nếu bạn đang tìm kiếm một nhanh chóng và dễ dàng với giao diện biên soạn mã với R, Rcppvới RcppArmadillolà con đường để đi. Chỉnh sửa: Sử dụng Rcpp, bạn cũng có quyền truy cập vào tất cả các
RNG được cấy

Cảm ơn đã bỏ phiếu tín nhiệm. Tôi cũng đề nghị như vậy ;-)
Dirk Eddelbuettel

7

Boost Random từ các thư viện Boost C ++ có thể phù hợp với bạn. Ngoài nhiều loại RNG, nó cung cấp nhiều loại phân phối khác nhau để rút ra, chẳng hạn như

  • Đồng phục (thật)
  • Đồng phục (hình cầu đơn vị hoặc kích thước tùy ý)
  • Bernoulli
  • Nhị thức
  • Cauchy
  • Gamma
  • Chất độc
  • Hình học
  • Tam giác
  • số mũ
  • Bình thường
  • Không thường xuyên

Ngoài ra, Boost Math bổ sung cho các bản phân phối ở trên mà bạn có thể lấy mẫu từ nhiều hàm mật độ của nhiều bản phân phối. Nó cũng có một số chức năng trợ giúp gọn gàng; chỉ để cung cấp cho bạn một ý tưởng:

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;
}

Nếu bạn quyết định sử dụng Boost, bạn cũng có thể sử dụng thư viện UBLAS của nó có nhiều loại ma trận và hoạt động khác nhau.


Cảm ơn vì tiền hỗ trợ. Boost trông giống như một cái búa lớn cho móng tay nhỏ của tôi, nhưng trưởng thành và được duy trì.
JMS

Tôi không chắc boot :: math :: binomial_distribution có chức năng tương tự như được thực hiện trong R binom.test () hai mặt. Tôi nhìn vào tài liệu tham khảo và không thể tìm thấy chức năng này. Tôi đã cố gắng thực hiện điều này, và nó không tầm thường!
Kemin Zhou

1

Có rất nhiều thư viện C / C ++, hầu hết tập trung vào một miền vấn đề cụ thể của (ví dụ: bộ giải PDE). Có hai thư viện toàn diện mà tôi có thể nghĩ rằng bạn có thể thấy đặc biệt hữu ích vì chúng được viết bằng C nhưng có các trình bao bọc Python tuyệt vời đã được viết.

1) IMSL CPyIMSL

2) trilinospytrilinos

Tôi chưa bao giờ sử dụng trilinos vì chức năng chủ yếu là các phương pháp phân tích số, nhưng tôi sử dụng PyIMSL rất nhiều cho công việc thống kê (và trong kiếp trước tôi cũng đã phát triển phần mềm).

Đối với RNG, đây là những người trong C và Python trong IMSL

KHÁM PHÁ

  • Random_binomial: Tạo số nhị phân giả ngẫu nhiên từ phân phối nhị thức.
  • Random_geometric: Tạo số giả ngẫu nhiên từ một phân phối hình học.
  • Random_hypergeometric: Tạo số giả ngẫu nhiên từ phân phối siêu bội.
  • Random_logarithmic: Tạo số giả ngẫu nhiên từ phân phối logarit.
  • Random_neg_binomial: Tạo số giả ngẫu nhiên từ phân phối nhị thức âm.
  • Random_poisson: Tạo số giả ngẫu nhiên từ phân phối Poisson.
  • Random_uniform_discittle: Tạo số giả ngẫu nhiên từ một phân phối thống nhất rời rạc.
  • Random_general_discittle: Tạo số giả ngẫu nhiên từ một phân phối rời rạc chung bằng phương pháp bí danh hoặc tùy chọn phương pháp tra cứu bảng.

PHÂN PHỐI TIẾP TỤC LIÊN TỤC

  • Random_beta: Tạo số giả ngẫu nhiên từ bản phân phối beta.
  • Random_cauchy: Tạo số giả ngẫu nhiên từ một bản phân phối Cauchy.
  • Random_chi_squared: Tạo số giả ngẫu nhiên từ phân phối chi bình phương.
  • Random_exponential: Tạo số giả ngẫu nhiên từ phân phối theo cấp số nhân tiêu chuẩn.
  • Random_exponential_mix: Tạo các số hỗn hợp giả từ một phân phối hàm mũ tiêu chuẩn.
  • Random_gamma: Tạo số giả ngẫu nhiên từ phân phối gamma tiêu chuẩn.
  • Random_logn normal: Tạo số giả ngẫu nhiên từ một phân phối hợp lý.
  • Random_n normal: Tạo số giả ngẫu nhiên từ một phân phối chuẩn thông thường.
  • Random_urdy: Thiết lập bảng để tạo số giả ngẫu nhiên từ một phân phối rời rạc chung.
  • Random_student_t: Tạo số giả ngẫu nhiên từ phân phối t của Sinh viên.
  • Random_triangular: Tạo số giả ngẫu nhiên từ phân phối tam giác.
  • Random_uniform: Tạo số giả ngẫu nhiên từ phân phối thống nhất (0, 1).
  • Random_von_mises: Tạo số giả ngẫu nhiên từ phân phối von Mises.
  • Random_weibull: Tạo số giả ngẫu nhiên từ phân phối Weibull.
  • Random_general_continupt: Tạo số giả ngẫu nhiên từ một phân phối liên tục chung.

PHÂN PHỐI LIÊN TỤC ĐA NĂNG

  • Random_n normal_multivariate: Tạo số giả ngẫu nhiên từ một phân phối bình thường nhiều biến số.
  • Random_orthogonal_matrix: Tạo ma trận trực giao giả ngẫu nhiên hoặc ma trận tương quan.
  • Random_mvar_from_data: Tạo số giả ngẫu nhiên từ một phân phối đa biến được xác định từ một mẫu nhất định.
  • Random_multinomial: Tạo số giả ngẫu nhiên từ một phân phối đa quốc gia.
  • Random_sphere: Tạo các điểm giả ngẫu nhiên trên vòng tròn đơn vị hoặc hình cầu K-chiều.
  • Random_table_twoway: Tạo bảng hai chiều giả ngẫu nhiên.

THỐNG KÊ ĐẶT HÀNG

  • Random_order_n normal: Tạo thống kê đơn đặt hàng giả từ một phân phối chuẩn thông thường.
  • Random_order_uniform: Tạo thống kê đơn đặt hàng giả từ phân phối thống nhất (0, 1).

CÁC QUY TRÌNH NGẪU NHIÊN

  • Random_arma: Tạo số quy trình ARMA giả.
  • Random_npp: Tạo số giả ngẫu nhiên từ quá trình Poisson không đồng nhất.

MẪU VÀ GIẤY PHÉP

  • Random_permuting: Tạo hoán vị giả ngẫu nhiên.
  • Random_sample_indices: Tạo một mẫu chỉ số giả đơn giản.
  • Random_sample: Tạo một mẫu giả ngẫu nhiên đơn giản từ một dân số hữu hạn.

CÁC CHỨC NĂNG TIỆN ÍCH

  • Random_option: Chọn bộ tạo số giả ngẫu nhiên đồng nhất (0, 1).
  • Random_option_get: Lấy ra bộ tạo số giả ngẫu nhiên đồng nhất (0, 1).
  • Random_seed_get: Lấy giá trị hiện tại của hạt giống được sử dụng trong các trình tạo số ngẫu nhiên IMSL.
  • Random_substream_seed_get: Lấy một hạt giống cho các trình tạo đồng quy không xáo trộn sẽ tạo ra các số ngẫu nhiên bắt đầu 100.000 số xa hơn.
  • Random_seed_set: Khởi tạo một hạt giống ngẫu nhiên để sử dụng trong các trình tạo số ngẫu nhiên IMSL.
  • Random_table_set: Đặt bảng hiện tại được sử dụng trong trình tạo được xáo trộn.
  • Random_table_get: Lấy bảng hiện tại được sử dụng trong trình tạo được xáo trộn.
  • Random_GFSR_table_set: Đặt bảng hiện tại được sử dụng trong trình tạo GFSR.
  • Random_GFSR_table_get: Lấy bảng hiện tại được sử dụng trong trình tạo GFSR.
  • Random_MT32_init: Khởi tạo trình tạo Mersenne Twister 32 bit bằng một mảng.
  • Random_MT32_table_get: Lấy bảng hiện tại được sử dụng trong trình tạo Mersenne Twister 32 bit.
  • Random_MT32_table_set: Đặt bảng hiện tại được sử dụng trong trình tạo Mersenne Twister 32 bit.
  • Random_MT64_init: Khởi tạo trình tạo Mersenne Twister 64 bit bằng một mảng.
  • Random_MT64_table_get: Lấy bảng hiện tại được sử dụng trong trình tạo Mersenne Twister 64 bit.
  • Random_MT64_table_set: Đặt bảng hiện tại được sử dụng trong trình tạo Mersenne Twister 64 bit.

YÊU CẦU THẤP

  • faure_next_point: Tính toán chuỗi Faure bị xáo trộn.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.