#ifndef __MATRIX_H
#define __MATRIX_H

#include <string.h>
#include <stdlib.h>
#include <stddef.h>

typedef double MATRIXTYPE;

struct matrix {
	size_t rows;
	size_t cols;
	MATRIXTYPE **data;
};

typedef struct matrix matrix_t;

// Allocate and Free
matrix_t * create_matrix(size_t rows, size_t cols);
void destroy_matrix(matrix_t *);

// Setting values
int zero_matrix(matrix_t *);
int identity_matrix(matrix_t *);
int scaled_identity_matrix(matrix_t *, double scale);
int neg_matrix(matrix_t *);

// Arithmetic
int add_matrix(matrix_t *src1, matrix_t *src2, matrix_t *dest);
int sub_matrix(matrix_t *src1, matrix_t *src2, matrix_t *dest);
int mul_matrix(matrix_t *src1, matrix_t *src2, matrix_t *dest);

// Scalar Arithmetic
int adds_matrix(matrix_t *src, MATRIXTYPE scalar, matrix_t *dest);
int subs_matrix(matrix_t *src, MATRIXTYPE scalar, matrix_t *dest);
int muls_matrix(matrix_t *src, MATRIXTYPE scalar, matrix_t *dest);
int divs_matrix(matrix_t *src, MATRIXTYPE scalar, matrix_t *dest);

// Square Matrix Specific
matrix_t * trans_matrix(matrix_t *);

#endif
