1use crate::bitsets::Bitset;
4use crate::cover::reversible_cover::{ShallowBitset, SparseBitset};
5use crate::globals::{attribute, item_type};
6
7pub mod reversible_cover;
8pub mod similarities;
9
10pub struct Cover {
21 pub num_attributes: usize,
23 pub num_labels: usize,
25 pub num_samples: usize,
27 attributes: Vec<Bitset>,
28 labels: Vec<Bitset>,
29 cover: SparseBitset,
30 branch: Vec<usize>,
31}
32
33impl Cover {
34 pub fn new(attributes: Vec<Bitset>, labels: Vec<Bitset>, num_samples: usize) -> Self {
37 Self {
38 num_attributes: attributes.len(),
39 num_labels: labels.len(),
40 num_samples,
41 attributes,
42 labels,
43 cover: SparseBitset::new(num_samples),
44 branch: vec![],
45 }
46 }
47
48 pub fn count(&self) -> usize {
50 self.cover.count()
51 }
52
53 pub fn labels_count(&self) -> Vec<usize> {
55 self.cover.count_intersect_with_many(&self.labels)
56 }
57
58 pub fn labels_count_with_buffer(&self, buffer: &mut Vec<usize>) {
60 buffer.clear();
61 buffer.extend_from_slice(&self.cover.count_intersect_with_many(&self.labels));
62 }
63
64 pub fn branch_on(&mut self, item: usize) -> usize {
67 self.branch.push(item);
68 let attribute = attribute(item);
69 let invert = item_type(item) == 0;
70 self.cover
71 .intersect_with(&self.attributes[attribute], invert)
72 }
73
74 pub fn count_if_branch_on(&self, item: usize) -> usize {
76 let attribute = attribute(item);
77 let invert = item_type(item) == 0;
78 self.cover
79 .count_intersect_with(&self.attributes[attribute], invert)
80 }
81
82 pub fn backtrack(&mut self) {
87 assert_ne!(self.branch.len(), 0, "No backtrack when at root");
88 self.branch.pop();
89 self.cover.restore();
90 }
91
92 #[inline]
94 pub fn to_vec(&self) -> Vec<usize> {
95 self.cover.to_vec()
96 }
97
98 pub fn shallow_cover(&self) -> ShallowBitset {
100 let cover = &self.cover;
101 cover.into()
102 }
103
104 pub fn sparse(&self) -> &SparseBitset {
106 &self.cover
107 }
108
109 pub fn path(&self) -> &[usize] {
111 &self.branch
112 }
113}