在C ++中创建一个执行Matlab操作的函数[z; z]其中z是一个矩阵或向量

时间:2017-01-24 20:26:39

标签: c++ matlab eigen

我正在尝试创建一个基本上复制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 ++中仍然是一个新手。

3 个答案:

答案 0 :(得分:3)

您应首先使用矩阵中的rowscols将输出矩阵初始化为正确的大小。然后,您可以使用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;