[英]Rcpp - How to compute a matrix where rowSums is exactly 1
I am trying to create a matrix with random numbers where the rowSums
should exactly be 1. 我试图创建一个随机数矩阵,其中
rowSums
应该是1。
I already have a condition which checks if the rowSums
is not 1 and tries to correct it. 我已经有一个条件来检查
rowSums
是否不是1并尝试纠正它。
When I print out the result it looks correct but if I test if all values are 1 it gives me some FALSE values. 当我打印出结果时,它看起来是正确的,但如果我测试所有值是否为1,它会给我一些FALSE值。
How can I correct that? 我怎么能纠正这个?
library(Rcpp)
cppFunction('
NumericMatrix imembrandc(int n, int k) {
NumericMatrix u( n , k );
IntegerVector sequ = seq(1,100);
NumericVector sampled;
for (int i=0; i < k; ++i) {
sampled = sample(sequ, n);
u(_,i) = sampled / sum(sampled);
}
if (is_true(any(rowSums(u) != 1))) {
u(_,1) = u(_,1) + (1 - rowSums(u));
}
return(u);
}')
When I print out the rowSums
of the result it looks correct: 当我打印出结果的
rowSums
时,它看起来是正确的:
res = imembrandc(n = 10, k = 5)
rowSums(res)
[1] 1 1 1 1 1 1 1 1 1 1
[1] 1 1 1 1 1 1 1 1 1 1
But checking it gives some FALSEs: 但检查它会产生一些错误:
rowSums(res) == 1
[1] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE FALSE TRUE
[1] TRUE TRUE TRUE TRUE FUE FALSE TRUE FUE FUE FALSE TRUE
The canonical way to generate n
random numbers that sum to 1 is to generate n - 1
values from [0,1)
, add 0 and 1 to the list and take the difference of the sorted list. 生成总和为1的
n
随机数的规范方法是从[0,1)
生成n - 1
值,将0和1加到列表中并获取排序列表的差异。 Of course, this depends on the distribution you want for the random numbers. 当然,这取决于随机数所需的分布。 This can be expressed in R as
这可以用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
Created on 2019-05-24 by the reprex package (v0.2.1) 由reprex包创建于2019-05-24(v0.2.1)
In your case in C++: 在你的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)))
*/
Note that I am generating rows to begin with, while you were generating columns and then tried to correct the rowSum
. 请注意,我正在生成行,而您正在生成列,然后尝试更正
rowSum
。 Output: 输出:
> 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
BTW, all.equal
gives TRUE
also for your matrix, since the difference is really small. BTW,
all.equal
也为你的矩阵提供TRUE
,因为差异非常小。 But I find it better to avoid the problem from the beginning. 但我发现从一开始就避免这个问题会更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.