2016-08-11 2 views
0

Eigen의 함수를 사용하여 코드를 압축하려고합니다. 특히 계수의 계수가있는 제품을 사용할 수 있도록 해 주겠지 만 아마도 사용하고있을 것입니다. 틀리게.고유 벡터 승수와 계수 승 곱셈의 조합

for (int dir = 0; dir < NDIM; dir++) 
    { 
    resultVectorDir[dir].noalias() = bigStoredVolMatrices[dir]* 
     (volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir)))); 
    } 

    for (int i = 0; i < nlocal; i++) 
    { 
    for (int dir = 0; dir < NDIM; dir++) 
     qNewPtr[i] += resultVectorDir[dir](i); 
    } 
: 같은 것을 사용하여,

for (int dir = 0; dir < NDIM; dir++) 
    { 
    resultVectorDir[dir].noalias() = bigStoredVolMatrices[dir]* 
     (volQuad.weights.array()*fAtQuad.array()*alpha.row(dir).array()).matrix(); 
    } 

    for (int i = 0; i < nlocal; i++) 
    { 
    for (int dir = 0; dir < NDIM; dir++) 
     qNewPtr[i] += resultVectorDir[dir](i); 
    } 

또는 배열과 행렬 사이를 전환하지 않고 :

for (int dir = 0; dir < NDIM; dir++) 
    { 
    for (int i = 0; i < nlocal; i++) 
    { 
     for (int qp = 0; qp < nVolQuad; qp++) 
     qNewPtr[i] += 
      volQuad.weights(qp)*bigStoredVolMatrices[dir](i,qp)*alpha(dir,qp)*fAtQuad(qp); 
    } 
    } 

I가 응축하려고이 포함 된 기본 개념은 루프 확장

내게 이상한 것은 때때로 작동하는 경우가 있습니다. 코드는 때로는 원하는 출력을 생성하지만 때로는 NaN도 생성합니다. 응축 된 버전에서 resultVectorDir을 명시 적으로 제로로 할 필요가 있다고 생각했지만 문제가 해결되지 않았습니다. 나는이 작전 순서를 수행하는 것에 미묘한 것이있을 것이라고 생각했다. 제공 될 수있는 모든 도움을 크게 주시면 감사하겠습니다.

이 질문에 대한 부록으로, 나는이 구식을 좋은 구식 프린트 문으로 공격했고 배열의 계수 와이즈 곱을 올바르게 사용해서는 안된다는 것을 알았습니다. 예를 들어,이 nVolQuad = 9, I는 코드 세그먼트의 실행 상황 :

for (int dir = 0; dir < NDIM; dir++) 
    { 
    tempArray = volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir))); 
    for (int qp = 0; qp < nVolQuad; qp++) 
    { 
     std::cout << std::endl; 
     std::cout << tempArray(qp) << " "; 
     std::cout << volQuad.weights(qp)*alpha(dir,qp)*fAtQuad(qp) << " "; 
     std::cout << std::endl; 
    } 
    std::cout << std::endl; 
    std::cout << std::endl; 
    } 

출력 덩어리는 다음과 같다 :

-2.23064e-05 -2.23064e-05을

1.49458e-154 -3.56902e-05 6.94729e-310 -2.23064e-05

-2.68156e + 154 -2.0672e-05

,745

1,515,

6.94729e-310 -3.30752e-05

6.94729e-310 -2.0672e-05

2.13645e-314 -2.99114e-06

6.94729e-310 -4.78582e-06 출력

6.94729e-310 -2.99114e-06

다른 세그먼트는 유사하다. 첫 번째 항목은 정확하지만 tempArray의 다른 8 개 항목은 의미가 없습니다. tempArray는 루프 전에 0.0으로 초기화되므로 손실이 발생합니다. Eigen의 문서를 계속 살펴보고이 함수를 사용하는 데 아주 어리석은 일을하지 않을 것입니다.

+0

: 이것은로 구문을 변경하여 쉽게 해결할 수 있습니다 그것들은 (또는 어떤 코드는 초기 값을 설정한다.) 당신이 사용하는 라이브러리에 관계없이. 'qNewPtr'은 무엇이고,'+ ='를 적용하기 전에'qNewPtr [i]'가 초기화됩니까? – PaulMcKenzie

+0

예! qNew (및 qNew에 대한 포인터)는 루프 전에 0으로 설정됩니다. 그것은 내 말에 가난한 선택이었습니다. 내가 의미하는 바는, 처음에는 resultVectorDir에 초기 값을주지 않는다는 오류라고 생각했습니다. 내가 고칠 때 슬프게도 내 문제가 해결되지 않았다. – junoravin

+0

'operator ='를 사용하면'resultVectorDir'의 값을 설정합니다. 모든 변수의 정의를 제공 할 수 있습니까, 아니면 더 나은 [mcve]를 제공 할 수 있습니까? –

답변

1

키 오류는 확장 된 루프가 다른 크기의 데이터에 액세스 할 때 즉시 확장 된 루프에서 계수 와이즈 제품으로 이동할 수 있다는 가정에 있습니다. 여기서는

volQuad.weights 및 fAtQuad는 아이겐 :: VectorXd로 초기화되기 때문에
volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir))) 

, 그들은 열 벡터이지만 alpha.row (DIR)를 사용하여, 해당 특정 데이터 구조는 행 벡터이다. 따라서, 계수 현명한 제품은 의미가 없으며 단지 첫 번째 항목을 올바르게 가져올 것입니다.당신이 사용하기 전에 모든 변수/배열이 알려진 값으로 초기화한다 - 내가 명시 적으로 압축 된 버전 *에 resultVectorDir을 제로에해야 할 수도 있습니다 생각 *

volQuad.weights.cwiseProduct(fAtQuad.cwiseProduct(alpha.row(dir).transpose()))