use p3_dft::{NaiveDft, TwoAdicSubgroupDft};
use p3_field::{ExtensionField, TwoAdicField};
use p3_matrix::Matrix;
use p3_matrix::dense::RowMajorMatrix;
use rand::SeedableRng;
use rand::distr::{Distribution, StandardUniform};
use rand::rngs::SmallRng;
pub fn test_dft_matches_naive<F, Dft>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<F>::rand(&mut rng, h, 3);
let dft_naive = NaiveDft.dft_batch(mat.clone());
let dft_result = dft.dft_batch(mat);
assert_eq!(dft_naive, dft_result.to_row_major_matrix());
}
}
pub fn test_coset_dft_matches_naive<F, Dft>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<F>::rand(&mut rng, h, 3);
let shift = F::GENERATOR;
let coset_dft_naive = NaiveDft.coset_dft_batch(mat.clone(), shift);
let coset_dft_result = dft.coset_dft_batch(mat, shift);
assert_eq!(coset_dft_naive, coset_dft_result.to_row_major_matrix());
}
}
pub fn test_idft_matches_naive<F, Dft>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<F>::rand(&mut rng, h, 3);
let idft_naive = NaiveDft.idft_batch(mat.clone());
let idft_result = dft.idft_batch(mat.clone());
assert_eq!(idft_naive, idft_result.to_row_major_matrix());
}
}
pub fn test_coset_idft_matches_naive<F, Dft>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<F>::rand(&mut rng, h, 3);
let shift = F::GENERATOR;
let idft_naive = NaiveDft.coset_idft_batch(mat.clone(), shift);
let idft_result = dft.coset_idft_batch(mat, shift);
assert_eq!(idft_naive, idft_result.to_row_major_matrix());
}
}
pub fn test_lde_matches_naive<F, Dft>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<F>::rand(&mut rng, h, 3);
let lde_naive = NaiveDft.lde_batch(mat.clone(), 1);
let lde_result = dft.lde_batch(mat, 1);
assert_eq!(lde_naive, lde_result.to_row_major_matrix());
}
}
pub fn test_coset_lde_matches_naive<F, Dft>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<F>::rand(&mut rng, h, 3);
let shift = F::GENERATOR;
let coset_lde_naive = NaiveDft.coset_lde_batch(mat.clone(), 1, shift);
let coset_lde_result = dft.coset_lde_batch(mat, 1, shift);
assert_eq!(coset_lde_naive, coset_lde_result.to_row_major_matrix());
}
}
pub fn test_dft_idft_consistency<F, Dft>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let original = RowMajorMatrix::<F>::rand(&mut rng, h, 3);
let dft_output = dft.dft_batch(original.clone());
let idft_output = dft.idft_batch(dft_output.to_row_major_matrix());
assert_eq!(original, idft_output.to_row_major_matrix());
}
}
pub fn test_dft_algebra_matches_naive<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let dft_naive = NaiveDft.dft_batch(mat.clone());
let dft_result = dft.dft_algebra_batch(mat);
assert_eq!(dft_naive, dft_result.to_row_major_matrix());
}
}
pub fn test_coset_dft_algebra_matches_naive<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let shift = F::GENERATOR;
let coset_dft_naive = NaiveDft.coset_dft_batch(mat.clone(), EF::from(shift));
let coset_dft_result = dft.coset_dft_algebra_batch(mat, shift);
assert_eq!(coset_dft_naive, coset_dft_result.to_row_major_matrix());
}
}
pub fn test_idft_algebra_matches_naive<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let idft_naive = NaiveDft.idft_batch(mat.clone());
let idft_result = dft.idft_algebra_batch(mat.clone());
assert_eq!(idft_naive, idft_result.to_row_major_matrix());
}
}
pub fn test_coset_idft_algebra_matches_naive<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let shift = F::GENERATOR;
let idft_naive = NaiveDft.coset_idft_batch(mat.clone(), EF::from(shift));
let idft_result = dft.coset_idft_algebra_batch(mat, shift);
assert_eq!(idft_naive, idft_result.to_row_major_matrix());
}
}
pub fn test_lde_algebra_matches_naive<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let lde_naive = NaiveDft.lde_batch(mat.clone(), 1);
let lde_result = dft.lde_algebra_batch(mat, 1);
assert_eq!(lde_naive, lde_result.to_row_major_matrix());
}
}
pub fn test_coset_lde_algebra_matches_naive<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let mat = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let shift = F::GENERATOR;
let coset_lde_naive = NaiveDft.coset_lde_batch(mat.clone(), 1, EF::from(shift));
let coset_lde_result = dft.coset_lde_algebra_batch(mat, 1, shift);
assert_eq!(coset_lde_naive, coset_lde_result.to_row_major_matrix());
}
}
pub fn test_dft_idft_algebra_consistency<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in 0..5 {
let h = 1 << log_h;
let original = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let dft_output = dft.dft_algebra_batch(original.clone());
let idft_output = dft.idft_algebra_batch(dft_output.to_row_major_matrix());
assert_eq!(original, idft_output.to_row_major_matrix());
}
}
pub fn test_dft_idft_algebra_consistency_large<F, EF, Dft>()
where
F: TwoAdicField,
EF: ExtensionField<F> + TwoAdicField,
StandardUniform: Distribution<EF>,
Dft: TwoAdicSubgroupDft<F>,
{
let dft = Dft::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in &[14, 15, 16, 17] {
let h = 1 << log_h;
let original = RowMajorMatrix::<EF>::rand(&mut rng, h, 3);
let dft_output = dft.dft_algebra_batch(original.clone());
let idft_output = dft.idft_algebra_batch(dft_output.to_row_major_matrix());
assert_eq!(
original,
idft_output.to_row_major_matrix(),
"Error Found in size: {h}"
);
}
}
pub fn test_large_coset_ldes_agree<F, Dft1, Dft2>()
where
F: TwoAdicField,
StandardUniform: Distribution<F>,
Dft1: TwoAdicSubgroupDft<F>,
Dft2: TwoAdicSubgroupDft<F>,
{
let dft1 = Dft1::default();
let dft2 = Dft2::default();
let mut rng = SmallRng::seed_from_u64(1);
for log_h in &[14, 15, 16, 17] {
let h = 1 << log_h;
let mat = RowMajorMatrix::<F>::rand(&mut rng, h, 16);
let shift = F::GENERATOR;
let coset_lde_result1 = dft1.coset_lde_batch(mat.clone(), 1, shift);
let coset_lde_result2 = dft2.coset_lde_batch(mat, 1, shift);
assert_eq!(
coset_lde_result1.to_row_major_matrix(),
coset_lde_result2.to_row_major_matrix()
);
}
}
#[macro_export]
macro_rules! test_field_dft {
($mod:ident, $field:ty, $extfield:ty, $dft:ty) => {
mod $mod {
#[test]
fn dft_matches_naive() {
$crate::test_dft_matches_naive::<$field, $dft>();
}
#[test]
fn coset_dft_matches_naive() {
$crate::test_coset_dft_matches_naive::<$field, $dft>();
}
#[test]
fn idft_matches_naive() {
$crate::test_idft_matches_naive::<$field, $dft>();
}
#[test]
fn coset_idft_matches_naive() {
$crate::test_coset_idft_matches_naive::<$field, $dft>();
}
#[test]
fn lde_matches_naive() {
$crate::test_lde_matches_naive::<$field, $dft>();
}
#[test]
fn coset_lde_matches_naive() {
$crate::test_coset_lde_matches_naive::<$field, $dft>();
}
#[test]
fn dft_idft_consistency() {
$crate::test_dft_idft_consistency::<$field, $dft>();
}
#[test]
fn dft_algebra_matches_naive() {
$crate::test_dft_algebra_matches_naive::<$field, $extfield, $dft>();
}
#[test]
fn coset_dft_algebra_matches_naive() {
$crate::test_coset_dft_algebra_matches_naive::<$field, $extfield, $dft>();
}
#[test]
fn idft_algebra_matches_naive() {
$crate::test_idft_algebra_matches_naive::<$field, $extfield, $dft>();
}
#[test]
fn coset_idft_algebra_matches_naive() {
$crate::test_coset_idft_algebra_matches_naive::<$field, $extfield, $dft>();
}
#[test]
fn lde_algebra_matches_naive() {
$crate::test_lde_algebra_matches_naive::<$field, $extfield, $dft>();
}
#[test]
fn coset_lde_algebra_matches_naive() {
$crate::test_coset_lde_algebra_matches_naive::<$field, $extfield, $dft>();
}
#[test]
fn dft_idft_algebra_consistency() {
$crate::test_dft_idft_algebra_consistency::<$field, $extfield, $dft>();
}
}
};
}
#[macro_export]
macro_rules! test_field_dft_large {
($mod:ident, $field:ty, $extfield:ty, $dft:ty) => {
mod $mod {
#[test]
fn test_dft_idft_algebra_consistency_large() {
$crate::test_dft_idft_algebra_consistency_large::<$field, $extfield, $dft>();
}
}
};
}
#[macro_export]
macro_rules! test_field_dft_consistency {
($mod:ident, $field:ty, $extfield:ty, $dft1:ty, $dft2:ty) => {
mod $mod {
#[test]
fn test_large_coset_ldes_agree() {
$crate::test_large_coset_ldes_agree::<$field, $dft1, $dft2>();
}
}
};
}