2015-01-12 6 views
0

으로 복잡한 매트릭스를 매핑 I 다음의 행렬이 있습니다은 아이겐

int N = 3; 
complex<double>* complexvector = new complex<double>[N]; 
for(int i=0; i<N; i++) 
     { 
      complexvector[i]=complex<double>(i+1,i+1); 
     } 



complex<double>** complexMatrix = new complex<double>*[N]; 
    for(int i=0; i<N; i++) 
    { 
     complexMatrix[i] = new complex<double>[N];// allocate an array to each pointer 
    } 



complexMatrix[0][0] = complex<double>(1,1); 
complexMatrix[0][1] = complex<double>(2,2); 
complexMatrix[0][2] = complex<double>(3,3); 

complexMatrix[1][0] = complex<double>(4,4); 
complexMatrix[1][1] = complex<double>(5,5); 
complexMatrix[1][2] = complex<double>(6,6); 

complexMatrix[2][0] = complex<double>(7,7); 
complexMatrix[2][1] = complex<double>(8,8); 
complexMatrix[2][2] = complex<double>(9,9); 


complex<double>* returnvector = new complex<double>[N]; 
returnvector = preformcholesky(complexMatrix, complexvector, N); 

을 그리고 난 여기에 콜레을 수행

complex<double>* preformcholesky(complex<double>** matrix, complex<double>* vector, 
int size) 
{ 
std::cout << "start cholesky" << std::endl; 
Map<MatrixXcd, RowMajor> mat(*matrix,size,size); 
Map<VectorXcd> vec(vector,size); 
printMatrix(matrix,size); 
std::cout << "mat" << mat << std::endl; 
std::cout << "vec" << vec << std::endl; 
//mat.llt(); 
VectorXcd x = mat.llt().solve(vec); 
std::cout << "coeff" << x << std::endl; 
return x.data(); 
} 

는 "매트"을 인쇄 할 때 문제가, 그것은 다음과 같이 간다 :

mat   (1,1) (0,3.21143e-322)   (6,6) 
     (2,2)   (4,4) (0,3.21143e-322) 
     (3,3)   (5,5)   (7,7) 

여기서 (0,3.21143e-322)는 어디에서 왔습니까? "매트릭스"를 인쇄하면 OK입니다. 그래서지도가 잘못되었다고 생각합니다. 더 많은 코드가 필요하면 알려주세요. 나는 Eigen을 처음 접했고 어쩌면 몇 가지 기본적인 실수를했을 것이다. 나는 C++과 리눅스를 사용하고있다.

+0

그들은 0에 가까워지는 부동 소수점 인 것처럼 보이는데, 이는 일부 수치 알고리즘에서 자주 발생합니다. 예 : 문턱 값은 0 점에 대한 독자적인 해석을 갖습니다. – keyser

+0

아직지도 알고리즘에서 MatrixXcd로 변환 한 알고리즘이 없습니다. – user1876942

+0

좋은 지적. 그 생성자가 어떻게 행렬 데이터를 만드는 지보십시오. – keyser

답변

1

해당 코드에는 몇 가지 문제가 있습니다. 예를 들어, performcholesky의 반환 값은 performcholesky이 반환 된 후에 더 이상 존재하지 않는 로컬 변수에 대한 포인터이며,이 매달린 포인터로 할당 된 메모리에 포인터를 덮어 쓰면서 해당 메모리를 유출합니다. Eigen::MatrixXcd과 (과) 직접 협력 해보세요. 나중에 모든 것을 디버깅하는 고통의 세계를 스스로 구할 수 있습니다.

어쨌든이 문제는 Eigen::Map 생성자가 포인터에 대한 포인터가 아니라 플랫 배열을 필요로한다는 것을 나타냅니다. 그것은 다음과 같이 사용할 수있다 : 어느 정도 이동하면 생성자에 통과하지 못한 두 배열 그럼에도 불구하고,지도에 표시하는 이유

// It would also work with naked new, but naked new leads to pain, fear, anger, 
// and suffering. Also to long hours of debugging. 
std::vector<std::complex<double> > data(N * N); 

for(int i = 0; i < N * N; ++i) { 
    data[i] = std::complex<double>(i, i); 
} 

Eigen::Map<Eigen::MatrixXcd, Eigen::RowMajor> mat(&data[0], N, N); 

흥미로운 질문입니다. 그 대답은 : 순수한 우연에 의해, new은 힙에 서로 뒤의 세 개의 슬랩을 주었다. 또한지도에서 보는 이상한 유물을 설명합니다. 이들은 double으로 재 해석 된 해당 할당 블록에 대한 힙 구현의 부기 데이터입니다. 본질적으로, complexmatrix[0] 주위의 메모리는 다음과 같습니다

the area that Eigen::Map uses 
+-----------------------------------------------------------------+ 
|(1,1)|(2,2)|(3,3)|bookkeeping|(4,4)|(5,5)|(6,6)|bookkeeping|(7,7)|(8,8)|(9,9)| 
+-----------------+   +-----------------+   +-----------------+ 
^-complexmatrix[0]   ^-complexmatrix[1]   ^-complexmatrix[2] 

당연히, 이것은 당신이 의존 할 행동이 아니다. 코드 new 블록이 다른 방식으로 배열되어 있으면 코드에서 임의의 데이터를 표시하거나 segfault로 크래시 할 수 있습니다.

+0

고마워요. 이것은 도움이됩니다. Eigen을 직접 사용할 수는 없기 때문에 모든 사람들이 Eigen을 사용하도록하고 싶지 않으며 원하지 않습니다. – user1876942