始める無料で始める

混合分布からのサンプリング(II)

混合分布からサンプリングする完全なアルゴリズムは次のとおりです。

  1. コンポーネントを1つ選びます。
  2. 選ばれたコンポーネントの平均と標準偏差を使って、正規乱数を生成します。

前の演習で作成した choose_component() は用意されています。ここでは2つ目のステップを仕上げ、rmix() の定義を完成させます。

この演習はコースの一部です

Rcpp で R コードを最適化する

コースを見る

演習の手順

  • 標準偏差の数が重みの数と同じであることを確認します。つまり、sds のサイズが d と同じであることを確認します。
  • total_weight を、重みの合計として計算します。
  • choose_component() を呼び出して、コンポーネントを選びます。
  • 選ばれたコンポーネントから、meanssdsj 番目の要素を使って正規乱数を生成し、シミュレーションします。

実践的なインタラクティブ演習

このサンプルコードを完成させて、この演習に挑戦してみましょう。

#include 
using namespace Rcpp;

// From previous exercise; do not modify
// [[Rcpp::export]]
int choose_component(NumericVector weights, double total_weight) {
  double x = R::runif(0, total_weight);
  int j = 0;
  while(x >= weights[j]) {
    x -= weights[j];
    j++;
  }
  return j;
}

// [[Rcpp::export]]
NumericVector rmix(int n, NumericVector weights, NumericVector means, NumericVector sds) {
  // Check that weights and means have the same size
  int d = weights.size();
  if(means.size() != d) {
    stop("means size != weights size");
  }
  // Do the same for the weights and std devs
  if(___) {
    stop("sds size != weights size");
  }
  
  // Calculate the total weight
  double total_weight = ___;
  
  // Create the output vector
  NumericVector res(n);
  
  // Fill the vector
  for(int i = 0; i < n; i++) {
    // Choose a component
    int j = ___(___, ___);
    
    // Simulate from the chosen component
    res[i] = ___::___(___, ___);
  }
  
  return res;
}

/*** R
  weights <- c(0.3, 0.7)
  means <- c(2, 4)
  sds <- c(2, 4)
  rmix(10, weights, means, sds)
*/
コードを編集して実行