Skip to content

Instantly share code, notes, and snippets.

@NickBeeuwsaert
Created April 30, 2015 12:45
Show Gist options
  • Select an option

  • Save NickBeeuwsaert/de2ad816401f34cd78a0 to your computer and use it in GitHub Desktop.

Select an option

Save NickBeeuwsaert/de2ad816401f34cd78a0 to your computer and use it in GitHub Desktop.
Here's a crappy little library I wrote to do matrix math in C because why not
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef DEBUG
# undef DEBUG
# define DEBUG(fmt, ...) fprintf(stderr, "%s:%d:%s: " fmt "\n", __FILE__, __LINE__, __func__, __VA_ARGS__)
#else
# define DEBUG(fmt, ...)
#endif
typedef struct {
float *elements;
int rows; // Height
int cols; // Width
} Matrix;
Matrix *Matrix_new(int r, int c) {
Matrix *m = (Matrix*)malloc(sizeof(Matrix));
m->rows = r;
m->cols = c;
m->elements = (float*)malloc(sizeof(float)*r*c);
return m;
}
void Matrix_free(Matrix *m) {
free(m->elements);
free(m);
}
void Matrix_printCol(Matrix * self, int col) {
for(int i = 0; i < self->rows; i++ ){
printf("| % 3.4f |\n", self->elements[i*self->cols+col]);
}
}
void Matrix_printRow(Matrix * self, int row) {
printf("| ");
for(int i = 0; i < self->cols; i++ ){
printf("% 3.4f ", self->elements[row*self->cols+i]);
}
printf("|\n");
}
//Returns a new matrix
Matrix *Matrix_multiply(Matrix *a, Matrix *b) {
// Check if the matrices have the correct dimensions
if(a->cols != b->rows) return NULL;
Matrix *result = Matrix_new(a->rows, b->cols);
// I'm adding these together and dividing by two here because I don't like
// preferring one of these over the other
int m = (a->cols + b->rows) / 2;
// avoid type {a,b,result}->elements a thousand times
float *A = a->elements,
*B = b->elements,
*R = result->elements;
//A whopping THREE nested loops! YEAH!
for(int y = 0; y < result->rows; y++) {
for(int x = 0; x < result->cols; x++) {
result->elements[y*result->cols + x] = 0;
for(int i = 0; i < m; i++) {
R[y*result->cols + x] +=
A[y*a->cols+i] * B[i*b->cols+x];
}
}
}
return result;
}
void Matrix_print(Matrix *self) {
for(int y = 0; y < self->rows; y++) {
printf("| ");
for(int x = 0; x < self->cols; x++) {
printf("% 9.4f ", self->elements[y*self->cols+x]);
}
printf("|\n");
}
}
int main() {
float A[] = {
1, 2, 3, 4,
5, 6, 7, 8,
};
float B[] = {
1, 2,// 3, 4,
5, 6,// 7, 8,
9,10,//11,12,
13,14,//15,16
};
Matrix *a = Matrix_new(2,4);
DEBUG("Created a %dx%d matrix", a->rows, a->cols);
memcpy(a->elements, A, sizeof(float)*2*4);
Matrix *b = Matrix_new(4,2);
DEBUG("Created a %dx%d matrix", a->rows, a->cols);
memcpy(b->elements, B, sizeof(float)*4*2);
printf("Matrix A is: \n");
Matrix_print(a);
printf("Matrix B is: \n");
Matrix_print(b);
printf("\nAnd, with their powers combined, C is: \n");
Matrix *c = Matrix_multiply(a, b);
if(!c) {
printf("Oh no! Your matrices aren't in the correct dimensions(Or, something exploded)\n");
}else {
Matrix_print(c);
Matrix_free(c);
}
Matrix_free(b);
Matrix_free(a);
return 0;
};
main: main.c
gcc -o main main.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment