|
楼主 |
发表于 2008-7-28 11:28:06
|
显示全部楼层
- #include <stdio.h>
- #include <malloc.h>
- #include <stdlib.h>
- int cofactor(int n,double *p,int k,int l)
- {
- int i,j,h,m;
- for(i=0,h=0;i<n;i++)
- {
- if(i==k)continue;
- for(j=0;j<n;j++,h++)
- {
- if(j==l){h--;continue;}
- p[h]=p[i*n+j];
- }
- }
- m=n-1;
- return m;
- }
- double value_det(int n,double *det)
- {
- int maxi,maxj,i,j;
- double value=1,*p;p=NULL;
- i=0;
- do
- {
- i++;
- p=(double *)malloc(n*n*sizeof(double));
- if(i>100){printf("function value_det() failed because malloc()!\n");exit(0);}
- }
- while(p==NULL);
- for(i=0;i<n*n;i++)p[i]=det[i];
- while(1)
- {
- if(n>=3)
- {
- for(i=0,maxi=0,maxj=0;i<n;i++)for(j=0;j<n;j++)if(p[i*n+j]>p[maxi*n+maxj]){maxi=i;maxj=j;}
- for(i=0,j=0;i<n;i++)if(p[maxi*n+i]==0)j++;
- for(i=0;i<n;i++)if(p[i*n+maxj]==0)j--;
- if(j>=0)
- {
- for(j=0;j<n;j++)
- {
- if(j==maxj||p[maxi*n+j]==0)continue;
- for(i=0;i<n;i++)
- {
- if(i==maxi)continue;
- p[i*n+j]=p[i*n+j]-p[i*n+maxj]*p[maxi*n+j]/p[maxi*n+maxj];
- }
- }
- }
- else {
- for(i=0;i<n;i++)
- {
- if(i==maxi||p[i*n+maxj]==0)continue;
- for(j=0;j<n;j++)
- {
- if(j==maxj)continue;
- p[i*n+j]=p[i*n+j]-p[maxi*n+j]*p[i*n+maxj]/p[maxi*n+maxj];
- }
- }
- }
- if((maxi+maxj)%2==1)value*=-1;
- value*=p[maxi*n+maxj];
- n=cofactor(n,p,maxi,maxj);
- }
- else if(n==2){value*=(p[0]*p[3]-p[1]*p[2]);break;}
- else if(n==1){value*=p[0];break;}
- }
- free(p);
- return value;
- }
- double *solve_cramer(int n,double *mtr)
- {
- double *x,*p,d;
- int i=0,j,k;
- do
- {i++;
- x=(double *)malloc(n*sizeof(double));
- if(i>100){printf("function solve_cramer() failed because malloc()!\n");exit(0);}
- }
- while(x==NULL);i=0;
- do
- {i++;
- p=(double *)malloc(n*n*sizeof(double));
- if(i>100){printf("function solve_cramer() failed because malloc()!\n");exit(0);}
- }
- while(p==NULL);
-
- for(j=0,k=0;k<n*n;j++){if((j+1)%(n+1)==0)continue;p[k]=mtr[j];k++;}
- d=value_det(n,p);
- if(d==0){free(x);x=NULL;}
- else
- {
- for(i=0;i<n;i++)
- {
- for(j=0,k=0;k<n*n;j++){if((j+1)%(n+1)==0)continue;p[k]=mtr[j];k++;}
- for(k=0;k<n;k++)p[k*n+i]=mtr[k*(n+1)+n];
- x[i]=value_det(n,p)/d;
- }
- }
- free(p);
- return x;
- }
- double *multiply_mtr(double *mtr1,double *mtr2,int m,int s,int n)
- {
- double *p1,*p2,*p;
- int i=0,k,j;
- do
- {
- i++;
- p1=(double *)malloc(m*s*sizeof(double));
- if(i>100){printf("function multiply_mtr() failed because malloc()!\n");exit(0);}
- }
- while(p1==NULL);i=0;
- do
- {
- i++;
- p2=(double *)malloc(n*s*sizeof(double));
- if(i>100){printf("function multiply_mtr() failed because malloc()!\n");exit(0);}
- }
- while(p2==NULL);i=0;
- do
- {
- i++;
- p=(double *)malloc(m*n*sizeof(double));
- if(i>100){printf("function multiply_mtr() failed because malloc()!\n");exit(0);}
- }
- while(p==NULL);
- for(i=0;i<m*s;i++)p1[i]=mtr1[i];
- for(i=0;i<s*n;i++)p2[i]=mtr2[i];
- for(i=0;i<m*n;i++)p[i]=0;
- for(i=0;i<m;i++)
- {
- for(j=0;j<n;j++)
- {
- for(k=0;k<s;k++)p[i*n+j]+=p1[i*s+k]*p2[k*n+j];
- }
- }
- free(p1);
- free(p2);
- return p;
- }
- double *transp_mtr(double *mtr,int m,int n)
- {
- double *p;
- int i=0,j;
- do
- {i++;
- p=(double *)malloc(m*n*sizeof(double));
- if(i>100){printf("function transp_mtr() failed by malloc()!\n");exit(0);}
- }
- while(p==NULL);
- for(i=0;i<n;i++)
- for(j=0;j<m;j++)
- p[i*m+j]=mtr[j*n+i];
- return p;
- }
- double *inv_mtr(double *mtr,int n)
- {
- int i=0,j,k;
- double *inver,*p,a;
- inver=NULL;
- p=NULL;
- do
- {i++;
- inver=(double *)malloc(n*n*sizeof(double));
- if(i>100){printf("function inv_mtr() failed by malloc()!\n");exit(0);}
- }
- while(inver==NULL);i=0;
- do
- {i++;
- p=(double *)malloc(n*n*sizeof(double));
- if(i>100){printf("function inv_mtr() failed by malloc()!\n");exit(0);}
- }
- while(p==NULL);
- for(i=0;i<n*n;i++)p[i]=mtr[i];
- if(value_det(n,p)==0){printf("no inverse of the matrix\n");free(p);free(inver);inver=NULL;}
- else
- {
- for(i=0;i<n;i++)
- {
- for(j=0;j<n;j++)
- {
- for(k=0;k<n*n;k++)p[k]=mtr[k];
- k=cofactor(n,p,i,j);
- inver[i*n+j]=value_det(k,p);
- if((i+j)%2==1)inver[i*n+j]*=-1;
- }
- }
- free(p);
- p=inver;
- inver=transp_mtr(p,n,n);
- free(p);
- a=value_det(n,mtr);
- for(i=0;i<n*n;i++)inver[i]/=a;
- }
- return inver;
- }
复制代码 |
|