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 }

 

posted @ 2020-06-15 09:32  ruxia_TJY  阅读(2107)  评论(1编辑  收藏  举报