矩陣運算庫

#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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章