Created
April 30, 2015 12:45
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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; | |
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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