diff --git a/include/matrix.h b/include/matrix.h
index e13a4d29749cc3d9fc55465ef67575c0747c4a63..62d2977b8affaf55dbbd0c346734fb03d283c640 100644
--- a/include/matrix.h
+++ b/include/matrix.h
@@ -6,20 +6,20 @@
typedef zp* zp_mat;
-void matrix_zp_from_int(zp_mat x, int *int_mat, int row, int col);
+zp_mat matrix_zp_from_int(int *int_mat, int row, int col);
-void matrix_zp_rand(zp_mat x, int row, int col);
+zp_mat matrix_zp_rand(int row, int col);
-void matrix_identity(zp_mat x, int size);
+zp_mat matrix_identity(int size);
int matrix_is_identity(zp_mat x, int size);
-void matrix_transpose(zp_mat xt, zp_mat x, int row, int col);
+zp_mat matrix_transpose(zp_mat x, int row, int col);
-void matrix_merge(zp_mat xy, zp_mat x, zp_mat y, int row, int col_x, int col_y);
+zp_mat matrix_merge(zp_mat x, zp_mat y, int row, int col_x, int col_y);
-void matrix_multiply(zp_mat xy, zp_mat x, zp_mat y, int row_x, int row_y, int col_y);
+zp_mat matrix_multiply(zp_mat x, zp_mat y, int row_x, int row_y, int col_y);
-void matrix_inverse(zp_mat xi, zp_mat x, int size);
+zp_mat matrix_inverse(zp_mat x, int size);
#endif //PPANN_MATRIX_H
diff --git a/src/matrix.c b/src/matrix.c
index ecc3e54ce0515323b67170e7989dc87351d1071c..6396f21619f6dbad938d6fb8431f5ac90435fe9e 100644
--- a/src/matrix.c
+++ b/src/matrix.c
@@ -1,28 +1,37 @@
#include "matrix.h"
-void matrix_zp_from_int(zp_mat x, int *int_mat, int row, int col) {
+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;
}
-void matrix_zp_rand(zp_mat x, int row, int col) {
+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;
}
-void matrix_identity(zp_mat x, int size) {
+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) {
@@ -35,15 +44,20 @@ int matrix_is_identity(zp_mat x, int size) {
return 1;
}
-void matrix_transpose(zp_mat xt, zp_mat x, int row, int col) {
+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;
}
-void matrix_merge(zp_mat xy, zp_mat x, zp_mat y, int row, int col_x, int col_y) {
+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]);
@@ -52,9 +66,12 @@ void matrix_merge(zp_mat xy, zp_mat x, zp_mat y, int row, int col_x, int col_y)
zp_copy(xy[i * (col_x + col_y) + col_x + j], y[i * col_y + j]);
}
}
+ return xy;
}
-void matrix_multiply(zp_mat xy, zp_mat x, zp_mat y, int row_x, int row_y, int col_y) {
+zp_mat matrix_multiply(zp_mat x, zp_mat y, int row_x, int row_y, int col_y) {
+ zp_mat xy;
+ xy = (zp_mat) malloc(sizeof(zp) * row_x * col_y);
zp temp;
for (int i = 0; i < row_x; i++) {
for (int j = 0; j < col_y; j++) {
@@ -65,15 +82,14 @@ void matrix_multiply(zp_mat xy, zp_mat x, zp_mat y, int row_x, int row_y, int co
}
}
}
+ return xy;
}
-void matrix_inverse(zp_mat xi, zp_mat x, int size) {
+zp_mat matrix_inverse(zp_mat x, int size) {
// Declare the row echelon matrix and generate it.
- zp *identity, *row_echelon;
- identity = (zp *) malloc(size * size * sizeof(zp));
- row_echelon = (zp *) malloc(2 * size * size * sizeof(zp));
- matrix_identity(identity, size);
- matrix_merge(row_echelon, x, identity, size, size, size);
+ 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;
@@ -81,20 +97,20 @@ void matrix_inverse(zp_mat xi, zp_mat x, int size) {
// Bottom left half to all zeros.
for (int i = 0; i < size; i++) {
for (int j = i; j < size; j++) {
- if (i == j && fp_cmp_dig(row_echelon[i * 2 * size + j], 1) != RLC_EQ) {
+ 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 && fp_cmp_dig(row_echelon[i * 2 * size + j], 0) == RLC_EQ) break;
+ 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]);
- fp_neg(temp_neg, temp_neg);
+ zp_neg(temp_neg, temp_neg);
zp_add(row_echelon[j * 2 * size + k], row_echelon[j * 2 * size + k], temp_neg);
}
}
@@ -107,16 +123,22 @@ void matrix_inverse(zp_mat xi, zp_mat x, int size) {
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]);
- fp_neg(temp_neg, temp_neg);
+ 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;
}
diff --git a/tests/test_matrix.c b/tests/test_matrix.c
index 2f170742140feccd8db41c22cc6f7ce320dbdff1..24857d3205dc3f5312b243c4077c0bc2aada10c4 100644
--- a/tests/test_matrix.c
+++ b/tests/test_matrix.c
@@ -1,52 +1,48 @@
#include "matrix.h"
int test_zp_from_int() {
- int row = 3, col = 3;
- zp x[row * col];
- int int_vec[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- matrix_zp_from_int(x, int_vec, 3, 3);
- return fp_cmp_dig(x[2 * col + 2], 9);
+ 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 x[row * col], xt[col * row];
- matrix_zp_rand(x, row, col);
- matrix_transpose(xt, x, row, col);
+ 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 = 1000;
- zp *x;
- x = (zp *) malloc(size * size * sizeof(zp));
- matrix_identity(x, size);
+ int size = 100;
+ zp_mat x;
+ x = matrix_identity(size);
return matrix_is_identity(x, size);
}
int test_merge() {
int size = 10;
- zp xy[(size + size) * size], x[size * size], y[size * size];
- matrix_zp_rand(x, size, size);
- matrix_identity(y, size);
- matrix_merge(xy, x, y, size, size, size);
+ 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 int_x[5] = {1, 2, 3, 4, 5};
- int int_y[15] = {10, 20, 30,
+ 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 x[5], y[15];
- matrix_zp_from_int(x, int_x, 1, 5);
- matrix_zp_from_int(y, int_y, 5, 3);
-
- zp xy[3];
- matrix_multiply(xy, x, y, 1, 5, 3);
+ 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);
}
@@ -54,24 +50,20 @@ int test_multiply_vector() {
int test_inverse() {
int size = 100;
// Allocate space.
- zp *x, *xi, *r;
- x = (zp *) malloc(size * size * sizeof(zp));
- xi = (zp *) malloc(size * size * sizeof(zp));
- r = (zp *) malloc(size * size * sizeof(zp));
- matrix_zp_rand(x, size, size);
- matrix_inverse(xi, x, size);
- matrix_multiply(r, xi, x, size, size, size);
+ 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();
// Perform tests.
- if (test_zp_from_int() != RLC_EQ) return 1;
+ 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;