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