algebra/module/
block_structure.rs1use std::ops::Range;
2
3use bivec::BiVec;
4use fp::vector::{FpSlice, FpSliceMut};
5
6#[derive(Debug)]
7pub struct GeneratorBasisEltPair {
8 pub generator_degree: i32,
9 pub generator_index: usize,
10 pub basis_index: usize,
11}
12
13#[derive(Debug)]
22pub struct BlockStructure {
23 basis_element_to_block_idx: Vec<GeneratorBasisEltPair>,
24 blocks: BiVec<Vec<Range<usize>>>, }
26
27impl BlockStructure {
28 pub fn new(block_sizes: &BiVec<Vec<usize>>) -> Self {
29 let mut total_dimension = 0;
30 let mut blocks = BiVec::with_capacity(block_sizes.min_degree(), block_sizes.len());
31 let mut basis_element_to_block_idx = Vec::new();
32 for (degree, block_sizes) in block_sizes.iter_enum() {
33 let mut block_starts_entry = Vec::with_capacity(block_sizes.len());
34 for (i, size) in block_sizes.iter().enumerate() {
35 block_starts_entry.push(total_dimension..total_dimension + size);
36 for j in 0..*size {
37 basis_element_to_block_idx.push(GeneratorBasisEltPair {
38 generator_degree: degree,
39 generator_index: i,
40 basis_index: j,
41 });
42 }
43 total_dimension += size;
44 }
45 blocks.push(block_starts_entry);
46 }
47 Self {
48 basis_element_to_block_idx,
49 blocks,
50 }
51 }
52
53 pub fn generator_to_block(&self, gen_deg: i32, gen_idx: usize) -> Range<usize> {
55 self.blocks[gen_deg][gen_idx].clone()
56 }
57
58 pub fn generator_basis_elt_to_index(
60 &self,
61 gen_deg: i32,
62 gen_idx: usize,
63 basis_elt: usize,
64 ) -> usize {
65 self.blocks[gen_deg][gen_idx].start + basis_elt
66 }
67
68 pub fn index_to_generator_basis_elt(&self, idx: usize) -> &GeneratorBasisEltPair {
71 &self.basis_element_to_block_idx[idx]
72 }
73
74 pub fn add_block(
76 &self,
77 mut target: FpSliceMut,
78 coeff: u32,
79 gen_deg: i32,
80 gen_idx: usize,
81 source: FpSlice,
82 ) {
83 let range = &self.blocks[gen_deg][gen_idx];
84 assert!(source.len() == range.len());
85 target.slice_mut(range.start, range.end).add(source, coeff);
86 }
87
88 pub fn total_dimension(&self) -> usize {
89 self.basis_element_to_block_idx.len()
90 }
91}