use crate::Matrix;
use air::EvaluationFrame;
use math::FieldElement;
use utils::collections::Vec;
pub struct TraceLde<E: FieldElement> {
main_segment_lde: Matrix<E::BaseField>,
aux_segment_ldes: Vec<Matrix<E>>,
blowup: usize,
}
impl<E: FieldElement> TraceLde<E> {
pub fn new(main_trace_lde: Matrix<E::BaseField>, blowup: usize) -> Self {
Self {
main_segment_lde: main_trace_lde,
aux_segment_ldes: Vec::new(),
blowup,
}
}
pub fn add_aux_segment(&mut self, aux_segment_lde: Matrix<E>) {
assert_eq!(
self.main_segment_lde.num_rows(),
aux_segment_lde.num_rows(),
"number of rows in auxiliary segment must be of the same as in the main segment"
);
self.aux_segment_ldes.push(aux_segment_lde);
}
pub fn main_trace_width(&self) -> usize {
self.main_segment_lde.num_cols()
}
pub fn aux_trace_width(&self) -> usize {
self.aux_segment_ldes
.iter()
.fold(0, |s, m| s + m.num_cols())
}
pub fn trace_len(&self) -> usize {
self.main_segment_lde.num_rows()
}
pub fn blowup(&self) -> usize {
self.blowup
}
pub fn read_main_trace_frame_into(
&self,
lde_step: usize,
frame: &mut EvaluationFrame<E::BaseField>,
) {
let next_lde_step = (lde_step + self.blowup()) % self.trace_len();
self.main_segment_lde
.read_row_into(lde_step, frame.current_mut());
self.main_segment_lde
.read_row_into(next_lde_step, frame.next_mut());
}
pub fn read_aux_trace_frame_into(&self, lde_step: usize, frame: &mut EvaluationFrame<E>) {
let next_lde_step = (lde_step + self.blowup()) % self.trace_len();
let mut offset = 0;
for segment in self.aux_segment_ldes.iter() {
segment.read_row_into(lde_step, &mut frame.current_mut()[offset..]);
segment.read_row_into(next_lde_step, &mut frame.next_mut()[offset..]);
offset += segment.num_cols();
}
}
pub fn get_main_segment(&self) -> &Matrix<E::BaseField> {
&self.main_segment_lde
}
pub fn get_aux_segment(&self, aux_segment_idx: usize) -> &Matrix<E> {
&self.aux_segment_ldes[aux_segment_idx]
}
}