use p3_field::{Algebra, Field};
#[inline]
pub(crate) fn dit_butterfly<F: Field, A: Algebra<F>, const N: usize>(
values: &mut [A; N],
idx_1: usize,
idx_2: usize,
twiddle: F,
) {
let val_1 = values[idx_1].clone();
let val_2 = values[idx_2].clone() * twiddle;
values[idx_1] = val_1.clone() + val_2.clone();
values[idx_2] = val_1 - val_2;
}
#[inline]
pub(crate) fn dif_butterfly<F: Field, A: Algebra<F>, const N: usize>(
values: &mut [A; N],
idx_1: usize,
idx_2: usize,
twiddle: F,
) {
let val_1 = values[idx_1].clone();
let val_2 = values[idx_2].clone();
values[idx_1] = val_1.clone() + val_2.clone();
values[idx_2] = (val_1 - val_2) * twiddle;
}
#[inline]
pub(crate) fn twiddle_free_butterfly<F: Field, A: Algebra<F>, const N: usize>(
values: &mut [A; N],
idx_1: usize,
idx_2: usize,
) {
let val_1 = values[idx_1].clone();
let val_2 = values[idx_2].clone();
values[idx_1] = val_1.clone() + val_2.clone();
values[idx_2] = val_1 - val_2;
}
#[inline]
pub(crate) fn bowers_g_layer<F: Field, A: Algebra<F>, const N: usize>(
values: &mut [A; N],
log_half_block_size: usize,
twiddles: &[F],
) {
let log_block_size = log_half_block_size + 1;
let half_block_size = 1 << log_half_block_size;
let num_blocks = N >> log_block_size;
for hi in 0..half_block_size {
let lo = hi + half_block_size;
twiddle_free_butterfly(values, hi, lo);
}
for (block, &twiddle) in (1..num_blocks).zip(&twiddles[1..]) {
let block_start = block << log_block_size;
for hi in block_start..block_start + half_block_size {
let lo = hi + half_block_size;
dif_butterfly(values, hi, lo, twiddle);
}
}
}
#[inline]
pub(crate) fn bowers_g_t_layer<F: Field, A: Algebra<F>, const N: usize>(
values: &mut [A; N],
log_half_block_size: usize,
twiddles: &[F],
) {
let log_block_size = log_half_block_size + 1;
let half_block_size = 1 << log_half_block_size;
let num_blocks = N >> log_block_size;
for hi in 0..half_block_size {
let lo = hi + half_block_size;
twiddle_free_butterfly(values, hi, lo);
}
for (block, &twiddle) in (1..num_blocks).zip(&twiddles[1..]) {
let block_start = block << log_block_size;
for hi in block_start..block_start + half_block_size {
let lo = hi + half_block_size;
dit_butterfly(values, hi, lo, twiddle);
}
}
}
#[inline]
pub(crate) fn bowers_g_t_layer_integrated<F: Field, A: Algebra<F>, const N: usize>(
values: &mut [A; N],
log_half_block_size: usize,
twiddles: &[F],
) {
let log_block_size = log_half_block_size + 1;
let half_block_size = 1 << log_half_block_size;
let num_blocks = N >> log_block_size;
for (block, &twiddle) in (0..num_blocks).zip(twiddles) {
let block_start = block << log_block_size;
for hi in block_start..block_start + half_block_size {
let lo = hi + half_block_size;
dit_butterfly(values, hi, lo, twiddle);
}
}
}