我正在尝试创建一个基本上复制matlab命令的函数:[z;-z]
其中z = randn(m,n)
返回m-by-n随机条目矩阵。我能够在C ++中为randn函数创建一个函数,如下所示:
MatrixXd generateGaussianNoise(int n, int m){
MatrixXd M(n,m);
normal_distribution<double> nd(0.0, 1.0);
random_device rd;
mt19937 gen(rd());
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
M(i,j) = nd(gen);
}
}
return M;
}
现在我需要创建[z;-z]
函数。例如,让我们说z = randn(2,2)
然后输出将是:
-2.2588 0.3188
0.8622 -1.3077
现在,当我写[z;-z]
时,我们得到:
-2.2588 0.3188
0.8622 -1.3077
2.2588 -0.3188
-0.8622 1.3077
我在想的是创建一个矩阵或向量z
中的函数,将这些条目存储在另一个矩阵或向量中,然后创建一个大小加倍的新矩阵或向量,以便将相关的条目放入正确的(i,j)
职位。
我不确定这是否应该如何进行。任何意见或建议都非常感谢。作为旁注,我在C ++中仍然是一个新手。
答案 0 :(得分:3)
您应首先使用矩阵中的rows
和cols
将输出矩阵初始化为正确的大小。然后,您可以使用comma initializer syntax通过将一个矩阵与相同矩阵的负数垂直连接来填充此矩阵
MatrixXd A(n, m);
normal_distribution<double> nd(0.0, 1.0);
random_device rd;
mt19937 gen(rd());
// Fill up the matrix
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
A(i, j) = nd(gen);
}
}
// Vertically concatenate the matrix with the negative version
MatrixXd B(A.rows() * 2, A.cols());
B << A, -A;
return B;
答案 1 :(得分:1)
您可以使用填充m-by-n矩阵的代码,并添加另一段代码,将此矩阵“加倍”为2m-by-n矩阵。
但是,在C ++中,您通常应该立即分配适当的尺寸,并且只进行一次。
那是:
MatrixXd M(2 * n, m);
(作为附注,请确定您的矩阵是m-by-n还是n-by-m;这对于防止混淆非常重要)
然后,在填充矩阵时,在每次迭代时写下两个元素:
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
double element = nd(gen);
M(i, j) = element;
M(i + n, j) = -element;
}
}
如果您打算使用大型矩阵,您应该记住元素以列主要顺序(unless you decide to override this choice)存储在内存中。这个顺序也被Matlab使用。因此,为了更好地使用大型矩阵,您应该填充它们,以便在另一列之前填充每列。所以你应该切换循环的嵌套顺序:
for(int j = 0; j < m; j++){
for(int i = 0; i < n; i++){
double element = nd(gen);
M(i, j) = element;
M(i + n, j) = -element;
}
}
这里,两次连续迭代将写入内存中的相邻地址,这很可能会有更好的性能。
答案 2 :(得分:0)
我认为这应该足够了吗?
MatrixXd generateGaussianNoise(int n, int m){
MatrixXd M(2*n,m);
normal_distribution<double> nd(0.0, 1.0);
random_device rd;
mt19937 gen(rd());
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
double r = nd(gen);
M(i,j) = r;
M(n+i,j) = -r;
}
}
return M;