Канонический способ для генерации n
случайных чисел, сумма которых равна 1, заключается в генерации n - 1
значений из [0,1)
, добавлении 0 и 1 в список и определении разности отсортированного списка. , Конечно, это зависит от желаемого распределения случайных чисел. Это может быть выражено в R как
set.seed(42)
v <- diff(sort(c(0, runif(5), 1)))
v
#> [1] 0.28613953 0.35560598 0.18870211 0.08435842 0.02226937 0.06292459
sum(v)
#> [1] 1
Создано в 2019-05-24 с помощью пакета Представление (v0.2.1)
В вашем случае в C ++:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix imembrandc(int n, int k) {
NumericMatrix u(n, k);
for (int i = 0; i < n; ++i) {
NumericVector row = runif(k - 1);
row.push_back(0.0);
row.push_back(1.0);
u(i, _) = diff(row.sort());
}
return u;
}
/*** R
set.seed(42)
res = imembrandc(n = 10, k = 5)
rowSums(res)
rowSums(res) == 1
all.equal(rowSums(res),rep(1, nrow(res)))
*/
Обратите внимание, что я генерирую строки для начала, пока вы генерировали столбцы, а затем пытались исправить rowSum
. Выход:
> set.seed(42)
> res = imembrandc(n = 10, k = 5)
> rowSums(res)
[1] 1 1 1 1 1 1 1 1 1 1
> rowSums(res) == 1
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> all.equal(rowSums(res),rep(1, nrow(res)))
[1] TRUE
Кстати, all.equal
дает TRUE
также для вашей матрицы, поскольку разница действительно небольшая. Но я считаю, что лучше избегать проблемы с самого начала.