1use p3_util::{log2_strict_usize, reverse_bits_len};
2
3use crate::dense::{DenseMatrix, DenseStorage, RowMajorMatrix};
4use crate::row_index_mapped::{RowIndexMap, RowIndexMappedView};
5use crate::util::reverse_matrix_index_bits;
6use crate::Matrix;
7
8pub trait BitReversableMatrix<T: Send + Sync>: Matrix<T> {
12 type BitRev: BitReversableMatrix<T>;
13 fn bit_reverse_rows(self) -> Self::BitRev;
14}
15
16#[derive(Debug)]
17pub struct BitReversalPerm {
18 log_height: usize,
19}
20
21impl BitReversalPerm {
22 pub fn new_view<T: Send + Sync, Inner: Matrix<T>>(
23 inner: Inner,
24 ) -> BitReversedMatrixView<Inner> {
25 RowIndexMappedView {
26 index_map: Self {
27 log_height: log2_strict_usize(inner.height()),
28 },
29 inner,
30 }
31 }
32}
33
34impl RowIndexMap for BitReversalPerm {
35 fn height(&self) -> usize {
36 1 << self.log_height
37 }
38 fn map_row_index(&self, r: usize) -> usize {
39 reverse_bits_len(r, self.log_height)
40 }
41 fn to_row_major_matrix<T: Clone + Send + Sync, Inner: Matrix<T>>(
44 &self,
45 inner: Inner,
46 ) -> RowMajorMatrix<T> {
47 let mut inner = inner.to_row_major_matrix();
48 reverse_matrix_index_bits(&mut inner);
49 inner
50 }
51}
52
53pub type BitReversedMatrixView<Inner> = RowIndexMappedView<BitReversalPerm, Inner>;
54
55impl<T: Clone + Send + Sync, S: DenseStorage<T>> BitReversableMatrix<T>
56 for BitReversedMatrixView<DenseMatrix<T, S>>
57{
58 type BitRev = DenseMatrix<T, S>;
59 fn bit_reverse_rows(self) -> Self::BitRev {
60 self.inner
61 }
62}
63
64impl<T: Clone + Send + Sync, S: DenseStorage<T>> BitReversableMatrix<T> for DenseMatrix<T, S> {
65 type BitRev = BitReversedMatrixView<DenseMatrix<T, S>>;
66 fn bit_reverse_rows(self) -> Self::BitRev {
67 BitReversalPerm::new_view(self)
68 }
69}