add/fix various comments to BitMatrix
Notably, the (hitherto unused) `less_than` method was not at all what it purported to be. It in fact computes the opposite.
This commit is contained in:
@@ -145,7 +145,7 @@ pub struct BitMatrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BitMatrix {
|
impl BitMatrix {
|
||||||
// Create a new `rows x columns` matrix, initially empty.
|
/// Create a new `rows x columns` matrix, initially empty.
|
||||||
pub fn new(rows: usize, columns: usize) -> BitMatrix {
|
pub fn new(rows: usize, columns: usize) -> BitMatrix {
|
||||||
// For every element, we need one bit for every other
|
// For every element, we need one bit for every other
|
||||||
// element. Round up to an even number of u64s.
|
// element. Round up to an even number of u64s.
|
||||||
@@ -163,9 +163,13 @@ impl BitMatrix {
|
|||||||
(start, start + u64s_per_row)
|
(start, start + u64s_per_row)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, source: usize, target: usize) -> bool {
|
/// Sets the cell at `(row, column)` to true. Put another way, add
|
||||||
let (start, _) = self.range(source);
|
/// `column` to the bitset for `row`.
|
||||||
let (word, mask) = word_mask(target);
|
///
|
||||||
|
/// Returns true if this changed the matrix, and false otherwies.
|
||||||
|
pub fn add(&mut self, row: usize, column: usize) -> bool {
|
||||||
|
let (start, _) = self.range(row);
|
||||||
|
let (word, mask) = word_mask(column);
|
||||||
let vector = &mut self.vector[..];
|
let vector = &mut self.vector[..];
|
||||||
let v1 = vector[start + word];
|
let v1 = vector[start + word];
|
||||||
let v2 = v1 | mask;
|
let v2 = v1 | mask;
|
||||||
@@ -173,19 +177,19 @@ impl BitMatrix {
|
|||||||
v1 != v2
|
v1 != v2
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Do the bits from `source` contain `target`?
|
/// Do the bits from `row` contain `column`? Put another way, is
|
||||||
///
|
/// the matrix cell at `(row, column)` true? Put yet another way,
|
||||||
/// Put another way, if the matrix represents (transitive)
|
/// if the matrix represents (transitive) reachability, can
|
||||||
/// reachability, can `source` reach `target`?
|
/// `row` reach `column`?
|
||||||
pub fn contains(&self, source: usize, target: usize) -> bool {
|
pub fn contains(&self, row: usize, column: usize) -> bool {
|
||||||
let (start, _) = self.range(source);
|
let (start, _) = self.range(row);
|
||||||
let (word, mask) = word_mask(target);
|
let (word, mask) = word_mask(column);
|
||||||
(self.vector[start + word] & mask) != 0
|
(self.vector[start + word] & mask) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns those indices that are reachable from both `a` and
|
/// Returns those indices that are true in rows `a` and `b`. This
|
||||||
/// `b`. This is an O(n) operation where `n` is the number of
|
/// is an O(n) operation where `n` is the number of elements
|
||||||
/// elements (somewhat independent from the actual size of the
|
/// (somewhat independent from the actual size of the
|
||||||
/// intersection, in particular).
|
/// intersection, in particular).
|
||||||
pub fn intersection(&self, a: usize, b: usize) -> Vec<usize> {
|
pub fn intersection(&self, a: usize, b: usize) -> Vec<usize> {
|
||||||
let (a_start, a_end) = self.range(a);
|
let (a_start, a_end) = self.range(a);
|
||||||
@@ -206,7 +210,7 @@ impl BitMatrix {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the bits from `read` to the bits from `write`,
|
/// Add the bits from row `read` to the bits from row `write`,
|
||||||
/// return true if anything changed.
|
/// return true if anything changed.
|
||||||
///
|
///
|
||||||
/// This is used when computing transitive reachability because if
|
/// This is used when computing transitive reachability because if
|
||||||
@@ -227,6 +231,8 @@ impl BitMatrix {
|
|||||||
changed
|
changed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterates through all the columns set to true in a given row of
|
||||||
|
/// the matrix.
|
||||||
pub fn iter<'a>(&'a self, row: usize) -> BitVectorIter<'a> {
|
pub fn iter<'a>(&'a self, row: usize) -> BitVectorIter<'a> {
|
||||||
let (start, end) = self.range(row);
|
let (start, end) = self.range(row);
|
||||||
BitVectorIter {
|
BitVectorIter {
|
||||||
|
|||||||
@@ -134,12 +134,12 @@ impl<T: Clone + Debug + Eq + Hash + Clone> TransitiveRelation<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a vector of all things less than `a`.
|
/// Returns a vector of all things greater than `a`.
|
||||||
///
|
///
|
||||||
/// Really this probably ought to be `impl Iterator<Item=&T>`, but
|
/// Really this probably ought to be `impl Iterator<Item=&T>`, but
|
||||||
/// I'm too lazy to make that work, and -- given the caching
|
/// I'm too lazy to make that work, and -- given the caching
|
||||||
/// strategy -- it'd be a touch tricky anyhow.
|
/// strategy -- it'd be a touch tricky anyhow.
|
||||||
pub fn less_than(&self, a: &T) -> Vec<&T> {
|
pub fn greater_than(&self, a: &T) -> Vec<&T> {
|
||||||
match self.index(a) {
|
match self.index(a) {
|
||||||
Some(a) => self.with_closure(|closure| {
|
Some(a) => self.with_closure(|closure| {
|
||||||
closure.iter(a.0).map(|i| &self.elements[i]).collect()
|
closure.iter(a.0).map(|i| &self.elements[i]).collect()
|
||||||
|
|||||||
Reference in New Issue
Block a user