i was thinking about the way to make matrices in C, that ensures matrix types (Matrix2x2, Matrix3x3, …) and provides operations (Add, Substract, Multiply, Transpose). I found two methods.
First Method
I thought of implementing matrices as macros that construct arrays depending on the number of rows and columns.
I also made macros for constructing operations.
#define MATRIX_DEFINE(ROWS, COLUMNS) typedef float Matrix##ROWS##x##COLUMNS##[ROWS][COLUMNS]
MATRIX_DEFINE(2, 2);
MATRIX_DEFINE(3, 3);
MATRIX_DEFINE(4, 4);
#define MATRIX_ADD(ROWS, COLUMNS) ...
#define MATRIX_SUBSTRACT(ROWS, COLUMNS) ...
#define MATRIX_MULTIPLY(R1, C1, R2, C2) ...
#define MATRIX_TRANSPOSE(ROWS, COLUMNS) ...
I found that this method gives me more control and offers a more explicit way of operations.
I Also heard that hard-coding operations is more efficient that using dynamic memory allocation (Hence the use of macros).
Second Method
This is the dynamic approach and it goes as follows:
typedef struct {
int rows;
int cols;
double **data;
} Matrix;
Matrix createMatrix(int rows, int cols) {
Matrix matrix;
matrix.rows = rows;
matrix.cols = cols;
matrix.data = (double **)malloc(rows * sizeof(double *));
for (int i = 0; i < rows; i++) {
matrix.data[i] = (double *)malloc(cols * sizeof(double));
}
return matrix;
}
void freeMatrix(Matrix matrix) {
for (int i = 0; i < matrix.rows; i++) {
free(matrix.data[i]);
}
free(matrix.data);
}
Matrix multiplyMatrices(Matrix a, Matrix b) {
if (a.cols != b.rows) {
fprintf(stderr, "Matrix dimensions do not match for multiplicationn");
exit(EXIT_FAILURE);
}
Matrix result = createMatrix(a.rows, b.cols);
for (int i = 0; i < a.rows; i++) {
for (int j = 0; j < b.cols; j++) {
result.data[i][j] = 0;
for (int k = 0; k < a.cols; k++) {
result.data[i][j] += a.data[i][k] * b.data[k][j];
}
}
}
return result;
}
...
I don’t know which approach i should go with and i would love some advice from you.