통계 컴퓨팅을위한 C ++ 라이브러리


23

C / C ++로 이식하려는 특정 MCMC 알고리즘이 있습니다. 비싼 계산의 많은 부분이 이미 Cython을 통해 C로 이루어졌지만 전체 샘플러를 컴파일 된 언어로 작성하여 Python / R / Matlab / 무엇이든 래퍼를 작성할 수 있기를 원합니다.

주위를 파고 난 후 C ++에 기대어 있습니다. 내가 아는 관련 라이브러리는 Armadillo (http://arma.sourceforge.net/)와 Scythe (http://scythe.wustl.edu/)입니다. 둘 다 R / Matlab의 일부 측면을 모방하여 학습 곡선을 완화하려고합니다. 내가하고 싶은 일에 낫 사각형이 조금 나아졌습니다. 특히, RNG에는 Armadillo가 균일 / 정규만을 갖는 많은 분포가 포함되어있어 불편합니다. Armadillo는 꽤 활발한 개발을 진행하고있는 반면 Scythe는 2007 년 마지막 릴리스를 보았습니다.

그래서 내가 궁금한 것은 누군가이 라이브러리에 대해 경험이 있거나 거의 필자가 놓친 다른 라이브러리에 대해 경험하고 있다면 그렇다면 Python / R / Matlab에 매우 익숙한 통계 전문가에게 다른 것을 추천 할 것이 있는지 여부입니다. 그러나 컴파일 된 언어의 경우에는 그렇지 않습니다 (완전히 무지하지는 않지만 정확하게 능숙하지는 않습니다 ...).

답변:


18

우리는 Rcpp 패키지 를 통해 C ++에서 R래핑 하는 것이 훨씬 쉬워 졌습니다 .

그리고 선형 대수학은 이미 잘 이해되고 코딩 된 분야이기 때문에 , 현재, 현대적이고, 유쾌하고, 잘 정리되고, 작고, 템플릿 화 된, 라이브러리 인 Armadillo 는 우리의 첫 번째 확장 래퍼에 매우 적합했습니다 : RcppArmadillo .

이것은 다른 MCMC 사용자의 관심을 끌었습니다. 나는 지난 여름 로체스터 대학 경영 대학원에서 하루 동안 일을했으며 비슷한 연구를 통해 MidWest의 다른 연구원을 도왔습니다. 부여 RcppArmadillo을 시도 - 그것은 적극적으로 유지, 잘 작동 및 지원 (새 아르마 자료를 1.1.4 오늘, 나는 새로운 나중에 RcppArmadillo를 만들 것입니다).

그리고 나는이 예제를 너무 많이 좋아하기 때문에, 여기에 lm()반환 계수와 표준 오류 의 빠른 "빠른"버전이 있습니다 .

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
}

마지막으로 인라인 을 통해 즉각적인 프로토 타이핑을 통해 '코딩 시간'을 단축 할 수 있습니다.


고마워요 더크-나는 당신이 나중에보다 빨리 대답 할 느낌이 들었습니다. :). 다른 소프트웨어 (주로 Python이지만 Matlab도 마찬가지)에서 호출 할 수있는 코드를 원한다면 Rcpp / RcppArmadillo에서 프로토 타입을 만들고 "직선적 인"Armadillo로 옮기는 것이 좋은 워크 플로우 일 것입니다. 구문 등은 매우 비슷합니다.
JMS

1
도움이 되셨기를 바랍니다.
Dirk Eddelbuettel

편집에서 두 번째 질문을 다시하십시오 : 물론. Armadillo는 R 또는 R의 경우에 거의 의존하지 않으며 R. Rcpp / RcppArmadillo는 독립형으로 재사용하거나 나중에 추가 할 수있는 Python 및 Matlab 래퍼로 프로토 타입 코드를 인터페이스하고 테스트하는 데 도움이됩니다. 콘래드는 무언가에 대한 포인터를 가질 수 있습니다. 파이썬이나 Matlab에는 없습니다.
Dirk Eddelbuettel

깔개를 꺼내서 죄송합니다 :) Enter 키를 사용하여 캐리지 리턴을 원하지만 대신 내 의견을 제출합니다. 어쨌든, 당신의 도움에 감사드립니다-나는 오늘 하루 종일 Rcpp 메일 링리스트를 통해 땜질을하고 파고 들었습니다.
JMS

8

난 강력하게 당신이 봐 가지고 제안 RCppRcppArmadillo에 대한 패키지를 R. 기본적으로 래퍼는 이미 "포함"되어 있으므로 걱정할 필요가 없습니다. 또한 구문 설탕은 정말 달콤합니다 (말장난 의도).

부수적으로, JAGSMCMC를 수행하고 소스 코드가 C ++로되어있는를 살펴 보는 것이 좋습니다 .


2
두 번째로 싶습니다. 당신은 빠르고 쉬운 방법을 찾고 있다면, R 사용하여 코드를 컴파일 인터페이스에 Rcpp함께 RcppArmadillo갈 수있는 방법입니다. 편집 : Rcpp를 사용하면 R에 기반한 C 코드에 포함 된 모든 RNG에 액세스 할 수 있습니다.
fabians

자신감을 가져 주셔서 감사합니다. 나는 같은 것을 제안하려고했다 ;-)
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 라이브러리도 사용할 수 있습니다.


팁 고마워. 부스트는 내 작은 손톱에는 큰 망치처럼 보이지만 성숙하고 유지됩니다.
JMS

boot :: math :: binomial_distribution이 R binom.test ()에서 구현 된 것과 동일한 기능을 가지고 있는지 잘 모르겠습니다. 참조를 보았고이 기능을 찾을 수 없습니다. 나는 이것을 구현하려고 시도했지만 사소한 것이 아니다!
Kemin Zhou

1

많은 특정 C / C ++ 라이브러리가 있으며 그 중 특정 문제 영역 (예 : PDE 솔버)에 중점을 둡니다. C로 작성되었지만 훌륭한 파이썬 래퍼가 이미 작성되어 있기 때문에 특히 유용하다고 생각할 수있는 두 가지 포괄적 인 라이브러리가 있습니다.

1) IMSL CPyIMSL

2) trilinospytrilinos

기능이 주로 수치 분석 방법이므로 trilinos를 사용한 적이 없지만 통계 작업에 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 : Cauchy 분포에서 의사 난수를 생성합니다.
  • random_chi_squared : 카이 제곱 분포에서 의사 난수를 생성합니다.
  • 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 : 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 : 셔플 링을 수행하지 않는 합동 생성기의 시드를 검색하여 10 만 숫자로 시작하는 난수를 생성합니다.
  • 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.