全选主元的高斯-若当消去法求逆矩阵的数学依据如下:
列选主元其实就不用恢复这一步骤。
全选主元代码
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
bool gjinv(double *a, int n) {
//d用于全选主元过程
//t用于存储各种临时数据
double d, t;
//i用于遍历时的行号
//j用于遍历时的列号
//p,q用于存储标号
//js用于存储全选主元元素的行号
//k用于表示第几次操作
int i, j, p, q, k, *js, *is;
js = new int[n];
is = new int[n];
double *c = new double[2 * n*n];
//构造增广矩阵
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
c[i * 2 * n + j] = a[i*n + j];
}
for (j = n; j < 2 * n; j++) {
if (j - n == i) {
c[i * 2 * n + j] = 1;
}
else c[i * 2 * n + j] = 0;
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < 2 * n; j++) {
cout <<setw(6)<<fixed<<left<<setprecision(2)<< c[i * 2 * n + j] << " ";
}
cout << endl;
}
//消元过程
for (k = 0; k < n; k++) {
//全选主元
{
d = 0.0;
for (i = k; i < n; i++) {
for (j = k; j < n; j++) {
t = c[i*2*n + j];
if (fabs(t) > d) {
d = fabs(t);
js[k] = j;//记录列变换操作
is[k] = i;//记录行号
}
}
}
//列选主元
//d = 0.0;
//for (i = k; i < n; i++) {
// t = c[i * 2 * n + k];
// if (fabs(t) > d) {
// d = fabs(t);
// is[k] = i;//记录行号
// }
//}
}
//如果全0则奇异矩阵,无法计算
{
if (d + 1.0 == 1.0) {
cout << "系数矩阵奇异,无法计算";
return 0;
}
}
//行交换
if (is[k] != k) {
for (j = 0; j < 2*n; j++) {
p = k*2*n + j;
q = is[k]*2*n + j;
t = c[p]; c[p] = c[q]; c[q] = t;
}
}
//列交换
if (js[k] != k) {
for (i = 0; i < n; i++) {
p = i*2*n + k;
q = i*2*n + js[k];
t = c[p]; c[p] = c[q]; c[q] = t;
}
}
//归一化
{
d = c[k*n*2 + k];
for (j = k + 1; j <2* n; j++) {
p = k*n*2 + j;
c[p] = c[p] / d;
}
}
//消元
for (i = 0; i < n; i++) {
if (i != k) {
for (j = k + 1; j < 2*n; j++) {
p = i*2*n + j;
q = i*2*n + k;
c[p] = c[p] - c[q] * c[k*2*n + j];
}
}
}
//用于调试:输出每次的矩阵
for (i = 0; i < n; i++) {
for (j = 0; j <2* n; j++) {
cout << fixed << setw(8) << left << setprecision(4) << c[i*2*n + j] << " ";
}
cout << endl;
}
cout << endl;
}
//恢复
for (k = n - 1; k >= 0; k--) {
for (j = 0; j < 2*n; j++) {//换列 : 其实是在换行
t = c[k * 2 * n + j];
c[k * 2 * n + j] = c[js[k] * 2 * n + j];
c[js[k] * 2 * n + j] = t;
}
}
for (i = 0; i < n; i++) {
for (j = 0; j <2 * n; j++) {
cout << fixed << setw(8) << left << setprecision(4) << c[i * 2 * n + j] << " ";
}
cout << endl;
}
//结束收工
delete[] is;
delete[] js;
return 1;
}
列选主元代码:
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
bool gjinv(double *a, int n) {
//d用于全选主元过程
//t用于存储各种临时数据
double d, t;
//i用于遍历时的行号
//j用于遍历时的列号
//p,q用于存储标号
//js用于存储全选主元元素的行号
//k用于表示第几次操作
int i, j, p, q, k, *js, *is;
js = new int[n];
is = new int[n];
double *c = new double[2 * n*n];
//构造增广矩阵
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
c[i * 2 * n + j] = a[i*n + j];
}
for (j = n; j < 2 * n; j++) {
if (j - n == i) {
c[i * 2 * n + j] = 1;
}
else c[i * 2 * n + j] = 0;
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < 2 * n; j++) {
cout <<setw(6)<<fixed<<left<<setprecision(2)<< c[i * 2 * n + j] << " ";
}
cout << endl;
}
//消元过程
for (k = 0; k < n; k++) {
//全选主元
{
//d = 0.0;
// for (i = k; i < n; i++) {
// for (j = k; j < n; j++) {
// t = c[i*2*n + j];
// if (fabs(t) > d) {
// d = fabs(t);
// js[k] = j;//记录列变换操作
// is[k] = i;//记录行号
// }
// }
//}
//列选主元
d = 0.0;
for (i = k; i < n; i++) {
t = c[i * 2 * n + k];
if (fabs(t) > d) {
d = fabs(t);
is[k] = i;//记录行号
}
}
}
//如果全0则奇异矩阵,无法计算
{
if (d + 1.0 == 1.0) {
cout << "系数矩阵奇异,无法计算";
return 0;
}
}
//行交换
if (is[k] != k) {
for (j = 0; j < 2*n; j++) {
p = k*2*n + j;
q = is[k]*2*n + j;
t = c[p]; c[p] = c[q]; c[q] = t;
}
}
//列交换
/*if (js[k] != k) {
for (i = 0; i < n; i++) {
p = i*2*n + k;
q = i*2*n + js[k];
t = c[p]; c[p] = c[q]; c[q] = t;
}
}*/
//归一化
{
d = c[k*n*2 + k];
for (j = k + 1; j <2* n; j++) {
p = k*n*2 + j;
c[p] = c[p] / d;
}
}
//消元
for (i = 0; i < n; i++) {
if (i != k) {
for (j = k + 1; j < 2*n; j++) {
p = i*2*n + j;
q = i*2*n + k;
c[p] = c[p] - c[q] * c[k*2*n + j];
}
}
}
//用于调试:输出每次的矩阵
for (i = 0; i < n; i++) {
for (j = 0; j <2* n; j++) {
cout << fixed << setw(8) << left << setprecision(4) << c[i*2*n + j] << " ";
}
cout << endl;
}
cout << endl;
}
//恢复
//for (k = n - 1; k >= 0; k--) {
//
// for (j = 0; j < 2*n; j++) {//换列 : 其实是在换行
// t = c[k * 2 * n + j];
// c[k * 2 * n + j] = c[js[k] * 2 * n + j];
// c[js[k] * 2 * n + j] = t;
// }
//}
for (i = 0; i < n; i++) {
for (j = 0; j <2 * n; j++) {
cout << fixed << setw(8) << left << setprecision(4) << c[i * 2 * n + j] << " ";
}
cout << endl;
}
//结束收工
delete[] is;
delete[] js;
return 1;
}