Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion benches/sample_z.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use criterion::*;
use qfall_math::{
integer::{MatZ, Z},
rational::Q,
utils::sample::discrete_gauss::{DiscreteGaussianIntegerSampler, LookupTableSetting},
};

/// benchmark creating a matrix of size 100x100 sampled by a comparatively wide discrete Gaussian distribution.
Expand Down Expand Up @@ -54,10 +55,29 @@ pub fn bench_sample_z_narrow_single(c: &mut Criterion) {
});
}

/// benchmark discrete Gaussian sampling using [`DiscreteGaussianIntegerSampler::sample_z`] for a variety of widths.
pub fn bench_sample_z(c: &mut Criterion) {
let center = 0;
let gaussian_widths = [
8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
];

for s in gaussian_widths {
let mut dgis =
DiscreteGaussianIntegerSampler::init(center, s, 6.0, LookupTableSetting::Precompute)
.unwrap();

c.bench_function("DiscreteGauss RejectionSampling", |b| {
b.iter(|| dgis.sample_z())
});
}
}

criterion_group!(
benches,
bench_sample_z_wide,
bench_sample_z_narrow,
bench_sample_z_wide_single,
bench_sample_z_narrow_single
bench_sample_z_narrow_single,
bench_sample_z,
);
18 changes: 12 additions & 6 deletions src/integer/mat_poly_over_z/sample/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{
error::MathError,
integer::{MatPolyOverZ, PolyOverZ, Z},
rational::Q,
traits::{MatrixDimensions, MatrixSetEntry},
utils::index::evaluate_index,
traits::{MatrixDimensions, MatrixSetEntry, SetCoefficient},
utils::{index::evaluate_index, sample::binomial::BinomialSampler},
};
use std::fmt::Display;

Expand Down Expand Up @@ -107,14 +107,20 @@ impl MatPolyOverZ {
) -> Result<Self, MathError> {
let max_degree = evaluate_index(max_degree)?;
let offset: Z = offset.into();
let n: Z = n.into();
let p: Q = p.into();
let mut bin_sampler = BinomialSampler::init(n, p)?;
let mut matrix = MatPolyOverZ::new(num_rows, num_cols);

for row in 0..matrix.get_num_rows() {
for col in 0..matrix.get_num_columns() {
let sample = PolyOverZ::sample_binomial_with_offset(max_degree, &offset, &n, &p)?;
unsafe { matrix.set_entry_unchecked(row, col, sample) };
let mut poly_z = PolyOverZ::default();

for index in 0..=max_degree {
let mut sample = bin_sampler.sample();
sample += &offset;
unsafe { poly_z.set_coeff_unchecked(index, sample) };
}

unsafe { matrix.set_entry_unchecked(row, col, poly_z) };
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/integer/mat_z/sample/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
integer::{MatZ, Z},
rational::Q,
traits::{MatrixDimensions, MatrixSetEntry},
utils::sample::binomial::sample_binomial,
utils::sample::binomial::BinomialSampler,
};
use std::fmt::Display;

Expand Down Expand Up @@ -102,14 +102,14 @@ impl MatZ {
p: impl Into<Q>,
) -> Result<Self, MathError> {
let offset: Z = offset.into();
let n: Z = n.into();
let p: Q = p.into();
let mut bin_sampler = BinomialSampler::init(n, p)?;
let mut matrix = MatZ::new(num_rows, num_cols);

for row in 0..matrix.get_num_rows() {
for col in 0..matrix.get_num_columns() {
let sample = sample_binomial(&n, &p)?;
unsafe { matrix.set_entry_unchecked(row, col, &offset + sample) };
let mut sample = bin_sampler.sample();
sample += &offset;
unsafe { matrix.set_entry_unchecked(row, col, sample) };
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/integer/poly_over_z/sample/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
// the terms of the Mozilla Public License Version 2.0 as published by the
// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.

//! This module contains algorithms for sampling
//! according to the binomial distribution.
//! This module contains algorithms for sampling according to the binomial distribution.

use crate::{
error::MathError,
integer::{PolyOverZ, Z},
rational::Q,
traits::SetCoefficient,
utils::{index::evaluate_index, sample::binomial::sample_binomial},
utils::{index::evaluate_index, sample::binomial::BinomialSampler},
};
use std::fmt::Display;

Expand Down Expand Up @@ -99,14 +98,15 @@ impl PolyOverZ {
) -> Result<Self, MathError> {
let max_degree = evaluate_index(max_degree)?;
let offset: Z = offset.into();
let n: Z = n.into();
let p: Q = p.into();

let mut poly_z = PolyOverZ::default();

let mut bin_sampler = BinomialSampler::init(n, p)?;

for index in 0..=max_degree {
let sample = sample_binomial(&n, &p)?;
unsafe { poly_z.set_coeff_unchecked(index, &offset + sample) };
let mut sample = bin_sampler.sample();
sample += &offset;
unsafe { poly_z.set_coeff_unchecked(index, sample) };
}

Ok(poly_z)
Expand Down
8 changes: 3 additions & 5 deletions src/integer/z/sample/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! This module contains algorithms for sampling
//! according to the binomial distribution.

use crate::{error::MathError, integer::Z, rational::Q, utils::sample::binomial::sample_binomial};
use crate::{error::MathError, integer::Z, rational::Q, utils::sample::binomial::BinomialSampler};

impl Z {
/// Chooses a [`Z`] instance according to the binomial distribution
Expand Down Expand Up @@ -38,11 +38,9 @@ impl Z {
/// - Returns a [`MathError`] of type [`ConversionError`](MathError::ConversionError)
/// if `n` does not fit into an [`i64`].
pub fn sample_binomial(n: impl Into<Z>, p: impl Into<Q>) -> Result<Self, MathError> {
let n: Z = n.into();
let p: Q = p.into();
let mut bin_sampler = BinomialSampler::init(n, p)?;

let sample = sample_binomial(&n, &p)?;
Ok(Z::from(sample))
Ok(bin_sampler.sample())
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/integer_mod_q/mat_zq/sample/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
integer_mod_q::{MatZq, Modulus},
rational::Q,
traits::{MatrixDimensions, MatrixSetEntry},
utils::sample::binomial::sample_binomial,
utils::sample::binomial::BinomialSampler,
};
use std::fmt::Display;

Expand Down Expand Up @@ -109,14 +109,14 @@ impl MatZq {
p: impl Into<Q>,
) -> Result<Self, MathError> {
let offset: Z = offset.into();
let n: Z = n.into();
let p: Q = p.into();
let mut bin_sampler = BinomialSampler::init(n, p)?;
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 = sample_binomial(&n, &p)?;
unsafe { matrix.set_entry_unchecked(row, col, &offset + sample) };
let mut sample = bin_sampler.sample();
sample += &offset;
unsafe { matrix.set_entry_unchecked(row, col, sample) };
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/integer_mod_q/poly_over_zq/sample/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
integer_mod_q::{Modulus, PolyOverZq},
rational::Q,
traits::SetCoefficient,
utils::{index::evaluate_index, sample::binomial::sample_binomial},
utils::{index::evaluate_index, sample::binomial::BinomialSampler},
};
use std::fmt::Display;

Expand Down Expand Up @@ -108,14 +108,14 @@ impl PolyOverZq {
let max_degree = evaluate_index(max_degree)?;
let offset: Z = offset.into();
let modulus: Modulus = modulus.into();
let n: Z = n.into();
let p: Q = p.into();
let mut bin_sampler = BinomialSampler::init(n, p)?;

let mut poly_z = PolyOverZq::from(&modulus);

for index in 0..=max_degree {
let sample = sample_binomial(&n, &p)?;
unsafe { poly_z.set_coeff_unchecked(index, &offset + sample) };
let mut sample = bin_sampler.sample();
sample += &offset;
unsafe { poly_z.set_coeff_unchecked(index, sample) };
}

Ok(poly_z)
Expand Down
7 changes: 3 additions & 4 deletions src/integer_mod_q/z_q/sample/binomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
integer::Z,
integer_mod_q::{Modulus, Zq},
rational::Q,
utils::sample::binomial::sample_binomial,
utils::sample::binomial::BinomialSampler,
};

impl Zq {
Expand Down Expand Up @@ -53,10 +53,9 @@ impl Zq {
p: impl Into<Q>,
) -> Result<Self, MathError> {
let modulus: Modulus = modulus.into();
let n: Z = n.into();
let p: Q = p.into();
let mut bin_sampler = BinomialSampler::init(n, p)?;

let sample = sample_binomial(&n, &p)?;
let sample = bin_sampler.sample();
Ok(Zq::from((sample, modulus)))
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

//! This module includes core functionality to sample according to random distributions.

pub(crate) mod binomial;
pub mod binomial;
pub mod discrete_gauss;
pub mod uniform;
Loading
Loading