6.S096 | January IAP 2014 | Undergraduate

Effective Programming in C and C++

Assignments

Sample Solution to Assignment 1, Problem 3

« Back to Assignments

/*
PROG: matrix2

LANG: C

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>



typedef struct Matrix_s {

  size_t R, C;

  int *index;

} Matrix;



Matrix* allocate_matrix( size_t R, size_t C ) {

  Matrix *matrix = malloc( sizeof( Matrix ) );

  matrix->R = R;

  matrix->C = C;

  matrix->index = malloc( R * C * sizeof( int ) );

  return matrix;

}



void destroy_matrix( Matrix *matrix ) {

  free( matrix->index );

  free( matrix );

}



typedef enum {

  REGULAR = 0,

  TRANSPOSE = 1

} Transpose;



// Allowing reading a matrix in as either regular or transposed

Matrix* read_matrix( FILE *input, Transpose orient ) {

  size_t R, C;

  fscanf( input, "%zu %zu", &R, &C );



  Matrix *matrix = NULL;



  if( orient == REGULAR ) {

    matrix = allocate_matrix( R, C );

    for( size_t r = 0; r < matrix->R; ++r ) {

      for( size_t c = 0; c < matrix->C; ++c ) {

        fscanf( input, "%d", &matrix->index[c + r * C] );

      }

    }

  } else if( orient == TRANSPOSE ) {

    matrix = allocate_matrix( C, R );

    for( size_t r = 0; r < matrix->C; ++r ) {

      for( size_t c = 0; c < matrix->R; ++c ) {

        fscanf( input, "%d", &matrix->index[r + c * R] );

      }

    }

  } else {

    fprintf( stderr, "Error: unknown orientation %d.\n", orient );

    exit( EXIT_FAILURE );

  }



  return matrix;

}



void print_matrix( FILE *output, Matrix *matrix ) {

  fprintf( output, "%zu %zu\n", matrix->R, matrix->C );

  for( size_t r = 0; r < matrix->R; ++r ) {

    for( size_t c = 0; c < matrix->C - 1; ++c ) {

      fprintf( output, "%d ", matrix->index[c + r * matrix->C] );

    }

    fprintf( output, "%d\n", matrix->index[matrix->C - 1 + r * matrix->C] );

  }

}



Matrix* product_matrix( Matrix *a, Matrix *b ) {

  if( a->C != b->C ) {

    printf( "Error: tried to multiply (%zux%zu)x(%zux%zu)\n", a->R, a->C, b->C, b->R );

    exit( EXIT_FAILURE );

  }



  Matrix *prod = allocate_matrix( a->R, b->R );

  size_t nRows = prod->R, nCols = prod->C, nInner = a->C;



  for( size_t r = 0; r < nRows; ++r ) {

    for( size_t c = 0; c < nCols; ++c ) {

      prod->index[c + r * nCols] = 0;

      for( size_t i = 0; i < nInner; ++i ) {

        prod->index[c + r * nCols] += a->index[i + r * nInner] * b->index[i + c * nInner];

      }

    }

  }



  return prod;

}



int main(void) {

  FILE *fin = fopen( "matrix2.in", "r" );



  if( fin == NULL ) {

    printf( "Error: could not open matrix2.in\n" );

    exit( EXIT_FAILURE );

  }



  Matrix *a = read_matrix( fin, REGULAR );

  Matrix *b = read_matrix( fin, TRANSPOSE );

  fclose( fin );



  Matrix *c = product_matrix( a, b );



  FILE *output = fopen( "matrix2.out", "w" );



  if( output == NULL ) {

    printf( "Error: could not open matrix2.out\n" );

    exit( EXIT_FAILURE );

  }



  print_matrix( output, c );

  fclose( output );



  destroy_matrix( a );

  destroy_matrix( b );

  destroy_matrix( c );



  return 0;

}

Below is the output using the test data:

matrix2:
1: OK [0.006 seconds]
2: OK [0.007 seconds]
3: OK [0.007 seconds]
4: OK [0.019 seconds]
5: OK [0.017 seconds]
6: OK [0.109 seconds]
7: OK [0.178 seconds]
8: OK [0.480 seconds]
9: OK [0.791 seconds]
10: OK [1.236 seconds]
11: OK [2.088 seconds]

« Back to Assignments

Course Info

Instructor
As Taught In
January IAP 2014
Learning Resource Types
Problem Sets with Solutions
Lecture Notes
Programming Assignments with Examples