use crate::{
integer::Z,
integer_mod_q::MatZq,
traits::{MatrixDimensions, MatrixSetEntry},
utils::sample::uniform::UniformIntegerSampler,
};
use std::fmt::Display;
impl MatZq {
pub fn sample_uniform(
num_rows: impl TryInto<i64> + Display,
num_cols: impl TryInto<i64> + Display,
modulus: impl Into<Z>,
) -> Self {
let modulus: Z = modulus.into();
let mut uis = UniformIntegerSampler::init(&modulus).unwrap();
let mut matrix = MatZq::new(num_rows, num_cols, modulus);
for row in 0..matrix.get_num_rows() {
for col in 0..matrix.get_num_columns() {
let sample = uis.sample();
unsafe { matrix.set_entry_unchecked(row, col, sample) };
}
}
matrix
}
}
#[cfg(test)]
mod test_sample_uniform {
use crate::traits::{MatrixDimensions, MatrixGetEntry};
use crate::{
integer::Z,
integer_mod_q::{MatZq, Modulus},
};
#[test]
fn boundaries_kept_small() {
for _ in 0..32 {
let matrix = MatZq::sample_uniform(1, 1, 17);
let sample: Z = matrix.get_entry(0, 0).unwrap();
assert!(Z::ZERO <= sample);
assert!(sample < 17);
}
}
#[test]
fn boundaries_kept_large() {
let modulus = Z::from(u64::MAX);
for _ in 0..256 {
let matrix = MatZq::sample_uniform(1, 1, &modulus);
let sample: Z = matrix.get_entry(0, 0).unwrap();
assert!(Z::ZERO <= sample);
assert!(sample < modulus);
}
}
#[should_panic]
#[test]
fn false_size() {
let modulus = Z::from(15);
let _ = MatZq::sample_uniform(0, 3, &modulus);
}
#[should_panic]
#[test]
fn invalid_modulus() {
let _ = MatZq::sample_uniform(4, 1, 1);
}
#[test]
fn availability() {
let modulus = Modulus::from(7);
let z = Z::from(7);
let _ = MatZq::sample_uniform(1, 1, 7u8);
let _ = MatZq::sample_uniform(1, 1, 7u16);
let _ = MatZq::sample_uniform(1, 1, 7u32);
let _ = MatZq::sample_uniform(1, 1, 7u64);
let _ = MatZq::sample_uniform(1, 1, 7i8);
let _ = MatZq::sample_uniform(1, 1, 7i16);
let _ = MatZq::sample_uniform(1, 1, 7i32);
let _ = MatZq::sample_uniform(1, 1, 7i64);
let _ = MatZq::sample_uniform(1, 1, &modulus);
let _ = MatZq::sample_uniform(1, 1, &z);
}
#[test]
fn matrix_size() {
let modulus = Z::from(15);
let mat_0 = MatZq::sample_uniform(3, 3, &modulus);
let mat_1 = MatZq::sample_uniform(4, 1, &modulus);
let mat_2 = MatZq::sample_uniform(1, 5, &modulus);
let mat_3 = MatZq::sample_uniform(15, 20, &modulus);
assert_eq!(3, mat_0.get_num_rows());
assert_eq!(3, mat_0.get_num_columns());
assert_eq!(4, mat_1.get_num_rows());
assert_eq!(1, mat_1.get_num_columns());
assert_eq!(1, mat_2.get_num_rows());
assert_eq!(5, mat_2.get_num_columns());
assert_eq!(15, mat_3.get_num_rows());
assert_eq!(20, mat_3.get_num_columns());
}
}