/*
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]