連立方程式の計算過程は紙に書けば解くことができるのでわかるのですが、プログラムの計算の過程が紙に書いて計算してみたのですがうまく理解できません。
質問は3つあります。
{ 1.0, -2.0, 3.0, -4.0, 5.0}(1)
{-2.0, 5.0, 8.0, -3.0, 9.0}(2)
{ 5.0, 4.0, 7.0, 1.0, -1.0}(3)
{ 9.0, 7.0, 3.0, 5.0, 4.0}(4)
(2)-(1)-2/1,(3)-(1)-5/1より
{0,9,0,5,-1}{0, 1, 14, -11, 19}(5)
{0,14,-8,21,-26}(6)が得られますが、{0,9,0,5,-1}{0, 1, 14, -11, 19},{0,14,-8,21,-26}の置いてある位置、というか保存先は{0=(1,0),9=(1,1),0=(1,2),5=(1,3),-1=(1,4)}(2)´
{0=(2,0),14=(2,1),-8=(2,2),21=(2,3),-26=(2,4)}(3)´となっているのでしょうか?
計算後の係数のデータがどこにいくのかわかりませんでした。
その後の計算は
{0,14,-8,21,-26}-{0,9,0,5,-1}*-14/9を行うのでしょうか?
最後にプログラムのfor (j = k + 1; j <= N; j++)
a[i][j] -= a[k][j] * d;
の部分がi行-k行*aik/akkを表していると思うのですが、for (j = k + 1; j <= N; j++)によって a[i][j] -= a[k][j] * d;のa[k][j]のjが変化してある行に存在する係数すべてにaik/akkを掛けられるということでしょうか?
過程の計算処理がわからないプログラムは以下の部分です。
// 前進消去 for (k = 0; k < N -1; k++) { for (i = k + 1; i < N; i++) { d = a[i][k] / a[k][k]; for (j = k + 1; j <= N; j++) a[i][j] -= a[k][j] * d; } }
全体のプログラムはこちらです。
/********************************************* * 連立方程式の解法 ( ガウスの消去法 ) *********************************************/ #include <iostream> // for cout #include <stdio.h> // for printf() // 元の数定義 #define N 4 // 3 using namespace std; /* * 計算クラス */ class Calc { double a[N][N + 1]; // 各種変数 double d; // ダミー int i, j, k; // LOOP インデックス public: // 連立方程式を解く(ガウスの消去法) void calcGaussElimination(); }; /* * 連立方程式を解く(ガウスの消去法) */ void Calc::calcGaussElimination() { // 係数 static double a[N][N + 1] = { //{ 2.0, -3.0, 1.0, 5.0}, //{ 1.0, 1.0, -1.0, 2.0}, //{ 3.0, 5.0, -7.0, 0.0} { 1.0, -2.0, 3.0, -4.0, 5.0}, {-2.0, 5.0, 8.0, -3.0, 9.0}, { 5.0, 4.0, 7.0, 1.0, -1.0}, { 9.0, 7.0, 3.0, 5.0, 4.0} }; // 元の連立方程式をコンソール出力 for (i = 0; i < N; i++) { for (j = 0; j < N; j++) printf("%+fx%d ", a[i][j], j + 1); printf("= %+f\n", a[i][N]); } // 前進消去 for (k = 0; k < N -1; k++) { for (i = k + 1; i < N; i++) { d = a[i][k] / a[k][k]; for (j = k + 1; j <= N; j++) a[i][j] -= a[k][j] * d; } } // 後退代入 for (i = N - 1; i >= 0; i--) { d = a[i][N]; for (j = i + 1; j < N; j++) d -= a[i][j] * a[j][N]; a[i][N] = d / a[i][i]; } // 結果出力 for (k = 0; k < N; k++) printf("x%d = %f\n", k + 1, a[k][N]); } /* * メイン処理 */ int main() { try { // 計算クラスインスタンス化 Calc objCalc; // 連立方程式を解く(ガウスの消去法) objCalc.calcGaussElimination(); } catch (...) { cout << "例外発生!" << endl; return -1; } // 正常終了 return 0; }
参考にしたサイトはこちらです。
https://www.mk-mode.com/octopress/2013/09/24/cpp-simultaneous-equation-by-gauss-elimination/
7/25(16:54)<編集>
for (k = 0; k < N -1; k++) { for (i = k + 1; i < N; i++) { d = a[i][k] / a[k][k]; for (j = k + 1; j <= N; j++) a[i][j] -= a[k][j] * d; } }
の部分での過程の処理を実際に書いてみたのですが、うまく計算過程が書けませんでした。
k=0,i=1,d = a[1][0] / a[0][0],a[1][1] =a[1][1] - a[0][1] * a[1][0] / a[0][0] ```となります。 この後a[0][1]に a[1][0] / a[0][0]を掛けているということは(0,0)は0として無いもののように扱いa[i][j] -= a[k][j] * dのjの値を(j <= Nの範囲で)変えながら計算してi行に存在する項を消して計算しているのでしょうか? わかりにくくて申し訳ありません。どうしても理解したいと思い、何度も紙に書いて計算を行っています。