From 49220b09d881bef2b004b8f0c33d18154ee42482 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Tue, 26 Aug 2025 23:58:31 +0530 Subject: [PATCH 1/5] feat: initialise linear algebra lib functions --- nn/src/linalg.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 nn/src/linalg.c diff --git a/nn/src/linalg.c b/nn/src/linalg.c new file mode 100644 index 0000000..9ebe4ac --- /dev/null +++ b/nn/src/linalg.c @@ -0,0 +1,83 @@ +#include "linalg.h" + +#include +#include +#include +#include + +#include "utils.h" + +Matrix* create_matrix(int rows, int cols) { + LOG_INFO("Creating a new matrix of size %dx%d.", rows, cols); + + Matrix* matrix = (Matrix*)malloc(sizeof(Matrix)); + CHECK_MALLOC(matrix, "Failed to allocate memory for Matrix struct."); + + matrix->matrix_data = (double*)malloc(rows * cols * sizeof(double)); + CHECK_MALLOC(matrix->matrix_data, + "Failed to allocate memory for matrix data."); + + matrix->rows = rows; + matrix->cols = cols; + + LOG_INFO("Matrix created successfully at address %p.", matrix); + + return matrix; +} + +Matrix* copy_matrix(const Matrix* m) { + ASSERT(m != NULL, "Input matrix for copy is NULL."); + + LOG_INFO("Copying a %dx%d matrix.", m->rows, m->cols); + Matrix* new_matrix = create_matrix(m->rows, m->cols); + + size_t total_bytes = m->rows * m->cols * sizeof(double); + memcpy(new_matrix->matrix_data, m->matrix_data, total_bytes); + + LOG_INFO("Matrix copy complete.", ); + + return new_matrix; +} + +// Helper function for flattening +Matrix* flatten_column_wise(const Matrix* m) { + Matrix* new_matrix = create_matrix(m->rows * m->cols, 1); + + int k = 0; + for (int j = 0; j < m->cols; j++) { + for (int i = 0; i < m->rows; i++) { + new_matrix->matrix_data[k] = m->matrix_data[i * m->cols + j]; + k++; + } + } + return new_matrix; +} + +Matrix* flatten_matrix(Matrix* m, int axis) { + ASSERT(m != NULL, "Input matrix to flatten is NULL."); + ASSERT(axis == 0 || axis == 1, + "Axis must be 0 (row-wise) or 1 (column-wise)."); + + if (axis == 0) { // row wise flattening + LOG_INFO( + "Flattening matrix row-wise. No operation needed as data is already " + "contiguous."); + m->cols = m->rows * m->cols; + m->rows = 1; + return m; + } else { // axis == 1, column wise flattening, invokes helper written above + LOG_INFO("Flattening matrix column-wise. A new matrix will be created."); + return flatten_column_wise(m); + } +} + +void fill_matrix(Matrix* m, double n) { + ASSERT(m != NULL, "Input matrix for fill_matrix is NULL."); + LOG_INFO("Filling a %dx%d matrix with the value %.2f.", m->rows, m->cols, n); + + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + m->matrix_data[i * m->cols + j] = n; + } + } +} From 3655b5a43c8db48f9d34ee2f0b8eb1d8ca0710ff Mon Sep 17 00:00:00 2001 From: Shreyash Date: Wed, 27 Aug 2025 01:20:34 +0530 Subject: [PATCH 2/5] feat: update header functions and complete initial linalg io implementation --- nn/include/linalg.h | 7 ++-- nn/src/linalg.c | 83 --------------------------------------------- 2 files changed, 3 insertions(+), 87 deletions(-) delete mode 100644 nn/src/linalg.c diff --git a/nn/include/linalg.h b/nn/include/linalg.h index 1d1f6c6..5f43e96 100644 --- a/nn/include/linalg.h +++ b/nn/include/linalg.h @@ -18,16 +18,15 @@ typedef struct _Matrix { // Functions for Matrix IO //===================== -Matrix* read_matrix(char* fileName); +Matrix* read_matrix(const char* fileName); Matrix* create_matrix(int rows, int cols); Matrix* copy_matrix(const Matrix* m); Matrix* flatten_matrix(Matrix* m, int axis); void fill_matrix(Matrix* m, double n); -void randomize_matrix(Matrix* m); +void randomize_matrix(Matrix* m, double n); void free_matrix(Matrix* m); -void write_matrix(Matrix* m, char* filename); +void write_matrix(Matrix* m,const char* filename); void print_matrix(Matrix* m); -void save_matrix(Matrix* m); int matrix_argmax(Matrix* m); //============================ diff --git a/nn/src/linalg.c b/nn/src/linalg.c deleted file mode 100644 index 9ebe4ac..0000000 --- a/nn/src/linalg.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "linalg.h" - -#include -#include -#include -#include - -#include "utils.h" - -Matrix* create_matrix(int rows, int cols) { - LOG_INFO("Creating a new matrix of size %dx%d.", rows, cols); - - Matrix* matrix = (Matrix*)malloc(sizeof(Matrix)); - CHECK_MALLOC(matrix, "Failed to allocate memory for Matrix struct."); - - matrix->matrix_data = (double*)malloc(rows * cols * sizeof(double)); - CHECK_MALLOC(matrix->matrix_data, - "Failed to allocate memory for matrix data."); - - matrix->rows = rows; - matrix->cols = cols; - - LOG_INFO("Matrix created successfully at address %p.", matrix); - - return matrix; -} - -Matrix* copy_matrix(const Matrix* m) { - ASSERT(m != NULL, "Input matrix for copy is NULL."); - - LOG_INFO("Copying a %dx%d matrix.", m->rows, m->cols); - Matrix* new_matrix = create_matrix(m->rows, m->cols); - - size_t total_bytes = m->rows * m->cols * sizeof(double); - memcpy(new_matrix->matrix_data, m->matrix_data, total_bytes); - - LOG_INFO("Matrix copy complete.", ); - - return new_matrix; -} - -// Helper function for flattening -Matrix* flatten_column_wise(const Matrix* m) { - Matrix* new_matrix = create_matrix(m->rows * m->cols, 1); - - int k = 0; - for (int j = 0; j < m->cols; j++) { - for (int i = 0; i < m->rows; i++) { - new_matrix->matrix_data[k] = m->matrix_data[i * m->cols + j]; - k++; - } - } - return new_matrix; -} - -Matrix* flatten_matrix(Matrix* m, int axis) { - ASSERT(m != NULL, "Input matrix to flatten is NULL."); - ASSERT(axis == 0 || axis == 1, - "Axis must be 0 (row-wise) or 1 (column-wise)."); - - if (axis == 0) { // row wise flattening - LOG_INFO( - "Flattening matrix row-wise. No operation needed as data is already " - "contiguous."); - m->cols = m->rows * m->cols; - m->rows = 1; - return m; - } else { // axis == 1, column wise flattening, invokes helper written above - LOG_INFO("Flattening matrix column-wise. A new matrix will be created."); - return flatten_column_wise(m); - } -} - -void fill_matrix(Matrix* m, double n) { - ASSERT(m != NULL, "Input matrix for fill_matrix is NULL."); - LOG_INFO("Filling a %dx%d matrix with the value %.2f.", m->rows, m->cols, n); - - for (int i = 0; i < m->rows; i++) { - for (int j = 0; j < m->cols; j++) { - m->matrix_data[i * m->cols + j] = n; - } - } -} From 68f539108405b395311d42b7021a327da98741d4 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Wed, 27 Aug 2025 01:22:05 +0530 Subject: [PATCH 3/5] feat: add io and operations file --- nn/src/linalg/io.c | 206 +++++++++++++++++++++++++++++++++++++ nn/src/linalg/operations.c | 0 2 files changed, 206 insertions(+) create mode 100644 nn/src/linalg/io.c create mode 100644 nn/src/linalg/operations.c diff --git a/nn/src/linalg/io.c b/nn/src/linalg/io.c new file mode 100644 index 0000000..07e6c9f --- /dev/null +++ b/nn/src/linalg/io.c @@ -0,0 +1,206 @@ +#include +#include +#include +#include +#include + +#include "linalg.h" +#include "utils.h" + +Matrix* read_matrix(const char* filename) { + LOG_INFO("Attempting to load matrix from file: %s", filename); + + FILE* file = fopen(filename, "r"); + ASSERT(file != NULL, "Failed to open file for matrix loading."); + + char entry[1024]; + int rows = 0, cols = 0; + + if (fgets(entry, sizeof(entry), file) == NULL) { + LOG_ERROR("Could not read rows from file: %s", filename); + fclose(file); + return NULL; + } + rows = atoi(entry); + + if (fgets(entry, sizeof(entry), file) == NULL) { + LOG_ERROR("Could not read columns from file: %s", filename); + fclose(file); + return NULL; + } + cols = atoi(entry); + + ASSERT(rows > 0 && cols > 0, "Invalid matrix dimensions read from file."); + + Matrix* m = create_matrix(rows, cols); + + for (int i = 0; i < rows; i++) { + if (fgets(entry, sizeof(entry), file) == NULL) { + LOG_ERROR("Unexpected end of file while reading matrix data."); + free_matrix(m); + fclose(file); + return NULL; + } + + char* line_ptr = entry; + for (int j = 0; j < cols; j++) { + m->matrix_data[i * cols + j] = strtod(line_ptr, &line_ptr); + } + } + + LOG_INFO("Successfully loaded a %dx%d matrix from %s.", m->rows, m->cols, + filename); + fclose(file); + return m; +} + +Matrix* create_matrix(int rows, int cols) { + LOG_INFO("Creating a new matrix of size %dx%d.", rows, cols); + + Matrix* matrix = (Matrix*)malloc(sizeof(Matrix)); + CHECK_MALLOC(matrix, "Failed to allocate memory for Matrix struct."); + + matrix->matrix_data = (double*)malloc(rows * cols * sizeof(double)); + CHECK_MALLOC(matrix->matrix_data, + "Failed to allocate memory for matrix data."); + + matrix->rows = rows; + matrix->cols = cols; + + LOG_INFO("Matrix created successfully at address %p.", matrix); + + return matrix; +} + +Matrix* copy_matrix(const Matrix* m) { + ASSERT(m != NULL, "Input matrix for copy is NULL."); + + LOG_INFO("Copying a %dx%d matrix.", m->rows, m->cols); + Matrix* new_matrix = create_matrix(m->rows, m->cols); + + size_t total_bytes = m->rows * m->cols * sizeof(double); + memcpy(new_matrix->matrix_data, m->matrix_data, total_bytes); + + LOG_INFO("Matrix copy complete."); + + return new_matrix; +} + +// Helper function for flattening +Matrix* flatten_column_wise(const Matrix* m) { + Matrix* new_matrix = create_matrix(m->rows * m->cols, 1); + + int k = 0; + for (int j = 0; j < m->cols; j++) { + for (int i = 0; i < m->rows; i++) { + new_matrix->matrix_data[k] = m->matrix_data[i * m->cols + j]; + k++; + } + } + return new_matrix; +} + +Matrix* flatten_matrix(Matrix* m, int axis) { + ASSERT(m != NULL, "Input matrix to flatten is NULL."); + ASSERT(axis == 0 || axis == 1, + "Axis must be 0 (row-wise) or 1 (column-wise)."); + + if (axis == 0) { + LOG_INFO( + "Flattening matrix row-wise. No operation needed as data is " + "already " + "contiguous."); + m->cols = m->rows * m->cols; + m->rows = 1; + return m; + } else { + LOG_INFO( + "Flattening matrix column-wise. A new matrix will be created."); + return flatten_column_wise(m); + } +} + +void fill_matrix(Matrix* m, double n) { + ASSERT(m != NULL, "Input matrix for fill_matrix is NULL."); + LOG_INFO("Filling a %dx%d matrix with the value %.2f.", m->rows, m->cols, + n); + + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + m->matrix_data[i * m->cols + j] = n; + } + } +} + +void randomize_matrix(Matrix* m, double n) { + LOG_INFO("Randomizing a %dx%d matrix.", m->rows, m->cols); + // Apparently a 1/n or 1/n^2 scaling leads to a vanishing gradient problem + double min = -1.0 / sqrt(n); + double max = 1.0 / sqrt(n); + double range = max - min; + + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + double random_value = (double)rand() / (double)RAND_MAX; + m->matrix_data[i * m->cols + j] = min + random_value * range; + } + } + LOG_INFO("Matrix randomized successfully."); +} + +void free_matrix(Matrix* m) { + LOG_INFO("Freeing matrix at address %p.", m); + free(m->matrix_data); + free(m); + m = NULL; // prevent dangling pointer + LOG_INFO("Matrix freed successfully."); +} + +void print_matrix(Matrix* m) { + ASSERT(m != NULL, "Input matrix for print is NULL."); + LOG_INFO("Printing matrix of size %dx%d.", m->rows, m->cols); + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + printf("%.3f ", m->matrix_data[i * m->cols + j]); + } + printf("\n"); + } +} + +void write_matrix(Matrix* m, const char* filename) { + ASSERT(m != NULL, "Input matrix for save is NULL."); + LOG_INFO("Saving a %dx%d matrix to file: %s", m->rows, m->cols, filename); + + FILE* file = fopen(filename, "w"); + ASSERT(file != NULL, "Failed to open file for saving matrix."); + + fprintf(file, "%d\n", m->rows); + fprintf(file, "%d\n", m->cols); + + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + fprintf(file, "%.3f ", m->matrix_data[i * m->cols + j]); + } + fprintf(file, "\n"); + } + + fclose(file); + LOG_INFO("Matrix saved successfully."); +} + +int matrix_argmax(Matrix* m) { + ASSERT(m != NULL, "Input matrix for argmax is NULL."); + ASSERT(m->cols == 1, "Input must be a column vector (Mx1)."); + + double maxValue = INT_MIN; + int maxIndex = 0; + + for (int i = 0; i < m->rows; i++) { + if (m->matrix_data[i] > maxValue) { + maxIndex = i; + maxValue = m->matrix_data[i]; + } + } + LOG_INFO("Max value found at index %d.", maxIndex); + return maxIndex; +} diff --git a/nn/src/linalg/operations.c b/nn/src/linalg/operations.c new file mode 100644 index 0000000..e69de29 From 13f9233def68c25d515eff8fd5f2c787ae08ebf7 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Wed, 27 Aug 2025 01:27:30 +0530 Subject: [PATCH 4/5] fix: fix linting errors --- nn/include/linalg.h | 9 +- nn/src/linalg/io.c | 258 ++++++++++++++++++++++---------------------- 2 files changed, 131 insertions(+), 136 deletions(-) diff --git a/nn/include/linalg.h b/nn/include/linalg.h index 5f43e96..ef486fa 100644 --- a/nn/include/linalg.h +++ b/nn/include/linalg.h @@ -25,7 +25,7 @@ Matrix* flatten_matrix(Matrix* m, int axis); void fill_matrix(Matrix* m, double n); void randomize_matrix(Matrix* m, double n); void free_matrix(Matrix* m); -void write_matrix(Matrix* m,const char* filename); +void write_matrix(Matrix* m, const char* filename); void print_matrix(Matrix* m); int matrix_argmax(Matrix* m); @@ -36,11 +36,8 @@ Matrix* identity_matrix(int n); Matrix* add_matrix(Matrix* a, Matrix* b); Matrix* subtract_matrix(Matrix* a, Matrix* b); Matrix* multiply_matrix(Matrix* a, Matrix* b); -Matrix* apply_onto_matrix(double* (*func)(double), - Matrix* m); // Apply our own stuff onto the matrix - // items, useful for activation +Matrix* apply_onto_matrix(double* (*func)(double), Matrix* m); Matrix* add_scalar_to_matrix(Matrix* m, double n); Matrix* dot_matrix(Matrix* a, Matrix* b); Matrix* transpose_matrix(Matrix* m); -Matrix* scale_matrix(double n, - Matrix* m); // matrix can be scaled to non integer values +Matrix* scale_matrix(double n, Matrix* m); diff --git a/nn/src/linalg/io.c b/nn/src/linalg/io.c index 07e6c9f..1e00d5e 100644 --- a/nn/src/linalg/io.c +++ b/nn/src/linalg/io.c @@ -8,199 +8,197 @@ #include "utils.h" Matrix* read_matrix(const char* filename) { - LOG_INFO("Attempting to load matrix from file: %s", filename); + LOG_INFO("Attempting to load matrix from file: %s", filename); - FILE* file = fopen(filename, "r"); - ASSERT(file != NULL, "Failed to open file for matrix loading."); + FILE* file = fopen(filename, "r"); + ASSERT(file != NULL, "Failed to open file for matrix loading."); - char entry[1024]; - int rows = 0, cols = 0; + char entry[1024]; + int rows = 0, cols = 0; - if (fgets(entry, sizeof(entry), file) == NULL) { - LOG_ERROR("Could not read rows from file: %s", filename); - fclose(file); - return NULL; - } - rows = atoi(entry); + if (fgets(entry, sizeof(entry), file) == NULL) { + LOG_ERROR("Could not read rows from file: %s", filename); + fclose(file); + return NULL; + } + rows = atoi(entry); - if (fgets(entry, sizeof(entry), file) == NULL) { - LOG_ERROR("Could not read columns from file: %s", filename); - fclose(file); - return NULL; - } - cols = atoi(entry); + if (fgets(entry, sizeof(entry), file) == NULL) { + LOG_ERROR("Could not read columns from file: %s", filename); + fclose(file); + return NULL; + } + cols = atoi(entry); - ASSERT(rows > 0 && cols > 0, "Invalid matrix dimensions read from file."); + ASSERT(rows > 0 && cols > 0, "Invalid matrix dimensions read from file."); - Matrix* m = create_matrix(rows, cols); + Matrix* m = create_matrix(rows, cols); - for (int i = 0; i < rows; i++) { - if (fgets(entry, sizeof(entry), file) == NULL) { - LOG_ERROR("Unexpected end of file while reading matrix data."); - free_matrix(m); - fclose(file); - return NULL; - } + for (int i = 0; i < rows; i++) { + if (fgets(entry, sizeof(entry), file) == NULL) { + LOG_ERROR("Unexpected end of file while reading matrix data."); + free_matrix(m); + fclose(file); + return NULL; + } - char* line_ptr = entry; - for (int j = 0; j < cols; j++) { - m->matrix_data[i * cols + j] = strtod(line_ptr, &line_ptr); - } + char* line_ptr = entry; + for (int j = 0; j < cols; j++) { + m->matrix_data[i * cols + j] = strtod(line_ptr, &line_ptr); } + } - LOG_INFO("Successfully loaded a %dx%d matrix from %s.", m->rows, m->cols, - filename); - fclose(file); - return m; + LOG_INFO("Successfully loaded a %dx%d matrix from %s.", m->rows, m->cols, + filename); + fclose(file); + return m; } Matrix* create_matrix(int rows, int cols) { - LOG_INFO("Creating a new matrix of size %dx%d.", rows, cols); + LOG_INFO("Creating a new matrix of size %dx%d.", rows, cols); - Matrix* matrix = (Matrix*)malloc(sizeof(Matrix)); - CHECK_MALLOC(matrix, "Failed to allocate memory for Matrix struct."); + Matrix* matrix = (Matrix*)malloc(sizeof(Matrix)); + CHECK_MALLOC(matrix, "Failed to allocate memory for Matrix struct."); - matrix->matrix_data = (double*)malloc(rows * cols * sizeof(double)); - CHECK_MALLOC(matrix->matrix_data, - "Failed to allocate memory for matrix data."); + matrix->matrix_data = (double*)malloc(rows * cols * sizeof(double)); + CHECK_MALLOC(matrix->matrix_data, + "Failed to allocate memory for matrix data."); - matrix->rows = rows; - matrix->cols = cols; + matrix->rows = rows; + matrix->cols = cols; - LOG_INFO("Matrix created successfully at address %p.", matrix); + LOG_INFO("Matrix created successfully at address %p.", matrix); - return matrix; + return matrix; } Matrix* copy_matrix(const Matrix* m) { - ASSERT(m != NULL, "Input matrix for copy is NULL."); + ASSERT(m != NULL, "Input matrix for copy is NULL."); - LOG_INFO("Copying a %dx%d matrix.", m->rows, m->cols); - Matrix* new_matrix = create_matrix(m->rows, m->cols); + LOG_INFO("Copying a %dx%d matrix.", m->rows, m->cols); + Matrix* new_matrix = create_matrix(m->rows, m->cols); - size_t total_bytes = m->rows * m->cols * sizeof(double); - memcpy(new_matrix->matrix_data, m->matrix_data, total_bytes); + size_t total_bytes = m->rows * m->cols * sizeof(double); + memcpy(new_matrix->matrix_data, m->matrix_data, total_bytes); - LOG_INFO("Matrix copy complete."); + LOG_INFO("Matrix copy complete."); - return new_matrix; + return new_matrix; } // Helper function for flattening Matrix* flatten_column_wise(const Matrix* m) { - Matrix* new_matrix = create_matrix(m->rows * m->cols, 1); + Matrix* new_matrix = create_matrix(m->rows * m->cols, 1); - int k = 0; - for (int j = 0; j < m->cols; j++) { - for (int i = 0; i < m->rows; i++) { - new_matrix->matrix_data[k] = m->matrix_data[i * m->cols + j]; - k++; - } + int k = 0; + for (int j = 0; j < m->cols; j++) { + for (int i = 0; i < m->rows; i++) { + new_matrix->matrix_data[k] = m->matrix_data[i * m->cols + j]; + k++; } - return new_matrix; + } + return new_matrix; } Matrix* flatten_matrix(Matrix* m, int axis) { - ASSERT(m != NULL, "Input matrix to flatten is NULL."); - ASSERT(axis == 0 || axis == 1, - "Axis must be 0 (row-wise) or 1 (column-wise)."); - - if (axis == 0) { - LOG_INFO( - "Flattening matrix row-wise. No operation needed as data is " - "already " - "contiguous."); - m->cols = m->rows * m->cols; - m->rows = 1; - return m; - } else { - LOG_INFO( - "Flattening matrix column-wise. A new matrix will be created."); - return flatten_column_wise(m); - } + ASSERT(m != NULL, "Input matrix to flatten is NULL."); + ASSERT(axis == 0 || axis == 1, + "Axis must be 0 (row-wise) or 1 (column-wise)."); + + if (axis == 0) { + LOG_INFO( + "Flattening matrix row-wise. No operation needed as data is " + "already " + "contiguous."); + m->cols = m->rows * m->cols; + m->rows = 1; + return m; + } else { + LOG_INFO("Flattening matrix column-wise. A new matrix will be created."); + return flatten_column_wise(m); + } } void fill_matrix(Matrix* m, double n) { - ASSERT(m != NULL, "Input matrix for fill_matrix is NULL."); - LOG_INFO("Filling a %dx%d matrix with the value %.2f.", m->rows, m->cols, - n); + ASSERT(m != NULL, "Input matrix for fill_matrix is NULL."); + LOG_INFO("Filling a %dx%d matrix with the value %.2f.", m->rows, m->cols, n); - for (int i = 0; i < m->rows; i++) { - for (int j = 0; j < m->cols; j++) { - m->matrix_data[i * m->cols + j] = n; - } + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + m->matrix_data[i * m->cols + j] = n; } + } } void randomize_matrix(Matrix* m, double n) { - LOG_INFO("Randomizing a %dx%d matrix.", m->rows, m->cols); - // Apparently a 1/n or 1/n^2 scaling leads to a vanishing gradient problem - double min = -1.0 / sqrt(n); - double max = 1.0 / sqrt(n); - double range = max - min; + LOG_INFO("Randomizing a %dx%d matrix.", m->rows, m->cols); + // Apparently a 1/n or 1/n^2 scaling leads to a vanishing gradient problem + double min = -1.0 / sqrt(n); + double max = 1.0 / sqrt(n); + double range = max - min; - for (int i = 0; i < m->rows; i++) { - for (int j = 0; j < m->cols; j++) { - double random_value = (double)rand() / (double)RAND_MAX; - m->matrix_data[i * m->cols + j] = min + random_value * range; - } + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + double random_value = (double)rand() / (double)RAND_MAX; + m->matrix_data[i * m->cols + j] = min + random_value * range; } - LOG_INFO("Matrix randomized successfully."); + } + LOG_INFO("Matrix randomized successfully."); } void free_matrix(Matrix* m) { - LOG_INFO("Freeing matrix at address %p.", m); - free(m->matrix_data); - free(m); - m = NULL; // prevent dangling pointer - LOG_INFO("Matrix freed successfully."); + LOG_INFO("Freeing matrix at address %p.", m); + free(m->matrix_data); + free(m); + m = NULL; // prevent dangling pointer + LOG_INFO("Matrix freed successfully."); } void print_matrix(Matrix* m) { - ASSERT(m != NULL, "Input matrix for print is NULL."); - LOG_INFO("Printing matrix of size %dx%d.", m->rows, m->cols); - for (int i = 0; i < m->rows; i++) { - for (int j = 0; j < m->cols; j++) { - printf("%.3f ", m->matrix_data[i * m->cols + j]); - } - printf("\n"); + ASSERT(m != NULL, "Input matrix for print is NULL."); + LOG_INFO("Printing matrix of size %dx%d.", m->rows, m->cols); + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + printf("%.3f ", m->matrix_data[i * m->cols + j]); } + printf("\n"); + } } void write_matrix(Matrix* m, const char* filename) { - ASSERT(m != NULL, "Input matrix for save is NULL."); - LOG_INFO("Saving a %dx%d matrix to file: %s", m->rows, m->cols, filename); + ASSERT(m != NULL, "Input matrix for save is NULL."); + LOG_INFO("Saving a %dx%d matrix to file: %s", m->rows, m->cols, filename); - FILE* file = fopen(filename, "w"); - ASSERT(file != NULL, "Failed to open file for saving matrix."); + FILE* file = fopen(filename, "w"); + ASSERT(file != NULL, "Failed to open file for saving matrix."); - fprintf(file, "%d\n", m->rows); - fprintf(file, "%d\n", m->cols); + fprintf(file, "%d\n", m->rows); + fprintf(file, "%d\n", m->cols); - for (int i = 0; i < m->rows; i++) { - for (int j = 0; j < m->cols; j++) { - fprintf(file, "%.3f ", m->matrix_data[i * m->cols + j]); - } - fprintf(file, "\n"); + for (int i = 0; i < m->rows; i++) { + for (int j = 0; j < m->cols; j++) { + fprintf(file, "%.3f ", m->matrix_data[i * m->cols + j]); } + fprintf(file, "\n"); + } - fclose(file); - LOG_INFO("Matrix saved successfully."); + fclose(file); + LOG_INFO("Matrix saved successfully."); } int matrix_argmax(Matrix* m) { - ASSERT(m != NULL, "Input matrix for argmax is NULL."); - ASSERT(m->cols == 1, "Input must be a column vector (Mx1)."); + ASSERT(m != NULL, "Input matrix for argmax is NULL."); + ASSERT(m->cols == 1, "Input must be a column vector (Mx1)."); - double maxValue = INT_MIN; - int maxIndex = 0; + double maxValue = INT_MIN; + int maxIndex = 0; - for (int i = 0; i < m->rows; i++) { - if (m->matrix_data[i] > maxValue) { - maxIndex = i; - maxValue = m->matrix_data[i]; - } + for (int i = 0; i < m->rows; i++) { + if (m->matrix_data[i] > maxValue) { + maxIndex = i; + maxValue = m->matrix_data[i]; } - LOG_INFO("Max value found at index %d.", maxIndex); - return maxIndex; + } + LOG_INFO("Max value found at index %d.", maxIndex); + return maxIndex; } From 201e2fdbff4ac37945c1b2bd0cf253dd3c09d289 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Wed, 27 Aug 2025 01:38:26 +0530 Subject: [PATCH 5/5] fix: fix build errors --- nn/include/linalg.h | 2 +- nn/src/linalg/io.c | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/nn/include/linalg.h b/nn/include/linalg.h index ef486fa..078edd1 100644 --- a/nn/include/linalg.h +++ b/nn/include/linalg.h @@ -18,7 +18,7 @@ typedef struct _Matrix { // Functions for Matrix IO //===================== -Matrix* read_matrix(const char* fileName); +Matrix* read_matrix(const char* filename); Matrix* create_matrix(int rows, int cols); Matrix* copy_matrix(const Matrix* m); Matrix* flatten_matrix(Matrix* m, int axis); diff --git a/nn/src/linalg/io.c b/nn/src/linalg/io.c index 1e00d5e..258f881 100644 --- a/nn/src/linalg/io.c +++ b/nn/src/linalg/io.c @@ -148,9 +148,14 @@ void randomize_matrix(Matrix* m, double n) { void free_matrix(Matrix* m) { LOG_INFO("Freeing matrix at address %p.", m); - free(m->matrix_data); + if (m == NULL) { + LOG_WARN("Attempted to free a NULL pointer."); + return; + } + if (m->matrix_data != NULL) { + free(m->matrix_data); + } free(m); - m = NULL; // prevent dangling pointer LOG_INFO("Matrix freed successfully."); }