C語言計算逆矩陣


花了4天寫的,不過三天在重學線代。

  1 #include<stdio.h>
  2 #include<stdlib.h>    // 操作內存
  3 #include<math.h>  // pow()函數,計算-1的n次方,可以不用這個函數,偷懶使用現成的
  4 
  5 /*
  6     顯示矩陣
  7     matrix: 矩陣
  8     order: 階數
  9 */
 10 void showMatrix(float** matrix, int order)
 11 {
 12     for (int i = 0; i < order; i++) {
 13         for (int j = 0; j < order; j++) {
 14             printf("    %f    ", matrix[i][j]);
 15         }
 16         printf("|\n");
 17     }
 18 }
 19 
 20 /*
 21     交換兩行
 22     一開始想使用初等行變換計算,此函數可以刪除,用不到
 23     x1:調換第一行
 24     x2:調換第二行
 25     order:矩陣階數
 26     matrix:矩陣
 27     */
 28 void replaceRow(int x1, int x2, int order, float **matrix)
 29 {    
 30     float temp;
 31     x1 -= 1;
 32     x2 -= 1;
 33     for (int i = 0; i < order; i++) {
 34         temp = matrix[x1][i];
 35         matrix[x1][i] = matrix[x2][i];
 36         matrix[x2][i] = temp;
 37     }
 38 }
 39 
 40 /*
 41     轉置矩陣
 42     matrix: 矩陣
 43     order: 階數
 44 */
 45 void transposeMatrix(float** matrix, int order)
 46 {
 47     float temp;
 48     for (int i = 0; i < order; i++) {
 49         for (int j = 0; j < i; j++) {
 50             temp = matrix[i][j];
 51             matrix[i][j] = matrix[j][i];
 52             matrix[j][i] = temp;
 53         }
 54     }
 55 }
 56 
 57 /*
 58     獲取除了某行某列的矩陣
 59     oldmatrix: 原本矩陣
 60     newmatrix: 新矩陣
 61     row: 要刪除行
 62     col: 要刪除列
 63     order: 階數
 64 */
 65 void get(float** oldmatrix, float** newmatrix, int row, int col, int order)
 66 {
 67     // 刪除了一行一列,所以新矩陣行列均比原矩陣少1
 68     int a = 0, b = 0;
 69     int x, y, z = 0, w = 0;
 70     // i,j循環原矩陣
 71     for (int i = 0; i < order - 1; i++) {
 72         for (int j = 0; j < order - 1; j++) {
 73             // z,w代表行列的是否加一狀態,防止多次加一,+1只需要1次
 74             if (i >= row && z == 0) { a += 1; z = 1; }
 75             if (j >= col && w == 0) { b += 1; w = 1; }
 76             
 77             newmatrix[i][j] = oldmatrix[i+a][j+b];
 78         }
 79         a = 0;b = 0;
 80         z = 0;w = 0;
 81     }
 82 }
 83 
 84 /*
 85     計算行列式
 86     matrix: 矩陣
 87     order: 階數
 88 */
 89 float calc(float** matrix, int order)
 90 {
 91     // 遞歸求行列式值
 92     float num=0;
 93     int i, j;
 94     if (order == 2) {
 95         // 如果是二階直接獲取值
 96         num = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
 97     }
 98     else {
 99         // 創建更小二維數組
100         order -= 1;
101         float** matrixlow = (float**)malloc(sizeof(float*) * order);
102         for (i = 0; i < order; i++) {
103             matrixlow[i] = (float*)malloc(sizeof(float) * order);
104         }
105         order += 1;
106         
107         // 循環展開第一行
108         for (j = 0; j < order; j++) {
109 
110             get(matrix, matrixlow, 0, j, order);            
111             // 此處開始遞歸,調用自身函數
112             num += matrix[0][j] * pow(-1, j) * calc(matrixlow, order - 1);            
113         }
114 
115         // 釋放內存
116         for (i = 0; i < order-1; ++i)free(*(matrixlow + i));
117     }
118 
119     return num;
120 }
121 
122 
123 /*
124     主函數
125 */
126 int main()
127 {
128     int order;    // 矩陣階數
129     int i, j;
130     float det;
131 
132     // 獲取矩陣階
133     printf("輸入矩陣階:");
134     scanf("%d", &order);
135 
136     printf("輸入的階是:%d\n\n", order);    
137 
138     // 申請二維數組內存
139     float** matrix = (float**)malloc(sizeof(float*) * order);
140     for (i = 0; i < order; i++) {
141         matrix[i] = (float*)malloc(sizeof(float) * order);
142     }
143 
144     // 獲取輸入
145     for (i = 0; i < order; i++) {
146         for (j = 0; j < order; j++) {
147             printf("位置:( %d , %d)請輸入數據:",i + 1,j + 1);            
148             scanf("%f", &matrix[i][j]);
149         }
150     }    
151         
152     // 計算並顯示det    
153     det = calc(matrix, order);
154     printf("\ndet值為:%f",det);
155     // 0不能做除數
156     if (det == 0) 
157         printf("\n矩陣接近奇異值,結果可能不准確!");
158     printf("\n\n");
159 
160     // 顯示輸入矩陣
161     printf("\n輸入的矩陣是:\n\n");
162     showMatrix(matrix, order);    
163 
164     // 申請二維數組存儲結果
165     float** Rmatrix = (float**)malloc(sizeof(float*) * order);
166     for (i = 0; i < order; i++) {
167         Rmatrix[i] = (float*)malloc(sizeof(float) * order);
168     }    
169 
170     
171     // 開始計算
172     if (order == 2) {
173         // 階數為二直接運行公式
174         float n = 1 / (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]);
175         Rmatrix[0][0] = n * matrix[1][1];
176         Rmatrix[0][1] = -n * matrix[0][1];
177         Rmatrix[1][0] = -n * matrix[1][0];
178         Rmatrix[1][1] = n * matrix[0][0];        
179     }
180     else {
181         // 轉置矩陣並顯示
182         transposeMatrix(matrix, order);
183         printf("\n\n轉置后為:\n\n");
184         showMatrix(matrix, order);
185         
186         // 循環求i,j位的代數余子式
187         for (i = 0; i < order; i++) {
188             for (j = 0; j < order; j++) {
189                 // 申請二維數組
190                 order -= 1;
191                 float** matrixlow = (float**)malloc(sizeof(float*) * order);
192                 for (int t = 0; t < order; t++) {
193                     matrixlow[t] = (float*)malloc(sizeof(float) * order);
194                 }
195                 order += 1;                
196 
197                 // 獲取除了i,j行的值組成行列式
198                 get(matrix, matrixlow, i, j, order);                            
199                 // 計算行列式值除以det
200                 Rmatrix[i][j] = pow(-1, i + j) * calc(matrixlow, order - 1) / det;                
201 
202                 // 釋放內存
203                 for (int t = 0; t < order-1; ++t)free(*(matrixlow + t));                
204             }
205         }        
206 
207     }
208     
209     // 顯示逆矩陣
210     printf("\n\n逆矩陣為:\n\n");
211     showMatrix(Rmatrix, order);
212 
213 
214     //// 釋放二維數組
215     for (i = 0; i < order; ++i)free(*(matrix + i));    
216     for (i = 0; i < order; ++i)free(*(Rmatrix + i));
217 
218     return 0;
219 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM