Search This Blog

Tuesday 19 July 2011

Matrix Manipulation Using C

            Matrix  is a great invention of Mathematics. It is very useful in solving system of equations through computer. Of course famous numerical computing platform, MATLAB is the well known application of matrix.
            In MATLAB everything is matrix. The images are also represented as a matrix in ease. It is easy to perform operations over matrices. This is why the matrix manipulation is an important.
Download the code here
            Here is my matrix library. It may be inefficient, since it is indented for educational purpose. I want to keep things simple so that the beginner also be able to understand. This article is also helpful for learning memory allocation in C, Pointer and its applications, recursion,  modularity.
                                                                
CodeListing
  1. /*----------------------------------------*/
  2. /* Program: matrix.h                      */
  3. /* Author: Vanangamudi                    */
  4. /* Date: 15/05/2011                       */
  5. /*----------------------------------------*/
  6. #include<stdio.h>
  7. #ifndef _MATRIX_H_
  8. #define _MATRIX_H_

  9. typedef struct matrix {
  10. float **mat;
  11. int m,n;
  12. }Matrix;

  13. typedef struct matrixEquation {
  14. Matrix *lhs;
  15. Matrix *rhs;
  16. Matrix *Soln;
  17.  }MatrixEqn;

  18. Matrix * matrix_new_Matrix(int m,int n);
  19. MatrixEqn * matrix_new_MatrixEqn(Matrix* lhs,Matrix *rhs);

  20. float matrix_Det(Matrix *matA);
  21. Matrix* matrix_Cofactor(Matrix *matA);
  22. Matrix* matrix_Minor(Matrix *matA, int m, int n);
  23. Matrix* matrix_Adjoint(Matrix *matA);
  24. Matrix* matrix_Inverse(Matrix *matA);

  25. int matrix_Solve_Det(MatrixEqn *matEqn);
  26. int matrix_Solve_Inv(MatrixEqn *matEqn);

  27. Matrix* matrix_Mult(Matrix *matA , Matrix *matB);
  28. Matrix* matrix_Add(Matrix *matA , Matrix *matB);
  29. Matrix* matrix_Sub(Matrix *matA , Matrix *matB);
  30. Matrix* matrix_tran(Matrix *matA);
  31. Matrix* matrix_ScalarMultiply(float X , Matrix *matA);
  32. Matrix* matrix_Duplicate(Matrix *matA);
  33. Matrix* matrix_ColumnReplace(Matrix *matA, Matrix* matB ,int IndA,int IndB );

  34. int matrix_Print(Matrix *matA);
  35. int matrix_Read(Matrix *matA);

  36. #endif       //_MATRIX_H_

  1. /*-----------------------------------------------*/
  2. /* Program: matrix.c                             */
  3. /* Author: Vanangamudi                           */
  4. /* Date: 15/05/2011                              */
  5. /*-----------------------------------------------*/

  6. #include "matrix.h"
  7. #include<malloc.h>
  8. #include<stdio.h>

  9. //Constructors
  10. Matrix* matrix_new_Matrix(int m, int n)
  11. {
  12.        Matrix *newMat = (Matrix*)malloc(sizeof(float));
  13.        newMat->mat = (float*)malloc(sizeof(float)*m);
  14.     int i = 0;
  15.     for(i =0 ; i < m ; i++){
  16.           newMat->mat[i] = (float*)malloc(sizeof(float)*n);
  17.     }
  18.       newMat->m = m;
  19.       newMat->n = n;
  20.     return newMat;
  21. }

  22. MatrixEqn * matrix_new_MatrixEqn(Matrix *lhs,Matrix *rhs)
  23. {
  24.       MatrixEqn* newEqn = (MatrixEqn*)malloc(sizeof(float));
  25.       newEqn->lhs = matrix_Duplicate(lhs); 
  26.       newEqn->rhs = matrix_Duplicate(rhs);
  27.       newEqn->Soln = matrix_new_Matrix(rhs->m,1);
  28.     return newEqn;
  29. }

  30. // Matrix Operations
  31. Matrix* matrix_Minor(Matrix *matA, int m, int n)
  32. {
  33.     int i,j;
  34.     int p,q;
  35.     Matrix *minor = matrix_new_Matrix(matA->m-1,matA->n-1);
  36.     for(i = 0,p = 0; i < matA->m , p < minor->m; i++){
  37.       if( i != m-1){
  38.          for(j=0, q=0; j <matA->n , q < minor->n; j++){
  39.             if(j != n-1){
  40.               minor->mat[p][q] = matA->mat[i][j];
  41.               q++;
  42.             }
  43.          }
  44.          p++;
  45.       }
  46.     }
  47.     return minor;
  48. }

  49. float matrix_Det(Matrix *matA)
  50. {
  51.     float det=0;
  52.     if((matA->m==1)&&(matA->n==1)){
  53.           det = matA->mat[0][0];
  54.     }else {
  55.       int i;
  56.       int sign=1;
  57.       for(i = 0; i<matA->m ; i++){
  58.          det += sign*matA->mat[0][i]*matrix_Det(matrix_Minor(matA,0,i));
  59.           sign = -1*sign;
  60.       }
  61.     }
  62.     return det;
  63. }

  64. Matrix* matrix_Cofactor(Matrix *matA)
  65. {
  66.     Matrix *Cofact = matrix_new_Matrix(matA->m,matA->n);
  67.     int i,j;
  68.     int sign =1;
  69.     for(i =0 ; i<matA->m;i++){
  70.        for(j=0 ; j<matA->n ; j++){
  71.           Cofact->mat[i][j] = sign*matrix_Det(matrix_Minor(matA,i,j));
  72.           sign = sign * (-1);
  73.        }
  74.        if(matA->m%2 == 0){
  75.               sign = (-1)*sign;
  76.        }
  77.     }
  78.     return Cofact;
  79. }

  80. Matrix* matrix_Adjoint(Matrix *matA)
  81. {
  82.      Matrix *Cofact = matrix_Cofactor(matA);
  83.      Matrix *Adj = matrix_tran(Cofact);
  84.      return Adj;
  85. }

  86. Matrix* matrix_Inverse(Matrix *matA)
  87. {
  88.     Matrix *Inv = matrix_Adjoint(matA);
  89.     float Det = matrix_Det(matA);
  90.     Inv = matrix_ScalarMultiply(1/Det, Inv);
  91.     return Inv;
  92. }

  93. //Arithmetics
  94. Matrix* matrix_Mult(Matrix *matA , Matrix *matB)
  95. {
  96.      if(matA->n != matB->m){
  97.         printf("\nMatrices cannot be multiplied");
  98.         return NULL;
  99.      }else{
  100.              Matrix *matC = matrix_new_Matrix(matA->m,matB->n);
  101.         int i,j,k;
  102.         for(i = 0 ;i< matB->m; i++){
  103.            for(j=0; j < matB->n ; j++){
  104.               matC->mat[i][j] = 0;
  105.               for( k =0;k < matA->n;k++){
  106.                  matC->mat[i][j]+=matA->mat[i][k]*matB->mat[k][j];
  107.               }
  108.             }
  109.          }
  110.         return matC;
  111.      }
  112. }

  113. Matrix* matrix_ScalarMultiply(float X , Matrix *matA)
  114. {
  115.         Matrix *matB = matrix_new_Matrix(matA->m,matA->n);
  116.      int i,j;
  117.      for(i = 0 ;i< matA->m; i++){
  118.         for(j=0; j < matA->n ; j++){
  119.            matB->mat[i][j] = X * matA->mat[i][j];
  120.         }
  121.      }
  122.      return matB;
  123. }

  124. Matrix* matrix_Add(Matrix *matA , Matrix *matB)
  125. {
  126.         Matrix *matC = matrix_new_Matrix(matA->m,matA->n);
  127.      int i,j;
  128.      for(i = 0 ;i< matA->m; i++){
  129.         for(j=0; j < matA->n ; j++){
  130.           matC->mat[i][j] = matA->mat[i][j]+matB->mat[i][j];
  131.         }
  132.      }
  133.       return matC;
  134. }

  135. Matrix* matrix_Sub(Matrix *matA , Matrix *matB)
  136. {
  137.         Matrix *matC = matrix_new_Matrix(matA->m,matA->n);
  138.      int i,j;
  139.      for(i = 0 ;i< matA->m; i++){
  140.         for(j=0; j < matA->n ; j++){
  141.            matC->mat[i][j] = matA->mat[i][j]-matB->mat[i][j];
  142.         }
  143.      }
  144.      return matC;
  145. }

  146. Matrix* matrix_tran(Matrix *matA)
  147. {
  148.     Matrix *matB = matrix_new_Matrix(matA->n,matA->m);
  149.     int i,j;
  150.     for(i = 0 ;i< matB->m; i++){
  151.        for(j=0; j < matB->n ; j++){
  152.           matB->mat[i][j] = matA->mat[j][i];
  153.        }
  154.     }
  155.     return matB;
  156. }

  157. //Matrix Eqn Solvers
  158. int matrix_Solve_Inv(MatrixEqn *matEqn)
  159. {
  160.     Matrix* Inv = matrix_Inverse(matEqn->lhs);
  161.     matEqn->Soln = matrix_Mult(Inv,matEqn->rhs);
  162. }

  163. int matrix_Solve_Det(MatrixEqn *matEqn)
  164. {
  165.     float Det = matrix_Det(matEqn->lhs);
  166.     Matrix* matA;
  167.     float DetXYZ;
  168.     int i;
  169.     for(i = 0;i <matEqn->Soln->m;i++){
  170.       matA = matrix_ColumnReplace(matEqn->lhs,matEqn->rhs,i+1,1);
  171.       DetXYZ = matrix_Det(matA);
  172.       matEqn->Soln->mat[i][0] = DetXYZ/Det;
  173.     }
  174. }

  175. //Misc
  176. Matrix* matrix_ColumnReplace(Matrix *matA, Matrix* matB ,int IndA,int IndB )
  177. {
  178.        Matrix* matC = matrix_Duplicate(matA);
  179.     int i;
  180.     for(i = 0;i<matA->n; i++){
  181.             matC->mat[i][IndA-1] = matB->mat[i][IndB-1];
  182.     }
  183.     return matC;
  184. }

  185. Matrix* matrix_Duplicate(Matrix *matA)
  186. {
  187.        Matrix *matB = matrix_new_Matrix(matA->m,matA->n);
  188.     int i,j;
  189.     for(i = 0 ;i< matB->m; i++){
  190.        for(j=0; j < matB->n ; j++){
  191.                 matB->mat[i][j] = matA->mat[i][j];
  192.        }
  193.     }
  194.     return matB;
  195. }

  196. //IO Operations
  197. int matrix_Read(Matrix *matA)
  198. {
  199.      int i=0 , j=0;
  200.         printf("\nEnter the Elements:\n");
  201.      for(i = 0; i < matA->m; i++){
  202.         for(j = 0; j < matA->n; j++ ){
  203.                  scanf("%f",&matA->mat[i][j]);
  204.         }
  205.      }
  206. }

  207. int matrix_Print(Matrix *matA)
  208. {
  209.      int i=0 , j=0;
  210.         printf("\n");
  211.      for(i = 0; i < matA->m; i++){
  212.         for(j = 0; j < matA->n; j++ ){
  213.                  printf("%0.3f\t",matA->mat[i][j]);
  214.         }
  215.              printf("\n\n");
  216.      }
  217.      return 0;
  218. }

Sample Program to Test
  1. /*-----------------------------------------------------*/
  2. /* Program: matrix_test.c                              */
  3. /* Author  : Vanangamudi                               */
  4. /* Date     :15/05/2011                                */
  5. /*-----------------------------------------------------*/

  6. #include "matrix.h"
  7. #include<stdio.h>

  8. int main()
  9. {
  10.     Matrix *matA  = matrix_new_Matrix(3,3);
  11.     Matrix *matB  = matrix_new_Matrix(3,3);

  12.     printf("\t\t|--------------------------|");
  13.     printf("\n\t\t|**************************|");
  14.     printf("\n\t\t|*** MATRIX ILLUSTRATION **|\n");
  15.     printf("\t\t|**************************|\n");
  16.     printf("\t\t|--------------------------|\n\n");

  17.     matrix_Read(matA);
  18.     matrix_Read(matB);

  19.     printf("\nmatA + matB:\n");
  20.     matrix_Print(matrix_Add(matA,matB));

  21.     printf("\nmatA - matB:\n");
  22.     matrix_Print(matrix_Sub(matA,matB));

  23.     printf("\nmatA * matB:\n");
  24.     matrix_Print(matrix_Mult(matA,matB));

  25.     printf("\n5 * matA:\n");
  26.     matrix_Print(matrix_ScalarMultiply(5,matA));

  27.     printf("\nTranspose ofmatA :\n");
  28.     matrix_Print(matrix_tran(matA));

  29.     printf("\nDeterminant of matA:\t");
  30.     printf("%f",matrix_Det(matA));

  31.     printf("\nCofactor matrix of matA :\n");
  32.     matrix_Print(matrix_Cofactor(matA));
  33.     printf("\nInverse matrix of matA:\n");
  34.     matrix_Print(matrix_Inverse(matA));
  35.     printf("\nMinor matrix of ( i , j) = (1,1) of matA:\n");
  36.     matrix_Print(matrix_Minor(matA,1,1));

  37.     return 0;
  38. }
        Once we wrote a library with generic functions, it easy to develop some projects easily based on our own library. Even though, there are many efficient scientific and mathematical libraries available free of charge.  We learn Programming easily through writing programs like this. 
Happy coding!!!

No comments:

Post a Comment