C言語は1つの行列の逆行列を求めます(部分の主元のガウスは法を消します)


1、問題の由来
最近,ネットワークセキュリティを研究する過程でhill暗号が研究され,この暗号化体制では行列の逆行列が用いられている.ネットワークリソースを検索することによって,一部のメタのGauss消去法を用いて逆行列を解くアルゴリズムを見つけ,皆さんに共有した.
2、アルゴリズム実現
//********************************  
//***          ***  
//********************************  
#include  
#include   
#include   
#include   

using namespace std;  
#define  N  10                //          10  

//         
float MatDet(float *p, int n);                    //         
float Creat_M(float *p, int m, int n, int k);    //     A(m, n)        
void print(float *p, int n);                    //    n*n  
bool Gauss(float A[][N], float B[][N], int n);    //               A    B  

int main()  
{  
	float a[N][N], b[N][N];
	int i,j,n;
	cout << "                   !
"; cout << " : "; cin >> n; cout << " " << n << " :
"; // n for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { cin >> a[i][j]; } } // if (Gauss(a, b, n)) { cout << " :
"; for (i = 0; i < n; i++) { cout << setw(4); for (j = 0; j < n; j++) { cout << b[i][j] << setw(10); } cout << endl; } } system("PAUSE"); return 0; } //----------------------------------------------- // : (n*n) // : , // : //---------------------------------------------- float MatDet(float *p, int n) { int r, c, m; int lop = 0; float result = 0; float mid = 1; if (n != 1) { lop = (n == 2) ? 1 : n; // , 2 , 1 , n for (m = 0; m < lop; m++) { mid = 1; // , for (r = 0, c = m; r < n; r++, c++) { mid = mid * (*(p + r*n + c%n)); } result += mid; } for (m = 0; m < lop; m++) { mid = 1; // , for (r = 0, c = n - 1 - m + n; r < n; r++, c--) { mid = mid * (*(p + r*n + c%n)); } result -= mid; } } else result = *p; return result; } //---------------------------------------------------------------------------- // : k*k A(m, n) // : k*k , A m,n, k // : k*k A(m, n) //---------------------------------------------------------------------------- float Creat_M(float *p, int m, int n, int k) { int len; int i, j; float mid_result = 0; int sign = 1; float *p_creat, *p_mid; len = (k - 1)*(k - 1); //k k-1 p_creat = (float*)calloc(len, sizeof(float)); // p_mid = p_creat; for (i = 0; i < k; i++) { for (j = 0; j < k; j++) { if (i != m && j != n) // i j p_mid { *p_mid++ = *(p + i*k + j); } } } sign = (m + n) % 2 == 0 ? 1 : -1; // 、 mid_result = (float)sign*MatDet(p_creat, k - 1); free(p_creat); return mid_result; } //----------------------------------------------------- // : n*n // : n*n , n // : //----------------------------------------------------- void print(float *p, int n) { int i, j; for (i = 0; i < n; i++) { cout << setw(4); for (j = 0; j < n; j++) { cout << setiosflags(ios::right) << *p++ << setw(10); } cout << endl; } } //------------------------------------------------------------------ // : A B // : , , // : true or false //------------------------------------------------------------------- bool Gauss(float A[][N], float B[][N], int n) { int i, j, k; float max, temp; float t[N][N]; // // A t[n][n] for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { t[i][j] = A[i][j]; } } // B for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { B[i][j] = (i == j) ? (float)1 : 0; } } for (i = 0; i < n; i++) { // max = t[i][i]; k = i; for (j = i + 1; j < n; j++) { if (fabs(t[j][i]) > fabs(max)) { max = t[j][i]; k = j; } } // i , if (k != i) { for (j = 0; j < n; j++) { temp = t[i][j]; t[i][j] = t[k][j]; t[k][j] = temp; //B temp = B[i][j]; B[i][j] = B[k][j]; B[k][j] = temp; } } // 0, , A , if (t[i][i] == 0) { cout << "There is no inverse matrix!"; return false; } // A i i temp = t[i][i]; for (j = 0; j < n; j++) { t[i][j] = t[i][j] / temp; // 1 B[i][j] = B[i][j] / temp; // } for (j = 0; j < n; j++) // 0 -> n { if (j != i) // i { temp = t[j][i]; for (k = 0; k < n; k++) // j - i *j i { t[j][k] = t[j][k] - t[i][k] * temp; B[j][k] = B[j][k] - B[i][k] * temp; } } } } return true; }

3、アルゴリズムケース
アルゴリズムの利用このアルゴリズムの例は次のhillパスワードを見てください