矩阵求逆及行列式求值 - 未来再来添点更多矩阵计算功能

来源:互联网 发布:知之网官网 编辑:程序博客网 时间:2024/04/30 12:46

   正在研究GTK+,争取尽快写出带有框体的程序,这个行列式的程序算是先写着练练手,感受一下递归调用函数吧,应该算是DFS吧,写起来实在是方便。

2014.3.3 修改

之前犯了很严重的错误,b[MAXNUM][MAXNUM]数组放在complemet_calculate函数内部,为自动变量,而返回的时候返回的b数组的指针,返回函数体内部声明定义的数组地址是很不安全的,之前能够正确运行的原因是函数结束时释放该自动变量,但该地址所拥有的数据暂时没有改动,系统知识标记了该部分数据可以修改,并不是进行数据的清空,所以指向该处的指针仍然可以正确读取数据。而一旦系统修改了这部分数据,程序就会出现不可预知的错误。

安全的做法应当是在不需要同时存在的情况下,把b数组声明为外部数组,就不会产生上述问题了。


2014.1.3 修改作
1.因为有了行列式计算的函数,于是就写了矩阵求逆的函数加了进去,现在已经可以计算行列式大小,输出伴随矩阵,输出余子式,代数余子式。矩阵的迹很好算,就先没有写,未来再加入计算A^2 ,计算矩阵的秩,计算矩阵特征值等等。(开始时因为只是想算行列式,输入函数写的时候只能输入为方阵,为了让函数有广泛适用性,添加着几个功能的时候应该还要修改一下输入函数。)
2.发现代数余子式的正负号似乎是错的,改了一下


#include <stdio.h>#include <math.h>#include <conio.h>#define MAXNUM 100     //行列式最大大小float b[MAXNUM][MAXNUM]; //complemet_calculate函数的临时数组,声明为外部变量防止数据丢失float* complement_calculate(float a[][MAXNUM],int n,int x,int y) //余子式矩阵计算函数,返回一个n-1阶二维数组指针{    int i,j,m,p;    memset(b,0,n-1);    for(i=0,m=0;i<=n-1;m++,i++)    {        if(i==(x-1))        {            m--            ;            continue;        }        for(j=0,p=0;j<=n-1;p++,j++)        {            if(j==(y-1))            {                p--;                continue;            }            b[m][p]=a[i][j];        }    }    return b;}float determinant_calculate(float a[][MAXNUM],int n) //行列式计算函数{    float result=0;    int i;    if(n==1)        return a[0][0];    else    {        for(i=0;i<=n-1;i++)        {            result+=pow(-1,1+(i+1))*a[0][i]*determinant_calculate(complement_calculate(a,n,1,i+1),n-1);        }    }    return result;}int determinant_input(float a[][MAXNUM])  //行列式输入函数,返回行列式大小n{    int i,n=0,j;    char c;    for(i=0;i<=MAXNUM-1;i++)    {        scanf("%f%c",&a[0][i],&c);        n++;        if(c=='\n')     break;    }    for(j=1;j<=n-1;j++)    {        for(i=0;i<=n-1;i++)        {            scanf("%f",&a[j][i]);        }    }    return n;}void show(float a[][MAXNUM],int n)  //显示n阶矩阵函数,测试用{    int i,j;    for(i=0;i<=n-1;i++)    {        for(j=0;j<=n-1;j++)        {            printf("%g ",a[i][j]);        }        printf("\n");    }}float *inverse_matrix_calculate(float a[][MAXNUM],int n) //逆矩阵计算函数,若不可逆,返回空指针NULL{    float b[MAXNUM][MAXNUM];    memset(b,0,MAXNUM);    int i,j;    float determinant=determinant_calculate(a,n);    if(determinant==0)        return NULL;   //若行列式的值为0,则矩阵不为可逆矩阵    else        for(i=0;i<=n-1;i++)        {            for(j=0;j<=n-1;j++)            {                b[j][i]=(pow(-1,i+1+j+1)*determinant_calculate(complement_calculate(a,n,i+1,j+1),n-1))/determinant;   //这里i j位置互换以达到转置的目的                if(fabs(b[j][i])<=1.e-5)   //消除误差                    b[j][i]=0;            }        }    return b;}int main(){    float a[MAXNUM][MAXNUM];    int n;  //n为矩阵大小(n*n)    float *p;    memset(a,0,MAXNUM);    n=determinant_input(a);    p=inverse_matrix_calculate(a,n);    if(p!=NULL)        show(p,n);    else        printf("Error ! The matrix can not be inverted .");    getch();    return 0;}


0 0
原创粉丝点击