CS13002 PDS Lab, Spring 2003, Section 1/A

Solution of Assignment 6

Read the in-line documentations in the program below to understand how the program works.
#include <stdio.h>
#include <stdlib.h>

#define MAX_DIMEN 20
typedef struct {
   int rowdim;                              /* Number of rows */
   int coldim;                              /* Number of columns */
   float element[MAX_DIMEN][MAX_DIMEN];     /* The elements */
} matrix;

typedef struct {
   int dim;                                 /* Dimension of a vector */
   float element[MAX_DIMEN];                /* The elements */
} vector;

int inverse ( matrix *B , matrix A )
/* Computes the inverse of a matrix.                                     */
/* A is the matrix to invert, B is the matrix to store the inverse of A. */
/* Return 1 on successful computation of inverse, 0 otherwise.           */
{
   int i,j,k,n;
   float t;

   n = A.rowdim;
   if (n != A.coldim) {
      fprintf(stderr, "Error in inverse: square matrix expected\n");
      return(0);
   }

   /* Initialize B to the identity matrix */
   (*B).rowdim = (*B).coldim = n;
   for (i=0;i<n;i++) {
      (*B).element[i][i] = 1;
      for (j=i+1;j<n;j++) (*B).element[i][j] = (*B).element[j][i] = 0;
   }

   for (i=0;i<n;i++) {
      /* Find non-zero entry in the i-th column */
      k = i;
      while ((k<n)&&(A.element[k][i]==0)) k++;
      if (k == n) return(0);
      if (k != i) {   /* Interchange i-th and k-th rows */
         for (j=0;j<i;j++) {
            /* There is no fun in interchanging 0's in A */

            t = (*B).element[i][j];
            (*B).element[i][j] = (*B).element[k][j];
            (*B).element[k][j] = t;
         }
         for (j=i;j<n;j++) {
            t = A.element[i][j];
            A.element[i][j] = A.element[k][j];
            A.element[k][j] = t;

            t = (*B).element[i][j];
            (*B).element[i][j] = (*B).element[k][j];
            (*B).element[k][j] = t;
         }
      }

      /* Multiply the i-th row by 1/a_ii, thereby forcing a_ii := 1 */
      t = 1.0 / A.element[i][i];
      A.element[i][i] = 1;
      for (j=0; j<=i; j++) (*B).element[i][j] *= t;
      for (; j<n; j++) {
         A.element[i][j] *= t;
         (*B).element[i][j] *= t;
      }

      /* Reduce other rows */
      for (k=0; k<n; k++) if (k != i) {
         t = A.element[k][i];
         for (j=0; j<=i; j++) (*B).element[k][j] -= t * (*B).element[i][j];
         A.element[k][i] = 0;
         for (j=i+1; j<n; j++) {
            A.element[k][j] -= t * A.element[i][j];
            (*B).element[k][j] -= t * (*B).element[i][j];
         }
      }
   }

   return(1);
}

void printMatrix ( matrix A )
/* Formatted printing of matrices */
{
   int i,j;

   for (i=0;i<A.rowdim;i++) {
      for (j=0;j<A.coldim;j++) printf("%9.5f ",A.element[i][j]);
      printf("\n");
   }
}

void printVector ( vector v )
/* Formatted printing of vectors. Well, our vectors are column vectors,
   but this printing makes vectors look like row vectors. Treat them as
   column vectors, whatever they look like... */
{
   int i;

   for (i=0;i<v.dim;i++) printf("%9.5f ",v.element[i]);
   printf("\n");
}

void randMatrix ( matrix *A , int m , int n )
/* Generate a random mxn matrix with integer entries between -10 and +10 */
{
   int i,j;

   (*A).rowdim = m;
   (*A).coldim = n;
   for (i=0;i<m;i++) for (j=0;j<n;j++) (*A).element[i][j] = (rand()%21)-10;
}

void randVector ( vector *v , int m )
/* Generate a random m-dimensional vector with integer entries
   between -10 and +10 */
{
   int i;

   (*v).dim = m;
   for (i=0;i<m;i++) (*v).element[i] = (rand()%21)-10;
}

void matVecMul ( vector *v , matrix A , vector u )
/* Multiplication of an mxn matrix A with an n-dimensional column vector u.
   The result (stored in *v) is an m-dimensional column vector. */
{
   int i,j,m,n;

   m = A.rowdim;
   n = A.coldim;
   if (n != u.dim) {
      fprintf(stderr, "Error in matVecMul: Incompatible dimensions...\n");
      return;
   }
   (*v).dim = m;
   for (i=0;i<m;i++) {
      (*v).element[i] = 0;
      for (j=0;j<n;j++) (*v).element[i] += A.element[i][j] * u.element[j];
   }
}

int main ()
{
   matrix A,Ainv;
   vector b,x;
   int n = 8;

   /* Seed the random number generator for getting different random systems */
   srand((unsigned int)time(NULL));

   /* Generate random system */
   randMatrix(&A,n,n);
   printf("A :\n"); printMatrix(A);
   randVector(&b,n);
   printf("b :\n"); printVector(b);

   if (inverse(&Ainv,A)) {
      printf("Inverse of A :\n"); printMatrix(Ainv);
      matVecMul(&x,Ainv,b);
      printf("x :\n"); printVector(x);
      printf("Original b :\n"); printVector(b);
      matVecMul(&b,A,x);
      printf("Reconstructed b :\n"); printVector(b);
   } else {
      printf("Error: unable to invert matrix... giving up!\n");
   }
}

Let me point out a couple of topics in connection with the above code.


[Course home] [Home]