
------------------mmult.c-----------------------------
//A program to multiply matrices
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include "matrix.h"


int main(int argc, char * argv[])
{
	// Three matrices to work with
	struct matrix *m1=NULL;
	struct matrix *m2=NULL;
	struct matrix *m3=NULL;

	// Create a random 3x3 matrix
	m1=mrand(3,3);
	if (m1==NULL) {
		printf("Malloc error\n");
		return 1;
	}
	// Create a random 3x3 matrix
	m2=mrand(3,3);
	if (m2==NULL) {
		printf("Malloc error\n");
		return 1;
	}

	// Multiply the two
	m3=mmult(m1,m2);
	if (m3==NULL) {
		mfree(m1);
		mfree(m2);
		return 1;
	}

	// Print them all
	mprint(m1);
	mprint(m2);
	mprint(m3);

	// Clean up
	mfree(m1);
	mfree(m2);
	mfree(m3);

	return 0;
}


--------------------matrix.c------------------------
//  - Matrix routines
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "matrix.h"

// Create random matrix of size i by j
struct matrix *mrand(int i, int j)
{
	int a, b;			// Counters
	struct matrix *m;	// The matrix pointer
	
	// Allocate the matrix structure
	m=(struct matrix *)malloc(sizeof(struct matrix));
	if (m==NULL) {
		perror("Malloc");
		return NULL;
	}

	// Set the size
	m->r=i;
	m->c=j;

	// Alocate the rows & Handle errors
	m->d=(float **)malloc(sizeof(float *)*m->r);
	if (m->d==NULL) {
		perror("Malloc");
		free(m);
		return NULL;
	}
	// Allocate the columns & Handle errors
	for (b=0; b<j; b++) {
		m->d[b]=(float *)malloc(sizeof(float)*m->c);
		if (m->d[b]==NULL) {
			perror("Malloc");
			for (a=0;a<b;a++) {
				free(m->d[a]);
			}
			free(m->d);
			free(m);
			return NULL;
		}
	}
	// Fill the matrix
	for (a=0;a<i;a++) {
		for (b=0;b<j;b++) {
			m->d[a][b]=drand48();
		}
	}
	return m;
}

// Multiply m1 by m2 result is allocated and returned
struct matrix *mmult(struct matrix *m1, struct matrix *m2)
{
	struct matrix *m;
	int a, b, c;

	// Sanity
	if (m1==NULL) {
		printf("Null matrix!\n");
		return NULL;
	}
	if (m2==NULL) {
		printf("Null matrix!\n");
		return NULL;
	}
	// Inner dimensions must agree
	if (m1->c!=m2->r) {
		printf("Matrix inner dimensions must agree\n");
		return NULL;
	}

	// As in mrand(), allocate space for the new matrix
	m=(struct matrix *)malloc(sizeof(struct matrix));
	if (m==NULL) {
		perror("Malloc");
		return NULL;
	}

	m->r=m1->r;
	m->c=m2->c;

	m->d=(float **)malloc(sizeof(float *)*m->r);
	if (m->d==NULL) {
		perror("Malloc");
		free(m);
		return NULL;
	}
	for (b=0; b<m->r; b++) {
		m->d[b]=(float *)malloc(sizeof(float)*m->c);
		if (m->d[b]==NULL) {
			perror("Malloc");
			for (a=0;a<b;a++) {
				free(m->d[a]);
			}
			free(m->d);
			free(m);
			return NULL;
		}
	}
	// Multiply
	for (a=0;a<m1->r;a++) {
		for (b=0;b<m2->c;b++) {
			m->d[a][b]=0;
			for (c=0;c<m1->c;c++) {
				m->d[a][b]+=m1->d[a][c]*m2->d[c][b];
			}
		}
	}
	return m;
}

// Print a matrix
void mprint(struct matrix *m)
{
	int a, b;	// Counters

	// Sanity
	if (m==NULL) {
		printf("Null Matrix!\n");
		return;
	}
	// MATLAB format
	printf("[");
	for (a=0;a<m->r;a++) {
		for (b=0;b<m->c;b++) {
			printf("%.9f ",m->d[a][b]);
		}
		printf(";\n");
	}
	printf("]\n");

	return;
}

// Free a matrix
void mfree(struct matrix *m)
{
	int a;	// Counter

	// Sanity
	if (m==NULL) {
		printf("Null Matrix!\n");
		return;
	}
	// Free in reverse order
	for (a=0;a<m->r;a++) {
		free(m->d[a]);
	}
	free(m->d);
	free(m);
	m=NULL;
	return;
}



------------matrix.h-------------
/***Matrix routine protos***/
#ifndef __MATRIX_H__
#define __MATRIX_H__

// Organize the matrix data
struct matrix {
	int r;
	int c;
	float **d;
};

// Create a random matrix
struct matrix * mrand(int i, int j);
// Multiply matrices
struct matrix * mmult(struct matrix *m1, struct matrix *m2);
// Free a matrix
void mfree(struct matrix *m);
// Print a matrix
void mprint(struct matrix *m);

#endif // __MATRIX_H__

-------------------Makefile---------------------------------

TARGET=mmult
OBJS=mmult.o matrix.o
CFLAGS=-g -Wall
.PHONY: clean all

all: ${TARGET}

${TARGET}: ${OBJS}
	${CC} -o ${TARGET} ${OBJS}

clean:
	rm -f ${OBJS} ${TARGET}

matrix.o: matrix.h