1. 程式人生 > >在C中實現矩陣運算

在C中實現矩陣運算

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

本文部落格連結:http://blog.csdn.net/jdh99,作者:jdh,轉載請註明.


環境:

主機:XP

開發環境:mingw


功能:

在C++中實現矩陣運算


說明:

將這篇文章(http://blog.csdn.net/jdh99/article/details/7360091)中在C++下實現的矩陣運算移植到C下,以便在微控制器中運算.


原始碼:

matrix.h:

#ifndef _MATRIX_H  #define _MATRIX_H//標頭檔案  #include <stdio.h>  #include <stdlib.h>    //矩陣資料結構  //二維矩陣  struct _Matrix
  {
       int m;      int n;      float *arr;  }; //矩陣方法//設定m  void matrix_set_m(struct _Matrix *m,int mm)//設定n  void matrix_set_n(struct _Matrix *m,int nn)//初始化  void matrix_init(struct _Matrix *m)//釋放 
void matrix_free(struct _Matrix *m)//讀取i,j座標的資料  //失敗返回-31415,成功返回值  float matrix_read(struct _Matrix *m,int i,int j)//寫入i,j座標的資料  //失敗返回-1,成功返回1  int matrix_write(struct _Matrix *m,int i,int j,float val); //矩陣運算//成功返回1,失敗返回-1  int matrix_add(struct _Matrix *A,struct _Matrix *B,struct _Matrix *C)//C = A - B  //成功返回1,失敗返回-1  int matrix_subtract(struct _Matrix *A,struct _Matrix *B,struct _Matrix *C)//C = A * B  //成功返回1,失敗返回-1  int matrix_multiply(struct _Matrix *A,struct _Matrix *B,struct _Matrix *C)//行列式的值,只能計算2 * 2,3 * 3  //失敗返回-31415,成功返回值  float matrix_det(struct _Matrix *A)//求轉置矩陣,B = AT  //成功返回1,失敗返回-1  int matrix_transpos(struct _Matrix *A,struct _Matrix *B)//求逆矩陣,B = A^(-1)  //成功返回1,失敗返回-1  int matrix_inverse(struct _Matrix *A,struct _Matrix *B);    #endif 

matrix.c:

#include "matrix.h"//矩陣方法//設定m  void matrix_set_m(struct _Matrix *m,int mm){ m->m = mm; }//設定n  void matrix_set_n(struct _Matrix *m,int nn){ m->n = nn;}//初始化  void matrix_init(struct _Matrix *m){ m->arr = (float *)malloc(m->m * m->n * sizeof(float));}//釋放  void matrix_free(struct _Matrix *m)free(m->arr);}//讀取i,j座標的資料  //失敗返回-31415,成功返回值  float matrix_read(struct _Matrix *m,int i,int j)if (i >= m->m || j >= m->n)      {          return -31415;      }            return *(m->arr + i * m->n + j);  }//寫入i,j座標的資料  //失敗返回-1,成功返回1  int matrix_write(struct _Matrix *m,int i,int j,float val)if (i >= m->m || j >= m->n)      {          return -1;      }            *(m->arr + i * m->n + j) = val;      return 1;  }//矩陣運算//成功返回1,失敗返回-1  int matrix_add(struct _Matrix *A,struct _Matrix *B,struct _Matrix *C)int i = 0;      int j = 0;            //判斷是否可以運算   if (A->m != B->m || A->n != B->n || \        A->m != C->m || A->n != C->n)      {          return -1;      }      //運算      for (i = 0;i < C->m;i++)      {          for (j = 0;j < C->n;j++)          {              matrix_write(C,i,j,matrix_read(A,i,j) + matrix_read(B,i,j));          }      }            return 1; }//C = A - B  //成功返回1,失敗返回-1  int matrix_subtract(struct _Matrix *A,struct _Matrix *B,struct _Matrix *C)int i = 0;      int j = 0;            //判斷是否可以運算      if (A->m != B->m || A->n != B->n || \        A->m != C->m || A->n != C->n)      {          return -1;      }      //運算      for (i = 0;i < C->m;i++)      {          for (j = 0;j < C->n;j++)          {              matrix_write(C,i,j,matrix_read(A,i,j) - matrix_read(B,i,j));          }      }            return 1; }//C = A * B  //成功返回1,失敗返回-1  int matrix_multiply(struct _Matrix *A,struct _Matrix *B,struct _Matrix *C)int i = 0;      int j = 0;      int k = 0;      float temp = 0;            //判斷是否可以運算      if (A->m != C->m || B->n != C->n || \        A->n != B->m)      {          return -1;      }      //運算      for (i = 0;i < C->m;i++)      {          for (j = 0;j < C->n;j++)          {              temp = 0;              for (k = 0;k < A->n;k++)              {                  temp += matrix_read(A,i,k) * matrix_read(B,k,j);              }              matrix_write(C,i,j,temp);          }      }            return 1; }//行列式的值,只能計算2 * 2,3 * 3  //失敗返回-31415,成功返回值  float matrix_det(struct _Matrix *A)float value = 0;            //判斷是否可以運算      if (A->m != A->n || (A->m != 2 && A->m != 3))      {          return -31415;      }      //運算      if (A->m == 2)      {          value = matrix_read(A,0,0) * matrix_read(A,1,1) - matrix_read(A,0,1) * matrix_read(A,1,0);      }      else      {          value = matrix_read(A,0,0) * matrix_read(A,1,1) * matrix_read(A,2,2) + \                matrix_read(A,0,1) * matrix_read(A,1,2) * matrix_read(A,2,0) + \                matrix_read(A,0,2) * matrix_read(A,1,0) * matrix_read(A,2,1) - \                matrix_read(A,0,0) * matrix_read(A,1,2) * matrix_read(A,2,1) - \                matrix_read(A,0,1) * matrix_read(A,1,0) * matrix_read(A,2,2) - \                matrix_read(A,0,2) * matrix_read(A,1,1) * matrix_read(A,2,0);      }            return value; }//求轉置矩陣,B = AT  //成功返回1,失敗返回-1  int matrix_transpos(struct _Matrix *A,struct _Matrix *B)int i = 0;      int j = 0;            //判斷是否可以運算      if (A->m != B->n || A->n != B->m)      {          return -1;      }      //運算      for (i = 0;i < B->m;i++)      {          for (j = 0;j < B->n;j++)          {              matrix_write(B,i,j,matrix_read(A,j,i));          }      }            return 1;  }//求逆矩陣,B = A^(-1)  //成功返回1,失敗返回-1  int matrix_inverse(struct _Matrix *A,struct _Matrix *B)int i = 0;      int j = 0;      int k = 0;      struct _Matrix m;      float temp = 0;      float b = 0;            //判斷是否可以運算      if (A->m != A->n || B->m != B->n || A->m != B->m)      {          return -1;      }            /*     //如果是2維或者3維求行列式判斷是否可逆     if (A->m == 2 || A->m == 3)     {         if (det(A) == 0)         {             return -1;         }     }     */            //增廣矩陣m = A | B初始化    matrix_set_m(&m,A->m); matrix_set_n(&m,2 * A->m); matrix_init(&m);    for (i = 0;i < m.m;i++)      {          for (j = 0;j < m.n;j++)          {              if (j <= A->n - 1)              {                  matrix_write(&m,i,j,matrix_read(A,i,j));              }              else              {                  if (i == j - A->n)                  {                      matrix_write(&m,i,j,1);                  }                  else                  {                      matrix_write(&m,i,j,0);                  }              }          }      }            //高斯消元      //變換下三角      for (k = 0;k < m.m - 1;k++)      {          //如果座標為k,k的數為0,則行變換          if (matrix_read(&m,k,k) == 0)          {              for (i = k + 1;i < m.m;i++)              {                  if (matrix_read(&m,i,k) != 0)                  {                      break;                  }              }              if (i >= m.m)              {                  return -1;              }              else              {                  //交換行                  for (j = 0;j < m.n;j++)                  {                      temp = matrix_read(&m,k,j);                      matrix_write(&m,k,j,matrix_read(&m,k + 1,j));                      matrix_write(&m,k + 1,j,temp);                  }              }          }                    //消元          for (i = k + 1;i < m.m;i++)          {              //獲得倍數              b = matrix_read(&m,i,k) / matrix_read(&m,k,k);              //行變換              for (j = 0;j < m.n;j++)              {                  temp = matrix_read(&m,i,j) - b * matrix_read(&m,k,j);                  matrix_write(&m,i,j,temp);              }          }      }      //變換上三角      for (k = m.m - 1;k > 0;k--)      {          //如果座標為k,k的數為0,則行變換          if (matrix_read(&m,k,k) == 0)          {              for (i = k + 1;i < m.m;i++)              {                  if (matrix_read(&m,i,k) != 0)                  {                      break;                  }              }              if (i >= m.m)              {                  return -1;              }              else              {                  //交換行                  for (j = 0;j < m.n;j++)                  {                      temp = matrix_read(&m,k,j);                      matrix_write(&m,k,j,matrix_read(&m,k + 1,j));                      matrix_write(&m,k + 1,j,temp);                  }              }          }                    //消元          for (i = k - 1;i >= 0;i--)          {              //獲得倍數              b = matrix_read(&m,i,k) / matrix_read(&m,k,k);              //行變換              for (j = 0;j < m.n;j++)              {                  temp = matrix_read(&m,i,j) - b * matrix_read(&m,k,j);                  matrix_write(&m,i,j,temp);              }          }      }      //將左邊方陣化為單位矩陣      for (i = 0;i < m.m;i++)      {          if (matrix_read(&m,i,i) != 1)          {              //獲得倍數              b = 1 / matrix_read(&m,i,i);              //行變換              for (j = 0;j < m.n;j++)              {                  temp = matrix_read(&m,i,j) * b;                  matrix_write(&m,i,j,temp);              }          }      }      //求得逆矩陣      for (i = 0;i < B->m;i++)      {          for (j = 0;j < B->m;j++)          {              matrix_write(B,i,j,matrix_read(&m,i,j + m.m));          }      }      //釋放增廣矩陣      matrix_free(&m);            return 1; }

main.c:(測試程式碼)

#include <stdio.h>#include "matrix.h"//列印2維矩陣void printf_matrix(struct _Matrix *A)int i = 0int j = 0int m = 0int n = 0;  m = A->m; n = A->n; for (i = 0;i < m;i++) {  for (j = 0;j < n;j++)  {   printf("%f\t",matrix_read(A,i,j));  }  printf("\n"); }}int main()int i = 0int j = 0int k = 0struct _Matrix m1; struct _Matrix m2; struct _Matrix m3;  //初始化記憶體 matrix_set_m(&m1,3); matrix_set_n(&m1,3); matrix_init(&m1); matrix_set_m(&m2,3); matrix_set_n(&m2,3); matrix_init(&m2); matrix_set_m(&m3,3); matrix_set_n(&m3,3); matrix_init(&m3);  //初始化資料 k = 1for (i = 0;i < m1.m;i++) {  for (j = 0;j < m1.n;j++)  {   matrix_write(&m1,i,j,k++);  } }  for (i = 0;i < m2.m;i++) {  for (j = 0;j < m2.n;j++)  {   matrix_write(&m2,i,j,k++);  } }  //原資料 printf("A:\n"); printf_matrix(&m1); printf("B:\n"); printf_matrix(&m2);  printf("A:行列式的值%f\n",matrix_det(&m1));  //C = A + B if (matrix_add(&m1,&m2,&m3) > 0) {  printf("C = A + B:\n");  printf_matrix(&m3); }  //C = A - B if (matrix_subtract(&m1,&m2,&m3) > 0) {  printf("C = A - B:\n");  printf_matrix(&m3); }  //C = A * B if (matrix_multiply(&m1,&m2,&m3) > 0) {  printf("C = A * B:\n");  printf_matrix(&m3); }  //C = AT if (matrix_transpos(&m1,&m3) > 0) {  printf("C = AT:\n");  printf_matrix(&m3); }  if (matrix_inverse(&m1,&m3) > 0) {  printf("C = A^(-1):\n");  printf_matrix(&m3); }  getchar(); return 0;}



           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述