/* Library for Matrix Operations --- Fundamental */
#include "stdio.h"#include "stdlib.h"#include "string.h"#include "math.h"
#define NEAR_ZERO 0.000005#define STR_LEN 1000
typedef struct { int rows; int cols; double *elem;} mat_t;
mat_t *mat_init(mat_t *mat) { if((mat->elem = malloc(sizeof(double))) == NULL) { printf("*** MEM ALLOC ERR ***"); exit(1); } mat->rows = mat->cols = 1; return mat;}
mat_t *mat_size(mat_t *mat, int rows, int cols) { if((mat->elem = realloc(mat->elem, rows * cols * sizeof(double))) == NULL) { printf("*** MEM REALLOC ERR ***"); exit(1); } mat->rows = rows; mat->cols = cols; return mat;}
void mat_free(mat_t *mat) { free(mat->elem); return; }
int count_rows(char *csv) { char *s = csv; int ctr = 1; for(; *s != '\0'; s++) if(*s == ';') ctr++; return ctr;}
int count_cols(char *csv) { char *s = csv; int ctr = 0; for(; *s != '\0'; s++) if(*s == ',') ctr++; return (ctr / count_rows(csv) + 1);}
mat_t *mat_set(mat_t *mat, char *csv) { char str[STR_LEN]; int r = count_rows(csv), c = count_cols(csv), ctr = r * c; double *m = mat_size(mat, mat->rows = r, mat->cols = c)->elem; *m++ = atof(strcpy(str, strtok(csv, ";,"))); for(; ctr > 1; ctr--) *m++ = atof(strcpy(str, strtok('\0', ";,"))); return mat;}
int mat_rows(mat_t *mat) { return mat->rows; }int mat_cols(mat_t *mat) { return mat->cols; }
int randnum(void) { double norm = 11.0 / (RAND_MAX + 1); if((double) rand() / RAND_MAX <= 0.3) return (- floor(rand() * norm)); else return ( floor(rand() * norm));}
mat_t *mat_rand(mat_t *mat, int rows, int cols) { int ctr = rows * cols; double *m = mat_size(mat, rows, cols)->elem; for(; ctr > 0; ctr--) *m++ = randnum(); return mat;}
mat_t *mat_print(mat_t *mat) { int r = mat->rows, c = mat->cols, i = 1, j; double *m = mat->elem; for(; i <= r; i++) { for(j = 1; j <= c; j++) printf("(%d, %d): %f ", i, j, *m++); putchar('\n'); } return mat;}
double nearint(double real) { long m = floor(real), n = m; double d = fabs(real - m), e = fabs(++n - real); if(d < e) if(d < NEAR_ZERO) return m; if(e < NEAR_ZERO) return n; return real;}
mat_t *mat_attrac(mat_t *org, mat_t *mat) { int r = org->rows, c = org->cols, ctr = r * c; double *o = org->elem, *a = mat_size(mat, r, c)->elem; for(; ctr > 0; ctr--) *a++ = nearint(*o++); return mat;}
mat_t *mat_write(mat_t *mat, int row, int col, double elem) { int r = mat->rows, c = mat->cols, ctr; double *m; if((row < 1) || (r < row) || (col < 1) || (c < col)) { printf("*** OUT OF DIM ***"); exit(1); } for(m = mat->elem, ctr = c * (row - 1) + col; ctr > 1; ctr--) m++; *m = elem; return mat;}
double mat_read(mat_t *mat, int row, int col) { int r = mat->rows, c = mat->cols, ctr; double *m; if((row < 1) || (r < row) || (col < 1) || (c < col)) { printf("*** OUT OF DIM ***"); exit(1); } for(m = mat->elem, ctr = c * (row - 1) + col; ctr > 1; ctr--) m++; return *m;}