Search This Blog

Saturday, 28 July 2012

Get Started: OpenCV development

    Setting up OpenCV development environment in Ubuntu 12.04. In general, if you want to use any of the development libraries or API's, you need to download the development packages. This packages contains headers required, and pre-compiled libraries available for linking from our executable or our custom library. In ubuntu, these packages are suffixed with "-dev".
 for example: libopencv-dev, libcv-dev.
Installing OpenCV:
   Installing opencv development libraries is very simple. I have used Synaptic Package manager to install opencv libraries, and their dependencies.

Here is the screenshot:

   Second one is the source code editor setup. Setting up an source editor requires another separate post. I'll use emacs and will post the instruction soon.

    Then comes the compilation part. Almost all the projects written in C/C++ use GCC/G++ compiler for compilation.

Compilation command syntax is:
  gcc -oOutputFilename SourceFilename.c `pkg-config opencv --cflags --libs`

where, gcc : compiler,
            OutputFilename : the name of the compiled executable or library,
            SourceFilename.c: the name of file containing source code,
            pkg-config: a utility used ease the job for including library headers.
                  pkg-config arguments.
                         opencv: tell the pkg-config utility to provide the paths for
                         libraries related to OpenCV.
                         - -cflags: option to obtain paths to headers.
                         - -libs:     option to obtain paths to libs.

     and note that it's  | ` | and not |  ' | in the compilation command.

Friday, 20 April 2012

Packing Widgets in GTKmm: My Experiment

Yes. This code compiles successfully. I have just completed an experiment based on the tutorial  from Programming with GTKmm by Murray Cumming.


Here is the code:

main.cpp
#include<gtkmm.h>
#include "MyWindow.h"


int main(int argc,char** argv)
{
    Gtk::Main kit(argc,argv);
    MyWindow window;
    Gtk::Main::run(window);
    return 0;
}


MyWindow.h

#ifndef GTKMM_TUT_CHKBUTTON_H
#define GTKMM_TUT_CHKBUTTON_H
#include<gtkmm.h>
#include<gtkmm/window.h>
class MyWindow: public Gtk::Window
{
    public:
        MyWindow();
        ~MyWindow();


    protected:
        //Signal Handlers
        //virtual void OnChkDisplayFlag_Toggled();
        virtual void OnBtnClose_Clicked();
        //virtual void OnAdjDigit();
        //virtual void OnAdjPageSize();


        Gtk::VBox m_vbxMain, m_vbxScale_Scroll;
        Gtk::HBox m_hbxVert_Horiz, m_hbxValuePos, 
              m_hbxUpdatePolicy, m_hbxDigit, m_hbxPageSize;


        Gtk::CheckButton m_chkDisplayFlag;
        Gtk::Label m_lblValuePos, m_lblUpdatePolicy,
                                 m_lblDigit, m_lblPageSize;


        //ComboBox
        Gtk::ComboBox m_cbxValuePos, m_cbxUpdatePolicy;


        class ModelColumns : public Gtk::TreeModelColumnRecord
        {
            public:
                ModelColumns()
                {
                    add(m_iID); add(m_sChoice);
                }
                Gtk::TreeModelColumn<int> m_iID;
                Gtk::TreeModelColumn<Glib::ustring> m_sChoice;
        };


        ModelColumns m_MC_UpdatePolicy, m_MC_ValuePos;
        Glib::RefPtr<Gtk::ListStore> mpLS_ValuePos, 
                                       mpLS_UpdatePolicy;


        Gtk::Adjustment m_adjVert, m_adjDigit, m_adjPageSize;
        Gtk::VScale m_vscVert ;
        Gtk::HScale m_hscHoriz,m_hscDigit,m_hscPageSize;
        Gtk::HScrollbar m_hsScroll;


        Gtk::HSeparator m_hspSep;
        Gtk::Button m_btnClose;


};
#endif //GTKMM_TUT_CHKBUTTON_H


MyWindow.cpp
#include"MyWindow.h"
#include<stdio.h>


MyWindow::MyWindow()
:
    m_vbxMain(false,30),
    m_vbxScale_Scroll(false,10),
    //m_vbxCloseButton(false,10),


    m_hbxVert_Horiz(false,10),
    m_hbxValuePos(false,10),
    m_hbxUpdatePolicy(false,10),
    m_hbxDigit(false,10),
    m_hbxPageSize(false,10),


    m_chkDisplayFlag("Display values in the Widgets",0),


    m_lblValuePos("Value Position"),
    m_lblUpdatePolicy("Update Policy"),
    m_lblDigit("Scale Digits"),
    m_lblPageSize("Page Size"),


    //Gtk::Adjustment::Adjustment (value,lower,upper,
                       step_increment,page_increment,page_size)
    m_adjVert(0.0 , 0.0, 101.0, 0.1, 1.0, 1.0),
    m_adjDigit(1.0, 0.0, 5.0),
    m_adjPageSize(1.0, 0.0, 101.1),


    m_hscHoriz(m_adjVert),
    m_vscVert(m_adjVert),
    m_hscDigit(m_adjDigit),
    m_hscPageSize(m_adjPageSize),


    m_hsScroll(m_adjVert),


    m_btnClose("Close")
{
    set_title("Ranging Widgets");


    //Vertical Scaler widget
    m_vscVert.set_update_policy(Gtk::UPDATE_CONTINUOUS);
    m_vscVert.set_digits(1);
    m_vscVert.set_value_pos(Gtk::POS_TOP);
    m_vscVert.set_draw_value();




    //Vertical Scaler widget
    m_hscHoriz.set_update_policy(Gtk::UPDATE_CONTINUOUS);
    m_hscHoriz.set_digits(1);
    m_hscHoriz.set_value_pos(Gtk::POS_TOP);
    m_hscHoriz.set_draw_value();
    m_hscHoriz.set_size_request(200,30);


    m_hscDigit.set_update_policy(Gtk::UPDATE_CONTINUOUS);
    m_hscDigit.set_digits(1);
    m_hscDigit.set_value_pos(Gtk::POS_TOP);
    m_hscDigit.set_draw_value();
    m_hscDigit.set_size_request(200,30);


    m_hscPageSize.set_update_policy(Gtk::UPDATE_CONTINUOUS);
    m_hscPageSize.set_digits(1);
    m_hscPageSize.set_value_pos(Gtk::POS_TOP);
    m_hscPageSize.set_draw_value();
    m_hscPageSize.set_size_request(200,30);




    //ComboBox-ValuePos
    mpLS_ValuePos = Gtk::ListStore::create(m_MC_ValuePos);
    m_cbxValuePos.set_model(mpLS_ValuePos);


    Gtk::TreeModel::Row row = *(mpLS_ValuePos->append());
    row[m_MC_ValuePos.m_iID] = 1;
    row[m_MC_ValuePos.m_sChoice] = "Top";




    row = *(mpLS_ValuePos->append());
    row[m_MC_ValuePos.m_iID] = 2;
    row[m_MC_ValuePos.m_sChoice] = "Right";


    row = *(mpLS_ValuePos->append());
    row[m_MC_ValuePos.m_iID] = 3;
    row[m_MC_ValuePos.m_sChoice] = "Bottom";




    row = *(mpLS_ValuePos->append());
    row[m_MC_ValuePos.m_iID] = 4;
    row[m_MC_ValuePos.m_sChoice] = "Left";


    m_cbxValuePos.pack_start(m_MC_ValuePos.m_iID);
    m_cbxValuePos.pack_start(m_MC_ValuePos.m_sChoice);


    //ComboBox-UpdatePolicy
    mpLS_UpdatePolicy =Gtk::ListStore::create(m_MC_UpdatePolicy);
    m_cbxUpdatePolicy.set_model(mpLS_UpdatePolicy);


    row = *(mpLS_UpdatePolicy->append());
    row[m_MC_UpdatePolicy.m_iID] = 1;
    row[m_MC_UpdatePolicy.m_sChoice] = "Continuous";


    row = *(mpLS_UpdatePolicy->append());
    row[m_MC_UpdatePolicy.m_iID] = 2;
    row[m_MC_UpdatePolicy.m_sChoice] = "Discontinuous";


    row = *(mpLS_UpdatePolicy->append());
    row[m_MC_UpdatePolicy.m_iID] = 3;
    row[m_MC_UpdatePolicy.m_sChoice] = "Delayed";


    m_cbxUpdatePolicy.pack_start(m_MC_UpdatePolicy.m_iID);
    m_cbxUpdatePolicy.pack_start(m_MC_UpdatePolicy.m_sChoice);




    m_btnClose.set_flags(Gtk::CAN_DEFAULT);
    m_btnClose.grab_default();
    m_btnClose.signal_clicked().connect(
          sigc::mem_fun(*this,&MyWindow::OnBtnClose_Clicked));


    //Packing
    add(m_vbxMain);
    m_vbxMain.pack_start(m_hbxVert_Horiz);
    m_vbxMain.pack_start(m_chkDisplayFlag);
    m_vbxMain.pack_start(m_hbxValuePos);
    m_vbxMain.pack_start(m_hbxUpdatePolicy);
    m_vbxMain.pack_start(m_hbxDigit);
    m_vbxMain.pack_start(m_hbxPageSize);
    m_vbxMain.pack_start(m_btnClose);


    m_hbxVert_Horiz.pack_start(m_vscVert);
    m_hbxVert_Horiz.pack_start(m_vbxScale_Scroll);


        m_vbxScale_Scroll.pack_start(m_hscHoriz);
        m_vbxScale_Scroll.pack_start(m_hsScroll);


    m_hbxValuePos.pack_start(m_lblValuePos);
    m_hbxValuePos.pack_start(m_cbxValuePos);


    m_hbxUpdatePolicy.pack_start(m_lblUpdatePolicy);
    m_hbxUpdatePolicy.pack_start(m_cbxUpdatePolicy);


    m_hbxDigit.pack_start(m_lblDigit);
    m_hbxDigit.pack_start(m_hscDigit);


    m_hbxPageSize.pack_start(m_lblPageSize);
    m_hbxPageSize.pack_start(m_hscPageSize);
    show_all_children();
}


MyWindow::~MyWindow()
{


}


void MyWindow::OnBtnClose_Clicked()
{
    printf("\nI'm over.. !!");
    hide();
}








Saturday, 14 April 2012

Sunday, 16 October 2011

food 4 thought : Specialized Operating System for Programming

Basic needs of Programmers:

  • Editor is one of the most basic needs of any programmer.
  • Version Control systems.
  • Automated Build systems like make, CMake, SCons, Ant.
  • Open-Source libraries like GNU C library, Gtk.
  • Shell scripting.
  • Basic Web/File browser - Specialized for browsing forums, IRC chat.
  • A simple mp3 playback utility.

I strongly believe most of the softwares in future gonna be written in this way.

There will be a low level functionalities written in C language(What I call App-specific Kernel), and this functions will be binded into a high level programming language API(predominantly python) to define UI, and to write plugins(the actual application apparently). 

So what I'm thinking now is why write separate low-level Kernel? Write a single package that is enough for the above listed functionalities, and then use a scripting language like python, lisp, perl etc. to write the application. One such application at present is GNU Emacs and Blender3D.

Components:
 
Misc...
  • UI defintions are done in scripts.
  • Minimal hardware support like Keyboard(importantly) and mouse.
  • Support for testing frameworks.

Sunday, 31 July 2011

Best Line(Curve) Fitting - Least Square Method

          Curve fitting is very fun with our own coding that fits a best curve for a given set of points. Although it is fun, it is also an essential friend for students for plotting their readings. Most of the engineering stream students have to submit their observation with well plotted graph. But what they actually do is draw the graph and adjust the readings according to the their graph. I hope this program will help them to plot their graph more appropriately.


Theory
        The name least square denote the squares of the errors are the least possible values. What are the errors? The difference between our actual reading and the value of the chosen equation.
        Let us assume we are going to fit a straight line for the given set of readings. The equation of the line is : y = mx+c. This equation has two parameters x and y thus it has it own (x,y) values and we have our own set of (x,y) values observed from the experiment. The difference between these y (from equation) and y (from experiment) is called error.


Our Expt: Ohm's Law.

The circuit on the left is to prove the Ohm's Law V = IR.
Definition: Ohm's law states that the current through a conductor between two points is directly proportional to the potential difference across the two points, and inversely proportional to the resistance between them.


Assume that this is the set of readings we have:    


X ( Current ) Y (Voltage )
1 2.3
2 4.6
3 5.8
4 7.5
5 9.8
                                            
        This plot is not a perfect straight line. So we try to fit a straight line such that it is nearer to all of the points. What we are going to do is place a scale on the graph sheet and adjust it until it becomes nearer to all points and then we draw the line. Mathematically we fit a line y = mx+c, then we find the values of 'm' and 'c' so that it resemble the line we draw using the experimental values. For more theory google for it.
Coding:          
       We use the matrix library that was discussed in my previous post


File: lsm.h
   #include<matrix.h>
   typedef struct readings {
     float *x;
     float *y;
     int len;
   }Readings;
   typedef struct lsm_line {
     float *x;
     float *y;
     float *x2;
     float *xy;
     float X , Y , XY , X2;
     float *newy;
     float Dev;
     int len;
   }LsmLine;
   Readings* lsm_new_Readings(int n);
   LsmLine* lsm_new_LsmLine(Readings *Read);
   int lsm_del_Readings(Readings *anchor);
   int lsm_Read_farray(float *array,int len);
   int lsm_Print_farray(float *array,int len);
   int lsm_Calc_LsmLine(LsmLine* line);
   int lsm_Print_LsmLine(LsmLine* line); 
File : lsm.c
     #include "lsm.h"
     Readings* lsm_new_Readings(int len)
     {
        Readings *newRead = (Readings*)malloc(sizeof(Readings));
        newRead->x = (float*)malloc(sizeof(float)*len);
        newRead->y = (float*)malloc(sizeof(float)*len);
        newRead->len = len;
        return newRead;
     }

     LsmLine* lsm_new_LsmLine(Readings *read)
     {
        LsmLine *newLine = (LsmLine*)malloc(sizeof(LsmLine));
        int len = read->len;
        newLine->x = (float*)malloc(sizeof(float)*len);
        newLine->y = (float*)malloc(sizeof(float)*len);
        newLine->xy = (float*)malloc(sizeof(float)*len);
        newLine->x2= (float*)malloc(sizeof(float)*len);
        newLine->newy= (float*)malloc(sizeof(float)*len);
        newLine->len = len;
        newLine->X  = 0;
        newLine->Y  = 0;
        newLine->XY = 0;
        newLine->X2 = 0;
        newLine->Dev=0;
        int i;
        newLine->len = read->len;
        for(i = 0;i<newLine->len;i++){
            newLine->x[i]=read->x[i];
            newLine->y[i]=read->y[i];
            newLine->xy[i]=read->x[i]*read->y[i];
            newLine->x2[i]=read->x[i]*read->x[i];
            newLine->X +=  newLine->x[i];
            newLine->Y +=  newLine->y[i];
            newLine->XY +=  newLine->xy[i];
            newLine->X2 +=  newLine->x2[i];
        }
        return newLine;
  }
  
  int lsm_Calc_LsmLine(LsmLine *Line)
  {
     int i;
     Matrix *lhs = matrix_new_Matrix(2,2);
     Matrix *rhs = matrix_new_Matrix(2,1);
     Assuming Eqn is y=ax+b
     lhs->mat[0][0] = Line->X;
     lhs->mat[0][1] = Line->len;
     lhs->mat[1][0] = Line->X2;
     lhs->mat[1][2] = Line->X;
     rhs->mat[0][0]=Line->Y;
     rhs->mat[1][0]=Line->XY;
     MatrixEqn *Eqn = matrix_new_MatrixEqn(lhs,rhs);
     matrix_Solve_Det(Eqn);
     float a = Eqn->Soln->mat[0][0];
     float b = Eqn->Soln->mat[1][0] ;
     for(i=0;i<Line->len;i++){
       Line->newy[i] =  a*Line->x[i]+b;
       Line->Dev += (Line->y[i]-Line->newy[i])*(Line->y[i]-Line->newy[i]);
     }
 }


 int lsm_Print_LsmLine(LsmLine* line)
 {
    printf("\nS.No\tX\t\tY\t\tX2\t\tXY\t\tNewY\n");
    int i;
    for (i=0;i<line->len;i++){
       printf("\n%d",i+1);
       printf("\t%0.3f",line->x[i]);
       printf("\t\t%0.3f",line->y[i]);
       printf("\t\t%0.3f",line->x2[i]);
       printf("\t%0.3f",line->xy[i]);
       printf("\t\t%0.3f",line->newy[i]);
    }
    printf("\n\nTotal");
    printf("\t%0.3f",line->X);
    printf("\t\t%0.3f",line->Y);
    printf("\t\t%0.3f",line->X2);
    printf("\t%0.3f",line->XY);
    printf("\n\n%0.3f = %0.3fa + %db ",line->Y,line->X,line->len);
    printf("\n%0.3f = %0.3fa + %0.3fb ",line->XY,line->X2,line->X);
    printf("\n\nDeviation = %0.3f",line->Dev);
    return 0;
  }
  
  void lsm_Read_farray(float *array,int len)
  {
     int i=0;
     for(i=0;i<len;i++){
        scanf("%f",&array[i]);
     }
     return 0;
  }
  
   lsm_Print_farray(float *array,int len)
   {
      int i=0;
      for(i=0;i<len;i++){
         printf("%0.3f",array[i]);
      }
      return 0;
   }
Sample program to test.
       #include<stdio.h>
   #include"lsm.h"
   int main()
   {
       printf("\n\n\t\t\tLEAST SQUARE METHOD FOR BEST LINE");
       int n,choice;
       printf("\n\nEnter the number of readings\t:");
       scanf("%d",&n);
       Readings *read = lsm_new_Readings(n);
       printf("\nEnter the type of Variation of X:");
       printf("\n\t1.Constant Steps of X");
       printf("\n\t2.Variable Steps of X\n");
       printf("\nEnter the Choice\t:");
       scanf("%d",&choice);
       switch(choice){
         case 1:   printf("\nEnter First : Step : Last of X\t:") ;
                   float first , step , last;
                   scanf("%f %f %f",&first,&step,&last);
                   int i;
                   float value;
                   for( i=0,value=first;value<=last; value +=step,i++){
                       read->x[i] = value;
                   }
                   break;
         case 2:   printf("\nEnter X\t:\n");
                   lsm_Read_farray(read->x,n);
                   break;
         default: printf("\nWrong Option Restart the program!!!");
                   break;
      }
      printf("\nEnter Y\t:\n");
      lsm_Read_farray(read->y,n);
      LsmLine *line = lsm_new_LsmLine(read);
      lsm_Calc_LsmLine(line);
      lsm_Print_LsmLine(line);
      return 0;
}
         We can extend these project to various curves, and choose the curve which has least summation of error 'S', since all set of points will not be as above.

    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!!!