arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/src/utils/vec.rs
src/utils/vec.rsRaw
  1use ark_ff::PrimeField;
  2pub use ark_relations::r1cs::Matrix as R1CSMatrix;
  3use ark_std::cfg_iter;
  4use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
  5
  6#[derive(Clone, Debug, Eq, PartialEq)]
  7pub struct SparseMatrix<F: PrimeField> {
  8    pub n_rows: usize,
  9    pub n_cols: usize,
 10    /// coeffs = R1CSMatrix = Vec<Vec<(F, usize)>>, which contains each row and the F is the value
 11    /// of the coefficient and the usize indicates the column position
 12    pub coeffs: R1CSMatrix<F>,
 13}
 14
 15impl<F: PrimeField> SparseMatrix<F> {
 16    pub fn to_dense(&self) -> Vec<Vec<F>> {
 17        let mut r: Vec<Vec<F>> = vec![vec![F::zero(); self.n_cols]; self.n_rows];
 18        for (row_i, row) in self.coeffs.iter().enumerate() {
 19            for &(value, col_i) in row.iter() {
 20                r[row_i][col_i] = value;
 21            }
 22        }
 23        r
 24    }
 25}
 26
 27pub fn dense_matrix_to_sparse<F: PrimeField>(m: Vec<Vec<F>>) -> SparseMatrix<F> {
 28    let mut r = SparseMatrix::<F> {
 29        n_rows: m.len(),
 30        n_cols: m[0].len(),
 31        coeffs: Vec::new(),
 32    };
 33    for m_row in m.iter() {
 34        let mut row: Vec<(F, usize)> = Vec::new();
 35        for (col_i, value) in m_row.iter().enumerate() {
 36            if !value.is_zero() {
 37                row.push((*value, col_i));
 38            }
 39        }
 40        r.coeffs.push(row);
 41    }
 42    r
 43}
 44
 45pub fn vec_add<F: PrimeField>(a: &[F], b: &[F]) -> Vec<F> {
 46    assert_eq!(a.len(), b.len());
 47    let mut r: Vec<F> = vec![F::zero(); a.len()];
 48    for i in 0..a.len() {
 49        r[i] = a[i] + b[i];
 50    }
 51    r
 52}
 53
 54pub fn vec_sub<F: PrimeField>(a: &[F], b: &[F]) -> Vec<F> {
 55    assert_eq!(a.len(), b.len());
 56    let mut r: Vec<F> = vec![F::zero(); a.len()];
 57    for i in 0..a.len() {
 58        r[i] = a[i] - b[i];
 59    }
 60    r
 61}
 62
 63pub fn vec_scalar_mul<F: PrimeField>(vec: &[F], c: &F) -> Vec<F> {
 64    let mut result = vec![F::zero(); vec.len()];
 65    for (i, a) in vec.iter().enumerate() {
 66        result[i] = *a * c;
 67    }
 68    result
 69}
 70
 71pub fn is_zero_vec<F: PrimeField>(vec: &[F]) -> bool {
 72    for e in vec {
 73        if !e.is_zero() {
 74            return false;
 75        }
 76    }
 77    true
 78}
 79
 80pub fn mat_vec_mul<F: PrimeField>(M: &Vec<Vec<F>>, z: &[F]) -> Vec<F> {
 81    assert!(!M.is_empty());
 82    assert_eq!(M[0].len(), z.len());
 83
 84    let mut r: Vec<F> = vec![F::zero(); M.len()];
 85    for (i, M_i) in M.iter().enumerate() {
 86        for (j, M_ij) in M_i.iter().enumerate() {
 87            r[i] += *M_ij * z[j];
 88        }
 89    }
 90    r
 91}
 92
 93pub fn mat_vec_mul_sparse<F: PrimeField>(matrix: &SparseMatrix<F>, vector: &[F]) -> Vec<F> {
 94    let mut res = vec![F::zero(); matrix.n_rows];
 95    for (row_i, row) in matrix.coeffs.iter().enumerate() {
 96        for &(value, col_i) in row.iter() {
 97            res[row_i] += value * vector[col_i];
 98        }
 99    }
100
101    res
102}
103
104pub fn hadamard<F: PrimeField>(a: &[F], b: &[F]) -> Vec<F> {
105    assert_eq!(a.len(), b.len());
106    cfg_iter!(a).zip(b).map(|(a, b)| *a * b).collect()
107}
108
109#[cfg(test)]
110pub mod tests {
111    use super::*;
112    use ark_pallas::Fr;
113
114    pub fn to_F_matrix<F: PrimeField>(M: Vec<Vec<usize>>) -> SparseMatrix<F> {
115        dense_matrix_to_sparse(to_F_dense_matrix(M))
116    }
117    pub fn to_F_dense_matrix<F: PrimeField>(M: Vec<Vec<usize>>) -> Vec<Vec<F>> {
118        let mut R: Vec<Vec<F>> = vec![Vec::new(); M.len()];
119        for i in 0..M.len() {
120            R[i] = vec![F::zero(); M[i].len()];
121            for j in 0..M[i].len() {
122                R[i][j] = F::from(M[i][j] as u64);
123            }
124        }
125        R
126    }
127    pub fn to_F_vec<F: PrimeField>(z: Vec<usize>) -> Vec<F> {
128        let mut r: Vec<F> = vec![F::zero(); z.len()];
129        for i in 0..z.len() {
130            r[i] = F::from(z[i] as u64);
131        }
132        r
133    }
134
135    #[test]
136    fn test_dense_sparse_conversions() {
137        let A = to_F_dense_matrix::<Fr>(vec![
138            vec![0, 1, 0, 0, 0, 0],
139            vec![0, 0, 0, 1, 0, 0],
140            vec![0, 1, 0, 0, 1, 0],
141            vec![5, 0, 0, 0, 0, 1],
142        ]);
143        let A_sparse = dense_matrix_to_sparse(A.clone());
144        assert_eq!(A_sparse.to_dense(), A);
145    }
146
147    // test mat_vec_mul & mat_vec_mul_sparse
148    #[test]
149    fn test_mat_vec_mul() {
150        let A = to_F_matrix::<Fr>(vec![
151            vec![0, 1, 0, 0, 0, 0],
152            vec![0, 0, 0, 1, 0, 0],
153            vec![0, 1, 0, 0, 1, 0],
154            vec![5, 0, 0, 0, 0, 1],
155        ])
156        .to_dense();
157        let z = to_F_vec(vec![1, 3, 35, 9, 27, 30]);
158        assert_eq!(mat_vec_mul(&A, &z), to_F_vec(vec![3, 9, 30, 35]));
159        assert_eq!(
160            mat_vec_mul_sparse(&dense_matrix_to_sparse(A), &z),
161            to_F_vec(vec![3, 9, 30, 35])
162        );
163
164        let A = to_F_matrix::<Fr>(vec![vec![2, 3, 4, 5], vec![4, 8, 12, 14], vec![9, 8, 7, 6]]);
165        let v = to_F_vec(vec![19, 55, 50, 3]);
166
167        assert_eq!(
168            mat_vec_mul(&A.to_dense(), &v),
169            to_F_vec(vec![418, 1158, 979])
170        );
171        assert_eq!(mat_vec_mul_sparse(&A, &v), to_F_vec(vec![418, 1158, 979]));
172    }
173
174    #[test]
175    fn test_hadamard_product() {
176        let a = to_F_vec::<Fr>(vec![1, 2, 3, 4, 5, 6]);
177        let b = to_F_vec(vec![7, 8, 9, 10, 11, 12]);
178        assert_eq!(hadamard(&a, &b), to_F_vec(vec![7, 16, 27, 40, 55, 72]));
179    }
180    #[test]
181    fn test_vec_add() {
182        let a: Vec<Fr> = to_F_vec::<Fr>(vec![1, 2, 3, 4, 5, 6]);
183        let b: Vec<Fr> = to_F_vec(vec![7, 8, 9, 10, 11, 12]);
184        assert_eq!(vec_add(&a, &b), to_F_vec(vec![8, 10, 12, 14, 16, 18]));
185    }
186}