2017-01-24 1 views
3

基本的にはmatlabコマンドをコピーする関数を作成しようとしています:[z;-z]z = randn(m,n) m-ランダムエントリーの行列。私は以下の通りです関数randnのためにC++で関数を作成することができました:Matlab演算[z; z]を実行する関数をC++で作成すると、zは行列またはベクトルです

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店で撮影した関数を作成されて考えていますそれらのエントリを別の行列またはベクトルに格納し、次に、サイズが2倍になった新しい行列またはベクトルを作成して、関連するエントリを正しい(i,j)の位置に配置します。

これがどうすればいいのかわかりません。ご意見やご提案をいただければ幸いです。補足として、私はまだC++の初心者です。

答えて

3

マトリックス内のrowscolsを使用して、出力マトリックスを正しいサイズに初期化する必要があります。あなたは、私はあなたが「J」で始まる代わりの順序を切り替えることで言おうとしているもの欠落している可能性があり、垂直同じ行列

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; 
+0

コードは私の答えと同じようです。連結なしで直接出力を計算するので、答えに収まらない。元の投稿のコードは、自分自身に連結するときに使用してください。 – anatolyg

+0

@anatolygおっと、その1行を削除するのを忘れてしまった。完全な例としてデータを取り込むために単純に借用しました。今更新されました – Suever

+0

2番目の部分(行列を垂直に連結)とちょっと混乱していますが、なぜ列が2倍になっていて列が正しくないのですか?私の例では、2行2列の行列は4行4列になるので、行と列の両方が2倍になると思われます。 – Scooby

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; 
1

あなたはm行n列の行列を満たし、あなたのコードを使用して、2メートル行n列の行列にこの行列を「倍増」というコードの別の部分を追加することができます。

しかし、C++では通常、すぐに適切なディメンションを割り当てて1回だけ行うことになっています。

です:

MatrixXd M(2 * n, m); 

(サイドノートとして、あなたの行列は、mのn-によって、またはn行mであるかどうかを判断してください。これは、混乱を防ぐために非常に重要である)

あなたのマトリックスを充填しながら

次に、各繰り返しでの2つの要素を記述します。

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; 
    } 
} 

、二つの連続する反復が最も可能性の高い優れた性能を持つことになりますメモリ内の隣接アドレスに書き込みます。

+0

のマイナスと1つのマトリックスを連結することで、この行列を埋めるためにcomma initializer syntaxを使用することができます'私'。あなたは、私は大きな行列を持つつもりなら、私は最初のforループで 'j'で始める必要がある正規分布乱数を生成する私の関数のために言っていますか?私の混乱のためのお詫び – Scooby

+0

また、なぜ列が倍増していて、列も同じではないのですか?私の例では、2行2列の行列は4行4列の行列になります – Scooby

関連する問題