解析
- 掃き出し法による連立方程式の解法
前述の正方行列管理クラスを使って連立一次方程式を解いてみます。
SquareMatrix a = new SquareMatrix( 3 );
a.SetRow( 0, 3, -4, 2 );
a.SetRow( 1, 2, 5, 3 );
a.SetRow( 2, -2, 3, -2 );
Vector b = new Vector( 0, 6, 1 );
Vector answer = SolveEquation( a, b );
/// <summary>AX = B連立一次方程式</summary>
/// <param name="a">A行列</param>
/// <param name="b">B行列(ベクトル)</param>
/// <returns>X行列(ベクトル)</returns>
public static Vector SolveEquation( SquareMatrix a, Vector b )
{
// 正方行列以外許さない。
if( a.Rows != a.Cols ) return null;
if( a.Rows != b.Count ) return null;
// 答え
Vector x = new Vector( b.Count );
double dDevide; // a[n,1]/a[1,1]
int nRow;
int nCol;
int nPrevious;
// 前進消去
for( nPrevious = 0; nPrevious < b.Count; nPrevious++ )
{
for( nRow = nPrevious + 1; nRow < b.Count; nRow++ )
{
dDevide = a[ nRow, nPrevious ] / a[ nPrevious, nPrevious ];
for( nCol = nPrevious + 1; nCol < b.Count; nCol++ )
{
a[ nRow, nCol ] = a[ nRow, nCol ] - dDevide * a[ nPrevious, nCol ];
}
b[ nRow ] = b[ nRow ] - dDevide * b[ nPrevious ];
}
}
// この時点でa[2,4]など左下半分は全てゼロになるべきだが、
// 結局この部分は後退代入で使わないので元のままにしてある。
// 後退代入の手順
// a[n,n] * x[n] = b[n]
// a[n-1,n-1] * x[n-1] + a[n-1,n] * x[n] = b[n-1]
// 後退代入
for( nRow = b.Count - 1; nRow >= 0; nRow-- )
{
for( nCol = nRow + 1; nCol < b.Count; nCol++ )
{
b[ nRow ] = b[ nRow ] - a[ nRow, nCol ] * x[ nCol ];
}
x[ nRow ] = b[ nRow ] / a[ nRow, nRow ];
}
return x;
}