#ifndef _MATRIX_H_
/********************************
* matrix.h *
* 矩陣運算庫 *
* edit 2004-8-9 *
* 版本1.0 *
*********************************
矩陣計算的幾個函數
atV計算轉置
abV計算a×b
abaddV計算a+b
absubV計算a-b
inputaV輸入矩陣
printaV輸出矩陣
求逆
int a_1V(double *in,double *out,int n)
轉置
int atV(double *in,double *out,int m,int n)
矩陣相乘
int abV(double *a,double *b,double *out,int am,int an,int bm,int bn)
矩陣相加
int abaddV(double *a,double *b,double *out,int m,int n)
矩陣相減
int absubV(double *a,double *b,double *out,int m,int n)
輸出
printaV(double *a,int m,int n)
輸入
inputaV(double *a,int m,int n)
*/
/* 轉置一個矩陣,矩陣存在一個一維數組in中,輸出也存在一個一維數組out
矩陣列數和維數由n指定,
調用可以使用數組,例
二維數組調用方式
atV(double in[n][n],double out[n][m],int m,int n)
一維調用方式
atV(double in[k],double out[k],int m,int n)
指針調用方式
atV(double *in,double *out,int m,int n)
*/
#include <malloc.h>
#include <math.h>
int atV(double *in,double *out,int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
*(out+ j*m +i)=*(in+ i*n +j);
}
return 1;
}
/* 矩陣相乘
out
am an 爲矩陣a的行數和列數
bm nn 爲矩陣b的行數和列數
矩陣列數和維數由n指定
調用可以使用數組,例
二維數組調用方式
avV(double a[am][an],double b[bm][bn],double out[am][bn],int am,int an,int bm,
int bn)
一維調用方式
avV(double a[k],double b[l],double out[j],int am,int an,int bm,int bn)
指針調用方式
avV(double *a,double *b,double *out,int am,int an,int bm,int bn)
*/
int abV(double *matrixa,double *matrixb,double *out,int am,int an,int bm,int bn)
{
int i,j,k;
double temp;
if(an!=bm) {return 0;} /*矩陣不可以計算*/
for(i=0;i<am;i++)
{
for(j=0;j<bn;j++)
{
for(k=0,temp=0;k<an;k++)
temp=temp + *(matrixa+i*an+k) * *(matrixb+k*bn+j);
*(out+i*bn+j) = temp;
}
}
return 1;
}
/*輸入一個m*n的矩陣,也可以輸出m*n數組以及一維數組按m*n輸出*/
int inputaV(double *matrixa,int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
printf("請輸入第%d行/n",i+1);
for(j=0;j<n;j++)
{
scanf("%lf",(matrixa+i*n+j));
}
}
return 1;
}
/*輸入一個m*n矩陣,也可以輸出m*n數組以及一維數組按m*n輸出*/
printaV(double *matrixa,int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
printf("%lf ",*(matrixa+i*n+j));
printf("/n");
}
printf("/n");
}
void initiones(double *q,int n) /*形成單位矩陣*/
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{ if(i==j)
q[i*n+j]=1;
else
q[i*n+j]=0;
}
}
void swap(double *r,int i,int line,int n) /*換行*/
{
int j;
double m;
for(j=0;j<n;j++)
{ m=r[i*n+j];
r[i*n+j]=r[line*n+j];
r[line*n+j]=m;
}
}
int solve(double *p,double *q,int n) /*形成下三角矩陣*/
{
int i ,j,k,m,line;
double max,temp,savep;
for (i=0;i<n;i++)
{ max=fabs(p[i*n+i]);
temp=p[i*n+i];
line=i;
for (j=i+1;j<n;j++)
{ if( fabs(p[j*n+i]) > max ) /*找出絕對值最大元*/
{line=j;
max=fabs(p[j*n+i]);
temp=p[j*n+i]; }
}
if(max<=1e-5) /*三角矩陣的對角元等於0則無解*/
{
return 0;}
if(line!=i)
{ swap(p,i,line,n);
swap(q,i,line,n);}
for (k=0;k<n;k++)
{p[i*n+k]/=temp;
q[i*n+k]/=temp;}
for(k=i+1;k<n;k++) /*消元,成下三角陣;*/
{ savep=p[k*n+i];
for( m=0;m<n;m++)
{ q[k*n+m]=q[k*n+m]-q[i*n+m]*savep;
p[k*n+m]=p[k*n+m]-p[i*n+m]*savep;}
}
}
return 1;
}
void backloop(double *p,double *q,int n) /*迴帶,形成單位矩陣*/
{
int i,j,k;
double savep;
for(i=n-1;i>0;i--)
{
for(j=i-1;j>=0;j--)
{
savep=p[j*n+i];
p[j*n+i]=p[j*n+i]-p[i*n+i]*savep;
for(k=0;k<n;k++)
q[j*n+k]=q[j*n+k]-q[i*n+k]*savep;
}
}
}
/*求a的逆陣,in爲輸入陣,out爲輸出的逆陣,n爲維數*/
int a_1V(double *in,double *out,int n)
{
double *p;
int i,j;
p=(double *)malloc(sizeof(double)*(n*n));
for(i=0;i<n;i++)
for(j=0;j<n;j++) p[j*n+i]=in[j*n+i];
initiones(out,n);
if(!solve(p,out,n)) {return 0;}
backloop(p,out,n);
return 1;
}
/*求矩陣和,a,b爲輸入陣,out爲和的矩陣,m,n爲行和列*/
int abaddV(double *matrixa,double *matrixb,double *out,int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
*(out+i*n+j)=*(matrixa+i*n+j)+*(matrixb+i*n+j);
}
return 1;
}
/*求矩陣差,a,b爲輸入陣,out爲差的矩陣,m,n爲行和列*/
int absubV(double *matrixa,double *matrixb,double *out,int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
*(out+i*n+j)=*(matrixa+i*n+j)-*(matrixb+i*n+j);
}
return 1;
}
#endif