From 3feecc2b0ee9b1607ffae1f6fd86b7c942db1de1 Mon Sep 17 00:00:00 2001
From: "dario.genga" <dario.genga@etu.hesge.ch>
Date: Mon, 22 Nov 2021 18:22:55 +0100
Subject: [PATCH] Add matrix allocation, initialisation and print

Also added the tests for the allocation and initiaisation.
---
 main.c   |   9 ++++++---
 makefile |  12 +++++++++---
 matrix.c |  51 +++++++++++++++++++++++++++++++++++++++++++++++++--
 matrix.h |  36 ++++++++++++++++++++++++++++++++++--
 test.c   |  25 +++++++++++++++++++++++++
 tests    | Bin 0 -> 32016 bytes
 6 files changed, 123 insertions(+), 10 deletions(-)
 create mode 100644 test.c
 create mode 100755 tests

diff --git a/main.c b/main.c
index b524a78..0a04670 100644
--- a/main.c
+++ b/main.c
@@ -1,16 +1,19 @@
 /* Author : Dario GENGA
- * Date : 13.10.2021
- * Description : Template for a standard c file
+ * Date : 16.11.2021
+ * Description : Manipulate matrix
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 // #include <math.h> 
 // #include <time.h>
+// #include <stdbool.h>
 #include "matrix.h"
 
 int main() {
-    printf("Hello world!");
+    matrix mat;
+    matrix_init(&mat, 3, 4, 0);
+    matrix_print(mat);
     
     return EXIT_SUCCESS;
 }
diff --git a/makefile b/makefile
index 30b4034..07e07fb 100644
--- a/makefile
+++ b/makefile
@@ -1,12 +1,18 @@
 LIB=-lm
 CC=gcc -Wall -Wextra -g
 
-matrix:matrix.o main.o
-	gcc $^ -fsanitize=address -o $@ $(LIB)
+run_tests: tests
+	./$<
+
+matrix: matrix.o main.o
+	$(CC) $^ -fsanitize=address -fsanitize=leak -o $@ $(LIB)
+
+tests: test.o matrix.o
+	$(CC) $^ -fsanitize=address -fsanitize=leak -o $@ $(LIB)
 
 matrix.o: matrix.c matrix.h
 	$(CC) -c $< $(LIB)
 main.o: main.c
 	$(CC) -c $< $(LIB)
 clean:
-	rm -f *.o matrix
\ No newline at end of file
+	rm -f *.o matrix tests
\ No newline at end of file
diff --git a/matrix.c b/matrix.c
index 920e761..64fe388 100644
--- a/matrix.c
+++ b/matrix.c
@@ -1,11 +1,58 @@
 /* Author : Dario GENGA
- * Date : 15.11.2021
- * Description : Manipulate an unidimensional array with dynamic memory allocation
+ * Date : 16.11.2021
+ * Description : Manipulate matrix
  */
 
 #include "matrix.h"
 #include <stdio.h>
 
+error_code matrix_alloc(matrix *mat, int32_t m, int32_t n) {
+    int32_t **data = malloc(m * sizeof(int32_t *));
+    mat->m = m;
+    mat->n = n;
+
+    if (data == NULL) {
+        return err;
+    }
+    mat->data = data;
+
+    for (int32_t i = 0; i < m; i++) {
+        int32_t *row = malloc(n * sizeof(int32_t *));
+
+        if (row == NULL) {
+            return err;
+        }
+
+        mat->data[i] = row;
+    }
+
+    return ok;
+}
+
+error_code matrix_init(matrix *mat, int32_t m, int32_t n, int32_t val) {
+    matrix_alloc(mat, m, n);
+
+    for (int32_t i = 0; i < m; i++) {
+        for (int32_t k = 0; k < n; k++) {
+            mat->data[i][k] = val;
+        }
+    }
+
+    return ok;
+}
+
+error_code matrix_print(const matrix mat) {
+    for (int i = 0; i < mat.m; i++) {
+        printf("[");
+        for (int k = 0; k < mat.n; k++) {
+            printf(" %d ", mat.data[i][k]);
+        }
+        printf("]\n");
+    }
+
+    return ok;
+}
+
 void swap(int *x, int *y)
 {
     int tmp = *x;
diff --git a/matrix.h b/matrix.h
index ee830b6..a614f66 100644
--- a/matrix.h
+++ b/matrix.h
@@ -1,11 +1,43 @@
 /* Author : Dario GENGA
- * Date : 15.11.2021
- * Description : Manipulate an unidimensional array with dynamic memory allocation
+ * Date : 16.11.2021
+ * Description : Manipulate matrix
  */
 #ifndef _MATRIX_H
 #define _MATRIX_H
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
+
+typedef struct _matrix {
+    int32_t m, n;
+    int32_t ** data;
+} matrix;
+
+typedef enum _error_code {
+    ok, err
+} error_code;
+
+error_code matrix_alloc(matrix *mat, int32_t m, int32_t n);
+
+error_code matrix_init(matrix *mat, int32_t m, int32_t n, int32_t val);
+
+error_code matrix_destroy(matrix *mat);
+
+error_code matrix_init_from_array(matrix *mat, int32_t m, int32_t n, int32_t data[], int32_t s);
+
+error_code matrix_clone(matrix *cloned, const matrix mat);
+
+error_code matrix_transpose(matrix *transposed, const matrix mat);
+
+error_code matrix_print(const matrix mat);
+
+error_code matrix_extract_submatrix(matrix *sub, const matrix mat,  int32_t m0, int32_t m1, int32_t n0, int32_t n1);
+
+bool matrix_is_equal(matrix mat1, matrix mat2);
+
+error_code matrix_get(int32_t *elem, const matrix mat, int32_t ix, int32_t iy);
+
+error_code matrix_set(matrix mat, int32_t ix, int32_t iy, int32_t elem);
 
 void swap(int *x, int *y);
 
diff --git a/test.c b/test.c
new file mode 100644
index 0000000..e34b3b4
--- /dev/null
+++ b/test.c
@@ -0,0 +1,25 @@
+/* Author : Dario GENGA
+ * Date : 16.11.2021
+ * Description : Manipulate matrix
+ */
+#include "matrix.h"
+#include <assert.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+int main() {
+    // Initialisation
+    matrix mat;
+    int32_t m = 3;
+    int32_t n = 4;
+    int32_t val = 1;
+    printf("Starting the tests...\n");
+    // Test allocation
+    assert(matrix_alloc(&mat, m, n) == ok);
+    // Test initialisation
+    assert(matrix_init(&mat, m, n, val) == ok);
+
+    printf("The tests are completed and were successful !");
+    return EXIT_SUCCESS;
+}
diff --git a/tests b/tests
new file mode 100755
index 0000000000000000000000000000000000000000..9fcfc55a0f9140259233a074e457e80538bc020f
GIT binary patch
literal 32016
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

literal 0
HcmV?d00001

-- 
GitLab