From b02af2384e992521940ed0de59a8cc0388c7ad6f Mon Sep 17 00:00:00 2001
From: Weiqi <weltch1997@gmail.com>
Date: Tue, 28 Feb 2023 17:56:00 -0500
Subject: [PATCH] refactor almost done

---
 include/matrix.h    |  50 ++++----
 src/matrix.c        | 281 ++++++++++++++++++++++----------------------
 tests/test_matrix.c | 145 +++++++++++------------
 3 files changed, 231 insertions(+), 245 deletions(-)

diff --git a/include/matrix.h b/include/matrix.h
index 8a6a2ec..b3c8e7a 100644
--- a/include/matrix.h
+++ b/include/matrix.h
@@ -1,25 +1,25 @@
-//#ifndef PPANN_MATRIX_H
-//#define PPANN_MATRIX_H
-//
-//#include "field.h"
-//#include "group.h"
-//
-//typedef zp* zp_mat;
-//
-//zp_mat matrix_zp_from_int(int *int_mat, int row, int col);
-//
-//zp_mat matrix_zp_rand(int row, int col);
-//
-//zp_mat matrix_identity(int size);
-//
-//int matrix_is_identity(zp_mat x, int size);
-//
-//zp_mat matrix_transpose(zp_mat x, int row, int col);
-//
-//zp_mat matrix_merge(zp_mat x, zp_mat y, int row, int col_x, int col_y);
-//
-//zp_mat matrix_multiply(zp_mat x, zp_mat y, int row_x, int row_y, int col_y);
-//
-//zp_mat matrix_inverse(zp_mat x, int size);
-//
-//#endif //PPANN_MATRIX_H
+#ifndef PPANN_MATRIX_H
+#define PPANN_MATRIX_H
+
+#include "field.h"
+#include "group.h"
+
+typedef struct zp *zp_mat;
+
+zp_mat matrix_zp_from_int(const int *int_mat, int row, int col, bn_t modular);
+
+zp_mat matrix_zp_rand(int row, int col, bn_t modular);
+
+zp_mat matrix_identity(int size, bn_t modular);
+
+int matrix_is_identity(zp_mat x, int size);
+
+zp_mat matrix_transpose(zp_mat x, int row, int col);
+
+zp_mat matrix_merge(zp_mat x, zp_mat y, int row, int col_x, int col_y);
+
+zp_mat matrix_multiply(zp_mat x, zp_mat y, int row_x, int row_y, int col_y, bn_t modular);
+
+zp_mat matrix_inverse(zp_mat x, int size, bn_t modular);
+
+#endif //PPANN_MATRIX_H
\ No newline at end of file
diff --git a/src/matrix.c b/src/matrix.c
index 78001e6..f830564 100644
--- a/src/matrix.c
+++ b/src/matrix.c
@@ -1,143 +1,138 @@
-//#include "matrix.h"
-//
-//zp_mat matrix_zp_from_int(int *int_mat, int row, int col) {
-//    zp_mat x;
-//    x = (zp_mat) malloc(sizeof(zp) * row * col);
-//    for (int i = 0; i < row; i++) {
-//        for (int j = 0; j < col; j++) {
-//            zp_from_int(x[i * col + j], int_mat[i * col + j]);
-//        }
-//    }
-//    return x;
-//}
-//
-//zp_mat matrix_zp_rand(int row, int col) {
-//    zp_mat x;
-//    x = (zp_mat) malloc(sizeof(zp) * row * col);
-//    for (int i = 0; i < row; i++) {
-//        for (int j = 0; j < col; j++) {
-//            rand_zp(x[i * col + j]);
-//        }
-//    }
-//    return x;
-//}
-//
-//zp_mat matrix_identity(int size) {
-//    zp_mat x;
-//    x = (zp_mat) malloc(sizeof(zp) * size * size);
-//    for (int i = 0; i < size; i++) {
-//        for (int j = 0; j < size; j++) {
-//            if (i == j) zp_from_int(x[i * size + j], 1);
-//            else zp_zero(x[i * size + j]);
-//        }
-//    }
-//    return x;
-//}
-//
-//int matrix_is_identity(zp_mat x, int size) {
-//    for (int i = 0; i < size; i++) {
-//        for (int j = 0; j < size; j++) {
-//            if (i == j && fp_cmp_dig(x[i * size + j], 1) != RLC_EQ) return 0;
-//            if (i != j && fp_cmp_dig(x[i * size + j], 0) != RLC_EQ) return 0;
-//        }
-//    }
-//    return 1;
-//}
-//
-//zp_mat matrix_transpose(zp_mat x, int row, int col) {
-//    zp_mat xt;
-//    xt = (zp_mat) malloc(sizeof(zp) * row * col);
-//    for (int i = 0; i < row; i++) {
-//        for (int j = 0; j < col; j++) {
-//            zp_copy(xt[j * row + i], x[i * col + j]);
-//        }
-//    }
-//    return xt;
-//}
-//
-//zp_mat matrix_merge(zp_mat x, zp_mat y, int row, int col_x, int col_y) {
-//    zp_mat xy;
-//    xy = (zp_mat) malloc(sizeof(zp) * row * (col_x + col_y));
-//    for (int i = 0; i < row; i++) {
-//        for (int j = 0; j < col_x; j++) {
-//            zp_copy(xy[i * (col_x + col_y) + j], x[i * col_x + j]);
-//        }
-//        for (int j = 0; j < col_y; j++) {
-//            zp_copy(xy[i * (col_x + col_y) + col_x + j], y[i * col_y + j]);
-//        }
-//    }
-//    return xy;
-//}
-//
-//zp_mat matrix_multiply(zp_mat x, zp_mat y, int row_x, int row_y, int col_y) {
-//    zp temp;
-//    zp_mat xy;
-//    xy = (zp_mat) malloc(sizeof(zp) * row_x * col_y);
-//
-//    for (int i = 0; i < row_x; i++) {
-//        for (int j = 0; j < col_y; j++) {
-//            zp_zero(xy[i * row_y + j]);
-//            for (int k = 0; k < row_y; k++) {
-//                zp_multiply(temp, x[i * row_y + k], y[k * col_y + j]);
-//                zp_add(xy[i * col_y + j], xy[i * col_y + j], temp);
-//            }
-//        }
-//    }
-//    return xy;
-//}
-//
-//zp_mat matrix_inverse(zp_mat x, int size) {
-//    // Declare the row echelon matrix and generate it.
-//    zp_mat identity, row_echelon;
-//    identity = matrix_identity(size);
-//    row_echelon = matrix_merge(x, identity, size, size, size);
-//
-//    // Declare temp value.
-//    zp temp_multiplier, temp_neg;
-//
-//    // Bottom left half to all zeros.
-//    for (int i = 0; i < size; i++) {
-//        for (int j = i; j < size; j++) {
-//            if (i == j && !zp_is_int(row_echelon[i * 2 * size + j], 1)) {
-//                zp_inverse(temp_multiplier, row_echelon[i * 2 * size + i]);
-//                for (int k = i; k < size * 2; k++) {
-//                    zp_multiply(row_echelon[j * 2 * size + k], row_echelon[j * 2 * size + k], temp_multiplier);
-//                }
-//            }
-//
-//            if (i == j && zp_is_int(row_echelon[i * 2 * size + j], 0)) break;
-//
-//            if (i != j) {
-//                zp_copy(temp_multiplier, row_echelon[j * 2 * size + i]);
-//                for (int k = i; k < size * 2; k++) {
-//                    zp_multiply(temp_neg, temp_multiplier, row_echelon[i * 2 * size + k]);
-//                    zp_neg(temp_neg, temp_neg);
-//                    zp_add(row_echelon[j * 2 * size + k], row_echelon[j * 2 * size + k], temp_neg);
-//                }
-//            }
-//        }
-//    }
-//
-//    // Top right half to all zeros.
-//    for (int i = size - 1; i > 0; i--) {
-//        for (int j = i - 1; j >= 0; j--) {
-//            zp_copy(temp_multiplier, row_echelon[j * 2 * size + i]);
-//            for (int k = i; k < size * 2; k++) {
-//                zp_multiply(temp_neg, temp_multiplier, row_echelon[i * 2 * size + k]);
-//                zp_neg(temp_neg, temp_neg);
-//                zp_add(row_echelon[j * 2 * size + k], row_echelon[j * 2 * size + k], temp_neg);
-//            }
-//        }
-//    }
-//
-//
-//    // Copy over the output.
-//    zp_mat xi;
-//    xi = (zp_mat) malloc(sizeof(zp) * size * size);
-//    for (int i = 0; i < size; i++) {
-//        for (int j = 0; j < size; j++) {
-//            zp_copy(xi[i * size + j], row_echelon[i * 2 * size + size + j]);
-//        }
-//    }
-//    return xi;
-//}
\ No newline at end of file
+#include "matrix.h"
+
+zp_mat matrix_zp_from_int(const int *int_mat, int row, int col, bn_st *modular) {
+    zp_mat x;
+    x = (zp_mat) malloc(sizeof(struct zp) * row * col);
+    for (int i = 0; i < row; i++) {
+        for (int j = 0; j < col; j++) {
+            x[i * col + j] = zp_from_int(int_mat[i * col + j], modular);
+        }
+    }
+    return x;
+}
+
+zp_mat matrix_zp_rand(int row, int col, bn_st *modular) {
+    zp_mat x;
+    x = (zp_mat) malloc(sizeof(struct zp) * row * col);
+    for (int i = 0; i < row; i++) {
+        for (int j = 0; j < col; j++) {
+            x[i * col + j] = rand_zp(modular);
+        }
+    }
+    return x;
+}
+
+zp_mat matrix_identity(int size, bn_st *modular) {
+    zp_mat x;
+    x = (zp_mat) malloc(sizeof(struct zp) * size * size);
+    for (int i = 0; i < size; i++) {
+        for (int j = 0; j < size; j++) {
+            if (i == j) x[i * size + j] = zp_one(modular);
+            else x[i * size + j] = zp_zero(modular);
+        }
+    }
+    return x;
+}
+
+int matrix_is_identity(zp_mat x, int size) {
+    for (int i = 0; i < size; i++) {
+        for (int j = 0; j < size; j++) {
+            if (i == j && !zp_cmp_int(x[i * size + j], 1)) return 0;
+            if (i != j && !zp_cmp_int(x[i * size + j], 0)) return 0;
+        }
+    }
+    return 1;
+}
+
+zp_mat matrix_transpose(zp_mat x, int row, int col) {
+    zp_mat xt;
+    xt = (zp_mat) malloc(sizeof(struct zp) * row * col);
+    for (int i = 0; i < row; i++) {
+        for (int j = 0; j < col; j++) {
+            xt[j * row + i] = zp_copy(x[i * col + j]);
+        }
+    }
+    return xt;
+}
+
+zp_mat matrix_merge(zp_mat x, zp_mat y, int row, int col_x, int col_y) {
+    zp_mat xy;
+    xy = (zp_mat) malloc(sizeof(struct zp) * row * (col_x + col_y));
+    for (int i = 0; i < row; i++) {
+        for (int j = 0; j < col_x; j++) {
+            xy[i * (col_x + col_y) + j] = zp_copy(x[i * col_x + j]);
+        }
+        for (int j = 0; j < col_y; j++) {
+            xy[i * (col_x + col_y) + col_x + j] = zp_copy(y[i * col_y + j]);
+        }
+    }
+    return xy;
+}
+
+zp_mat matrix_multiply(zp_mat x, zp_mat y, int row_x, int row_y, int col_y, bn_st *modular) {
+    zp_mat xy = (zp_mat) malloc(sizeof(struct zp) * row_x * col_y);
+
+    for (int i = 0; i < row_x; i++) {
+        for (int j = 0; j < col_y; j++) {
+            xy[i * row_y + j] = zp_zero(modular);
+            for (int k = 0; k < row_y; k++) {
+                xy[i * col_y + j] = zp_add(xy[i * col_y + j], zp_mul(x[i * row_y + k], y[k * col_y + j]));
+            }
+        }
+    }
+    return xy;
+}
+
+zp_mat matrix_inverse(zp_mat x, int size, bn_st *modular) {
+    // Declare the row echelon matrix and generate it.
+    zp_mat identity = matrix_identity(size, modular);
+    zp_mat row_echelon = matrix_merge(x, identity, size, size, size);
+
+    // Declare temp value.
+    struct zp temp_multiplier, temp_neg;
+
+    // Bottom left half to all zeros.
+    for (int i = 0; i < size; i++) {
+        for (int j = i; j < size; j++) {
+            if (i == j && !zp_cmp_int(row_echelon[i * 2 * size + j], 1)) {
+                temp_multiplier = zp_inv(row_echelon[i * 2 * size + i]);
+                for (int k = i; k < size * 2; k++) {
+                    row_echelon[j * 2 * size + k] = zp_mul(row_echelon[j * 2 * size + k], temp_multiplier);
+                }
+            }
+
+            if (i == j && zp_cmp_int(row_echelon[i * 2 * size + j], 0)) break;
+
+            if (i != j) {
+                temp_multiplier = zp_copy(row_echelon[j * 2 * size + i]);
+                for (int k = i; k < size * 2; k++) {
+                    temp_neg = zp_mul(temp_multiplier, row_echelon[i * 2 * size + k]);
+                    temp_neg = zp_neg(temp_neg);
+                    row_echelon[j * 2 * size + k] = zp_add(row_echelon[j * 2 * size + k], temp_neg);
+                }
+            }
+        }
+    }
+
+    // Top right half to all zeros.
+    for (int i = size - 1; i > 0; i--) {
+        for (int j = i - 1; j >= 0; j--) {
+            temp_multiplier = zp_copy(row_echelon[j * 2 * size + i]);
+            for (int k = i; k < size * 2; k++) {
+                temp_neg = zp_mul(temp_multiplier, row_echelon[i * 2 * size + k]);
+                temp_neg = zp_neg(temp_neg);
+                row_echelon[j * 2 * size + k] = zp_add(row_echelon[j * 2 * size + k], temp_neg);
+            }
+        }
+    }
+
+    // Copy over the output.
+    zp_mat xi;
+    xi = (zp_mat) malloc(sizeof(struct zp) * size * size);
+    for (int i = 0; i < size; i++) {
+        for (int j = 0; j < size; j++) {
+            xi[i * size + j] = zp_copy(row_echelon[i * 2 * size + size + j]);
+        }
+    }
+    return xi;
+}
\ No newline at end of file
diff --git a/tests/test_matrix.c b/tests/test_matrix.c
index 60c81f3..6610e35 100644
--- a/tests/test_matrix.c
+++ b/tests/test_matrix.c
@@ -1,78 +1,69 @@
-//#include "matrix.h"
-//
-//int test_zp_from_int() {
-//    zp_mat x;
-//    int int_mat[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
-//    x = matrix_zp_from_int(int_mat, 3, 3);
-//    return zp_is_int(x[8], 9);
-//}
-//
-//int test_transpose() {
-//    int row = 3, col = 3;
-//    zp_mat x, xt;
-//    x = matrix_zp_rand(row, col);
-//    xt = matrix_transpose(x, row, col);
-//    return fp_cmp(xt[col - 1], x[2 * row]);
-//}
-//
-//int test_identity() {
-//    int size = 100;
-//    zp_mat x;
-//    x = matrix_identity(size);
-//    return matrix_is_identity(x, size);
-//}
-//
-//int test_merge() {
-//    int size = 10;
-//    zp_mat xy, x, y;
-//    x = matrix_zp_rand(size, size);
-//    y = matrix_identity(size);
-//    xy = matrix_merge(x, y, size, size, size);
-//    return fp_cmp(x[2 * size + 1], xy[4 * size + 1]);
-//}
-//
-//int test_multiply_vector() {
-//    int mat_x[5] = {1, 2, 3, 4, 5};
-//    int mat_y[15] = {10, 20, 30,
-//                     10, 20, 30,
-//                     10, 20, 30,
-//                     10, 20, 30,
-//                     10, 20, 30};
-//
-//    zp_mat x, y, xy;
-//    x = matrix_zp_from_int(mat_x, 1, 5);
-//    y = matrix_zp_from_int(mat_y, 5, 3);
-//    xy = matrix_multiply(x, y, 1, 5, 3);
-//
-//    return fp_cmp_dig(xy[1], 300);
-//}
-//
-//int test_inverse() {
-//    int size = 100;
-//    // Allocate space.
-//    zp_mat x, xi, r;
-//    x = matrix_zp_rand(size, size);
-//    xi = matrix_inverse(x, size);
-//    r = matrix_multiply(xi, x, size, size, size);
-//    return matrix_is_identity(r, size);
-//}
-//
-//int main() {
-//    // Init core and setup.
-//    core_init();
-//    pc_param_set_any();
+#include "matrix.h"
 
-//// Get order.
-//bn_t N;
-//pc_get_ord(N);
-//
-//    // Perform tests.
-//    if (test_zp_from_int() != 1) return 1;
-//    if (test_transpose() != RLC_EQ) return 1;
-//    if (test_identity() != 1) return 1;
-//    if (test_merge() != RLC_EQ) return 1;
-//    if (test_multiply_vector() != RLC_EQ) return 1;
-//    if (test_inverse() != 1) return 1;
-//
-//    return 0;
-//}
\ No newline at end of file
+int test_zp_from_int(bn_st *N) {
+    int int_mat[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+    zp_mat x = matrix_zp_from_int(int_mat, 3, 3, N);
+    return zp_cmp_int(x[8], 9);
+}
+
+int test_transpose(bn_st *N) {
+    int row = 3, col = 3;
+    zp_mat x = matrix_zp_rand(row, col, N);
+    zp_mat xt = matrix_transpose(x, row, col);
+    return zp_cmp(xt[col - 1], x[2 * row]);
+}
+
+int test_identity(bn_st *N) {
+    int size = 10;
+    zp_mat x = matrix_identity(size, N);
+    return matrix_is_identity(x, size);
+}
+
+int test_merge(bn_st *N) {
+    int size = 10;
+    zp_mat x = matrix_zp_rand(size, size, N);
+    zp_mat y = matrix_identity(size, N);
+    zp_mat xy = matrix_merge(x, y, size, size, size);
+    return zp_cmp(x[2 * size + 1], xy[4 * size + 1]);
+}
+
+int test_multiply_vector(bn_st *N) {
+    int mat_x[5] = {1, 2, 3, 4, 5};
+    int mat_y[15] = {10, 20, 30,
+                     10, 20, 30,
+                     10, 20, 30,
+                     10, 20, 30,
+                     10, 20, 30};
+    zp_mat x = matrix_zp_from_int(mat_x, 1, 5, N);
+    zp_mat y = matrix_zp_from_int(mat_y, 5, 3, N);
+    zp_mat xy = matrix_multiply(x, y, 1, 5, 3, N);
+    return zp_cmp_int(xy[2], 450);
+}
+
+int test_inverse(bn_st *N) {
+    int size = 100;
+    zp_mat x = matrix_zp_rand(size, size, N);
+    zp_mat xi = matrix_inverse(x, size, N);
+    zp_mat r = matrix_multiply(x, xi, size, size, size, N);
+    return matrix_is_identity(r, size);
+}
+
+int main() {
+    // Init core and setup.
+    core_init();
+    pc_param_set_any();
+
+    // Get order.
+    bn_t N;
+    pc_get_ord(N);
+
+    // Perform tests.
+    if (test_zp_from_int(N) != 1) return 1;
+    if (test_transpose(N) != 1) return 1;
+    if (test_identity(N) != 1) return 1;
+    if (test_merge(N) != 1) return 1;
+    if (test_multiply_vector(N) != 1) return 1;
+    if (test_inverse(N) != 1) return 1;
+
+    return 0;
+}
\ No newline at end of file
-- 
GitLab