2017-03-05 1 views
1

현재 C++의 유한 차분 방법을 사용하여 미분 방정식을 풀기위한 작은 프로그램을 작성하고 있습니다. 문제는 내가 tridiagonal 매트릭스를 해결하기 위해 lapack을 사용하고 있지만 루틴이 호출 된 후 Segmentation Fault가 발생합니다. 루틴은 여전히 ​​info = 0로 종료되므로 문제가 무엇인지 알 수 없습니다. 여기에 프로그램이 있습니다.Lapack 루틴의 세그먼트 오류

#include <iostream> 
#include <cmath> 
#include <vector> 

#define pi 3.14159265358979323846 

using namespace std; 

extern "C" void dstev_(char* job, int* N, double* D, double* OFFD, double* EV, int* VDIM, double* WORK, int* INFO); 

int main(){ 

int i = 0; 

// systems parameters 
double a = 2e10-6; 
double k = pi/1.55e-6; 
double n1_sq = pow(3.0, 2), n2_sq = pow(3.1, 2); 
double step = 1e-6; 
double factor = 1/(k*k*step*step); 


// parameters for lapack 
char job = 'V'; 
int N = 80, vdim = 100, info; 

// create and initialize vector arrays for lapack routine 
vector<double> d, offd, work; 
vector< vector<double> > ev(vdim, vector<double>(N)); 

// set up diagonal elements 
d.push_back(n1_sq - factor); 
for(i=1; i<N-1; i++){ 
    if(i<N/4 || i>=3*N/4){ 
     d.push_back(n1_sq - 2*factor); 
    } 
    else{ 
     d.push_back(n2_sq - 2*factor); 
    } 
} 
d.push_back(n1_sq - factor); 

// set up off diagonal elements 
for(i=0; i<N-1; i++){ 
    offd.push_back(factor); 
} 

// initialize other arrays 
for(i=0; i<vdim; i++){ 
    work.push_back(0.0); 
} 


cout << "Before routine" << endl; 

dstev_(&job, &N, &*d.begin(), &*offd.begin(), &*(ev.begin()->begin()), &vdim, &*work.begin(), &info); 

cout << "After routine"<< endl; 

return 0; 
} 

이 LAPACK 그래서 내가 바로이 코드에 대해/잘못하지만 어떤 도움이 감사 모르겠어요 사용하여 내 처음이다. 또한 벡터를 루틴에 전달하기 위해 begin() 반복기를 전달해야하는 이유는 무엇입니까? 이것은 내가 그것을 어떻게 배웠지 만, 나는 그것을 완전히 이해했다고 생각하지 않는다.

답변

1

이 코드에서 유일한 문제인지는 모르겠지만 std::vector< std::vector< double> >은 인접 메모리를 할당하지 않습니다 ... 따라서 Lapack은 행렬 ev의 모든 요소에 액세스 할 수 없습니다. 행렬의 (i,j)i+j*n 인 크기 n*n의 벡터를 제공해야합니다.