Skip to content

Commit c6ada58

Browse files
rickardnorlanderRickard Norlander
andauthored
Use binary search in fenwick model (#35)
Co-authored-by: Rickard Norlander <[email protected]>
1 parent 38380db commit c6ada58

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

examples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ Encodes the entire text of "The Adventures of Sherlock Holmes". By allowing a su
2222

2323
Encodes "The Adventures of Sherlock Holmes" using an adaptive model based on [fenwick trees](https://en.wikipedia.org/wiki/Fenwick_tree).
2424

25-
## [Fenwick Tree (Context-Switcing)](./fenwick_adaptive.rs)
25+
## [Fenwick Tree (Context-Switcing)](./fenwick_context_switching.rs)
2626

2727
Encodes "The Adventures of Sherlock Holmes" using a *context switching* adaptive model based on [fenwick trees](https://en.wikipedia.org/wiki/Fenwick_tree). Achieves very high compression.

fenwick-model/src/lib.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,23 @@ impl Weights {
6262
return None;
6363
}
6464

65-
for i in 0..self.len() {
66-
if prefix_sum < self.prefix_sum(Some(i)) {
67-
return Some(i);
65+
// invariant: low <= our answer < high
66+
// we seek the lowest number i such that prefix_sum(i) > prefix_sum
67+
let mut low = 0;
68+
let mut high = self.len();
69+
debug_assert!(low < high);
70+
debug_assert!(prefix_sum < self.prefix_sum(Some(high - 1)));
71+
while low + 1 < high {
72+
let i = (low + high - 1) / 2;
73+
if self.prefix_sum(Some(i)) > prefix_sum {
74+
// i could be our answer, so set high just above it.
75+
high = i + 1;
76+
} else {
77+
// i could not be our answer, so set low just above it.
78+
low = i + 1;
6879
}
6980
}
70-
71-
unreachable!()
81+
Some(low)
7282
}
7383

7484
fn total(&self) -> u64 {

0 commit comments

Comments
 (0)