2017-01-24 1 views
3

기본적으로 복사하는 함수를 작성하려고합니다 : [z;-z]z = randn(m,n) m-by-n 무작위 항목의 매트릭스. 나는 아래에있는 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 가게에서 찍은 기능을 만드는 생각하고 해당 항목을 다른 행렬 또는 벡터에 배치 한 다음 관련 항목을 올바른 (i,j) 위치에 배치하기 위해 크기가 두 배로 된 새 행렬 또는 벡터를 만듭니다.

진행 방법을 잘 모르겠습니다. 모든 의견이나 제안은 대단히 감사하겠습니다. 부수적으로, 나는 C++의 초심자이다.

답변

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; 
난 당신이 대신 'J'로 시작 순서를 전환하여 말을 하려는지 누락 될 수 있습니다
+0

코드는 내 대답과 같을 것이다. 연결없이 직접 출력을 계산하므로 응답에 적합하지 않습니다. 원래 게시물의 코드를 연결하려면 자체 게시물을 사용해야합니다. – anatolyg

+0

@anatolyg 아, 그 한 줄을 지우는 걸 잊었 네. 간단히 말해 데이터를 채우기 위해 빌린 것입니다. 업데이트되었습니다. – Suever

+0

두 번째 부분 (행렬을 수직으로 연결)과 약간 혼동되어 있습니다. 왜 행이 두 배가되고 열이 아닌가? 예제에서 2 x 2 행렬은 4 x 4가되므로 행과 열 모두가 두 배가됩니다. – 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 행렬을 채우는 코드를 사용하고, 2m 별 N 매트릭스에이 행렬을 "두 배로"고 코드의 또 다른 조각을 추가 할 수 있습니다.

그러나 C++에서는 대개 적절한 크기를 즉시 할당해야하며 한 번만 수행합니다.

즉 :

MatrixXd M(2 * n, m); 

(사이드 참고로, 당신의 행렬 여부를 결정하시기 바랍니다 m 별 n 또는 n 형으로-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; 
    } 
} 

, 두 개의 연속적인 반복은 대부분 더 나은 성능을해야합니다 메모리에 이웃 주소로 작성합니다.

+0

'나는'. 내가 큰 매트릭스를 가질 것이라면 첫 번째 for 루프에서 'j'로 시작해야한다는 정규적으로 분산 된 난수를 생성하는 함수에 대해 말하고 있습니까? 내 혼란에 대한 사과 – Scooby

+0

또한 열이 왜 두 배가되고 행이 아닌가? 내 예제에서 2 x 2 행렬은 4 x 4 행렬이된다. – Scooby