c语言实现矩阵AX=b算法
如何使用C语言实现矩阵的转置、乘法、求逆等操作在本文中会得到深刻的理解。
想要代码实现 向量*矩阵=向量 首先要明白数学求解过程:
A为矩阵,b为向量,随机生成A和b,求X
X=A-*b , A-为A的逆矩阵
A的逆矩阵=A的伴随矩阵/A的行列式 , 即A- =A* / |A|
伴随矩阵中的1个值为A*=-1i+j*去除本行本列以外剩余矩阵的行列式
最后将求出的伴随矩阵转置与向量B相除即可得到向量X
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
double arrA[3][3],arrD[3][3]; //arrA存放A的伴随矩阵 arrD存放A的伴随矩阵转置矩阵
double getA(double arr[3][3], int n) //此函数作用为计算|A|
{
if (n == 1)
{
return arr[0][0];
}
double ans = 0;
double temp[3][3];
int i, j, k;
for (i = 0; i<n; i++)
{
for (j = 0; j<n - 1; j++)
{
for (k = 0; k<n - 1; k++)
{
temp[j][k] = arr[j + 1][(k >= i) ? k + 1 : k];
}
}
double t = getA(temp, n - 1);
if (i % 2 == 0)
{
ans += arr[0][i] * t;
}
else
{
ans -= arr[0][i] * t;
}
}
return ans;
}
double get_num(double ori[2][2]) //计算2*2矩阵行列式的值
{
return ori[1][1]*ori[0][0]-ori[1][0]*ori[0][1];
}
double getB(double arr[3][3]) { //此函数作用为求arr[][]的伴随矩阵
int i,j,k,t,v,b;
double arrB[2][3],arrC[2][2]; //arrB储存对行操作后的矩阵,arrC储存对列操作后的矩阵
for(i=0;i<3;i++){ //对行进行操作
for(j=0;j<3;j++){
if(i==0){
arrB[0][0]=arr[1][0];
arrB[0][1]=arr[1][1];
arrB[0][2]=arr[1][2];
arrB[1][0]=arr[2][0];
arrB[1][1]=arr[2][1];
arrB[1][2]=arr[2][2];
if(j==0){
arrC[0][0]=arrB[0][1];
arrC[0][1]=arrB[0][2];
arrC[1][0]=arrB[1][1];
arrC[1][1]=arrB[1][2];
}
if(j==1){
arrC[0][0]=arrB[0][0];
arrC[0][1]=arrB[0][2];
arrC[1][0]=arrB[1][0];
arrC[1][1]=arrB[1][2];
}
if(j==2){
arrC[0][0]=arrB[0][0];
arrC[0][1]=arrB[0][1];
arrC[1][0]=arrB[1][0];
arrC[1][1]=arrB[1][1];
}
}
if(i==1){
arrB[0][0]=arr[0][0];
arrB[0][1]=arr[0][1];
arrB[0][2]=arr[0][2];
arrB[1][0]=arr[2][0];
arrB[1][1]=arr[2][1];
arrB[1][2]=arr[2][2];
if(j==0){
arrC[0][0]=arrB[0][1];
arrC[0][1]=arrB[0][2];
arrC[1][0]=arrB[1][1];
arrC[1][1]=arrB[1][2];
}
if(j==1){
arrC[0][0]=arrB[0][0];
arrC[0][1]=arrB[0][2];
arrC[1][0]=arrB[1][0];
arrC[1][1]=arrB[1][2];
}
if(j==2){
arrC[0][0]=arrB[0][0];
arrC[0][1]=arrB[0][1];
arrC[1][0]=arrB[1][0];
arrC[1][1]=arrB[1][1];
}
}
if(i==2){
arrB[0][0]=arr[0][0];
arrB[0][1]=arr[0][1];
arrB[0][2]=arr[0][2];
arrB[1][0]=arr[1][0];
arrB[1][1]=arr[1][1];
arrB[1][2]=arr[1][2];
if(j==0){
arrC[0][0]=arrB[0][1];
arrC[0][1]=arrB[0][2];
arrC[1][0]=arrB[1][1];
arrC[1][1]=arrB[1][2];
}
if(j==1){
arrC[0][0]=arrB[0][0];
arrC[0][1]=arrB[0][2];
arrC[1][0]=arrB[1][0];
arrC[1][1]=arrB[1][2];
}
if(j==2){
arrC[0][0]=arrB[0][0];
arrC[0][1]=arrB[0][1];
arrC[1][0]=arrB[1][0];
arrC[1][1]=arrB[1][1];
}
}
arrA[i][j]=pow(-1,i+j+2)*get_num(arrC); //将2*2矩阵行列式的值代入公式,得到代数余子式的值
printf("getA:%.2f ",get_num(arrC));
}
}
for(v=0; v<3; v++){ //将伴随矩阵转置
for(b=0; b<3; b++){
arrD[b][v]=arrA[v][b];
}
printf("\n");
}
printf("经转置后的伴随矩阵为:\n");
for(v=0; v<3; v++){ //打印经过转置后的伴随矩阵
for(b=0; b<3; b++){
printf("%.2f ",arrD[v][b]);
}
printf("\n");
}
}
double getC(double arrD[3][3],double n){
int i,j;
for(i=0; i<3; i++){ //求A的逆矩阵,参数为伴随矩阵与|A|
for(j=0; j<3; j++){
arrD[i][j]=arrD[i][j]/n;
printf("%.2f ",arrD[i][j]);
}
printf("\n");
}
}
double getD(double noarr[3][3],double vector[3]){ //利用A的逆矩阵与b求x
double x[3];
int i,j;
for(i=0;i<3;i++){
x[i]=noarr[i][0]*vector[0]+noarr[i][1]*vector[1]+noarr[i][2]*vector[2];
printf("%.2f ",x[i]);
}
}
int main(){
int N=3,M=3,i,j,k;
double arr[N][M],vector[3]; //arr[][]为随机生成的矩阵,
srand((unsigned)time(NULL)); //定义时间种子
for(i=0;i<N;i++){ //利用for循环随机生成3*3矩阵
for(j=0;j<M;j++){
arr[i][j]=(rand()%1000)/100;
vector[i]=(rand()%1000)/100;
}
}
printf("随机生成矩阵为arr[%d][%d]:\n",N,M);
for(i=0;i<N;i++){ //输出随机生成的矩阵Arr[3][3]
for(j=0;j<M;j++){
printf("%.2f ",arr[i][j]);
}
printf("\n");
}
printf("\n\n");
printf("随机生成向量为vector[3]:\n");
for(i=0;i<N;i++){ //输出随机生成的向量vector[3]
printf("%.2f ",vector[i]);
}
printf("\n\n\n");
printf("矩阵arr的行列式值为:\n");
double a = getA(arr, 3);
printf("====%.2f====\n\n\n",a);
printf("测试getB函数(生成9个二维数组的行列式值):\n");
getB(arr); //调用getB函数,查看取出的2*2矩阵
printf("\n\n");
printf("矩阵A的逆矩阵为:\n");
getC(arrD,a);
printf("\n\n");
printf("向量x为:\n");
getD(arrD,vector);
printf("\n\n\n");
system("pause");
}
代码解析
目前共有5个函数: Main()用于调用函数,测试,运行整个项目;
GetA()用于求矩阵行列式,已经实现其功能
GetB()用于求A的伴随矩阵;
GetC()求A的逆矩阵,传入参数为A的伴随矩阵,与A的行列式的值
GetD()求X向量,传入参数为A的逆矩阵与向量b
测试程序正确性时可将以下代码(固定赋值初始矩阵与初始向量的值)替换随机生成代码;
arr[0][0]=1; //vector[]为随机生成的向量
arr[0][1]=2;
arr[0][2]=3;
arr[1][0]=2;
arr[1][1]=2;
arr[1][2]=1;
arr[2][0]=3;
arr[2][1]=4;
arr[2][2]=3;
vector[0]=2;
vector[1]=-1;
vector[2]=4;
将下面代码替换
srand((unsigned)time(NULL)); //定义时间种子
for(i=0;i<N;i++){ //利用for循环随机生成3*3矩阵
for(j=0;j<M;j++){
arr[i][j]=(rand()%1000)/100;
vector[i]=(rand()%1000)/100;
}
}
如需源码文件可私信作者
|