use crate::ring::*;
use crate::mempool::*;
use super::karatsuba::*;
pub trait ConvMulComputation: RingBase {
fn karatsuba_threshold(&self) -> usize;
fn add_assign_conv_mul<M: MemoryProvider<Self::Element>>(&self, dst: &mut [Self::Element], lhs: &[Self::Element], rhs: &[Self::Element], memory_provider: &M);
}
impl<R: RingBase + ?Sized> ConvMulComputation for R {
default fn karatsuba_threshold(&self) -> usize {
0
}
fn add_assign_conv_mul<M: MemoryProvider<Self::Element>>(&self, dst: &mut [Self::Element], lhs: &[Self::Element], rhs: &[Self::Element], memory_provider: &M) {
karatsuba(self.karatsuba_threshold(), dst, lhs, rhs, RingRef::new(self), memory_provider);
}
}
#[cfg(test)]
use test;
#[cfg(test)]
use crate::primitive_int::*;
#[cfg(test)]
use crate::default_memory_provider;
#[bench]
fn bench_naive_mul_1024_bit(bencher: &mut test::Bencher) {
let a: Vec<i32> = (0..32).collect();
let b: Vec<i32> = (0..32).collect();
let mut c: Vec<i32> = (0..64).collect();
bencher.iter(|| {
c.clear();
c.resize(64, 0);
karatsuba(10, &mut c[..], &a[..], &b[..], StaticRing::<i32>::RING, &default_memory_provider!());
assert_eq!(c[31], 31 * 31 * 32 / 2 - 31 * (31 + 1) * (31 * 2 + 1) / 6);
assert_eq!(c[62], 31 * 31);
});
}
#[bench]
fn bench_karatsuba_mul_1024_bit(bencher: &mut test::Bencher) {
let a: Vec<i32> = (0..32).collect();
let b: Vec<i32> = (0..32).collect();
let mut c: Vec<i32> = (0..64).collect();
bencher.iter(|| {
c.clear();
c.resize(64, 0);
karatsuba(4, &mut c[..], &a[..], &b[..], StaticRing::<i32>::RING, &default_memory_provider!());
assert_eq!(c[31], 31 * 31 * 32 / 2 - 31 * (31 + 1) * (31 * 2 + 1) / 6);
assert_eq!(c[62], 31 * 31);
});
}