混合分布からのサンプリング(II)
混合分布からサンプリングする完全なアルゴリズムは次のとおりです。
- コンポーネントを1つ選びます。
- 選ばれたコンポーネントの平均と標準偏差を使って、正規乱数を生成します。
前の演習で作成した choose_component() は用意されています。ここでは2つ目のステップを仕上げ、rmix() の定義を完成させます。
この演習はコースの一部です
Rcpp で R コードを最適化する
演習の手順
- 標準偏差の数が重みの数と同じであることを確認します。つまり、
sdsのサイズがdと同じであることを確認します。 total_weightを、重みの合計として計算します。choose_component()を呼び出して、コンポーネントを選びます。- 選ばれたコンポーネントから、
meansとsdsのj番目の要素を使って正規乱数を生成し、シミュレーションします。
実践的なインタラクティブ演習
このサンプルコードを完成させて、この演習に挑戦してみましょう。
#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)
*/