2017-11-12 21 views
-1

wikipediaにある擬似コードに従ってJacobiの繰り返しを計算しようとしています。私はgdbでコードを実行しました。私は、行列とベクトルの合計を乗算しようとするたびに、ヒープバッファオーバーフローが発生することがわかりました。ここでC++の行列とベクトルの乗算Segフォールトを合計に格納しようとしたとき

は私のコードは次のとおりです。ウィキによると、私は答え7.1111、-3.2222を受けるべき

std::vector<double> sol(std::vector<double> &x,std::vector<std::vector<double> > &A, std::vector<double> &b, int n) 
{ 

    double sum; 
    int counter = n; 
    while(counter != 0) 
    { 
     for (int i = 1; i <= n; ++i) 
     { 
      sum = 0.0; 
      for (int j = 1; j <= n; ++j) 
      { 
       if(j != i) 
       { 
        sum += A[i][j]*x[j]; //Issue seems to be here in GDB 
        std::cout << "Sum " << sum << std::endl; 
       } 
      } 
      x[i] = (1.0/A[i][i])*(b[i]-sum); 
      for(auto&& e : x) 
      { 
       std::cout << e << " "; 
      } 
      std::cout << std::endl; 
     } 
     counter--; 
    } 

    return x; 
} 


int main() 
{ 

    //const int SIZE = 1000; 
    const int SIZE = 2; 

    double ranNumber = 0.0; 
    std::vector<std::vector<double> > A; 
    std::vector<double> testX = {1.0,1.0}; 
    std::vector<double> testB = {11.0,13.0}; 


    for (int i = 0; i < SIZE; ++i) 
    { 
     std::vector<double> k; 
     for(int j = 0; j < SIZE; ++j) 
     { 
      ranNumber = randNumber(); 
      k.emplace_back(ranNumber); 
     } 
     A.emplace_back(k); 
    } 

    A[0][0] = 2.0; 
    A[0][1] = 1.0; 
    A[1][0] = 5.0; 
    A[1][1] = 7.0; 

    std::vector<double> xSol = sol(testX,A,testB,30); 

    for(auto &&e:xSol) 
    { 
     std::cout << e << " "; 
    } 
    std::cout << std::endl; 

    return 0; 
} 

、私はどのように非常にわからないので、私はk一部を除いて擬似コードを踏襲していると思いますこれをベクトルに実装することができます。

セグメンテーションフォルトの原因は何ですか?私はベクターやマトリックスで限界を超えていますか?それは私がセグフォルトだと思うように導くが、私はここで何が起こっているのか正確にはわからない。どんな助けでも大歓迎です。

おかげ

編集:私は明確にすべき、はい、これは実装のベクトルのベクトルを持っている恐ろしい方法です。これはウィキペディアにあるものを複製できるかどうかを確認するテストにすぎません。この回答を得ることができれば、私は不要なA [0] [0] ...などを取り除きます。私には数字を生成する乱数関数があります。しかしこれは、これが正しく機能していることを確認することです。

+0

投票の理由を説明していただきます。 – Sailanarmo

+1

C/C++での配列のインデックス付けは '0'から始まります。 –

+0

@SemyonBurov、forループを変更しようとしました。' int i = 0; i Sailanarmo

答えて

1

最初に、1からnではなく、0からn-1までのインデックスの問題があります。

次に、ベクトルAを2 x 2で構成しますが、A[i][j]、jを30まで繰り返します。だからあなたは範囲外の配列にアクセスします! SIZEに基づいて行列を構成するので、SIZEを使用して関数を呼び出します。

最後に、ゼロ除算でないことを確認することなく、A[i][i]で除算します。 (そうではありませんが、一種の反射として確認する必要があります)。

正しい答えが得られるかどうかわかりませんが、短いダンプは発生しません。

関連する問題