@@ -636,7 +636,7 @@ impl<T: Idx> GrowableBitSet<T> {
636
636
///
637
637
/// All operations that involve a row and/or column index will panic if the
638
638
/// index exceeds the relevant bound.
639
- #[ derive( Clone , Debug ) ]
639
+ #[ derive( Clone , Debug , Eq , PartialEq , RustcDecodable , RustcEncodable ) ]
640
640
pub struct BitMatrix < R : Idx , C : Idx > {
641
641
num_rows : usize ,
642
642
num_columns : usize ,
@@ -658,6 +658,23 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
658
658
}
659
659
}
660
660
661
+ /// Creates a new matrix, with `row` used as the value for every row.
662
+ pub fn from_row_n ( row : & BitSet < C > , num_rows : usize ) -> BitMatrix < R , C > {
663
+ let num_columns = row. domain_size ( ) ;
664
+ let words_per_row = num_words ( num_columns) ;
665
+ assert_eq ! ( words_per_row, row. words( ) . len( ) ) ;
666
+ BitMatrix {
667
+ num_rows,
668
+ num_columns,
669
+ words : iter:: repeat ( row. words ( ) ) . take ( num_rows) . flatten ( ) . cloned ( ) . collect ( ) ,
670
+ marker : PhantomData ,
671
+ }
672
+ }
673
+
674
+ pub fn rows ( & self ) -> impl Iterator < Item = R > {
675
+ ( 0 ..self . num_rows ) . map ( R :: new)
676
+ }
677
+
661
678
/// The range of bits for a given row.
662
679
fn range ( & self , row : R ) -> ( usize , usize ) {
663
680
let words_per_row = num_words ( self . num_columns ) ;
@@ -737,6 +754,49 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
737
754
changed
738
755
}
739
756
757
+ /// Adds the bits from `with` to the bits from row `write`, and
758
+ /// returns `true` if anything changed.
759
+ pub fn union_row_with ( & mut self , with : & BitSet < C > , write : R ) -> bool {
760
+ assert ! ( write. index( ) < self . num_rows) ;
761
+ assert_eq ! ( with. domain_size( ) , self . num_columns) ;
762
+ let ( write_start, write_end) = self . range ( write) ;
763
+ let mut changed = false ;
764
+ for ( read_index, write_index) in ( 0 ..with. words ( ) . len ( ) ) . zip ( write_start..write_end) {
765
+ let word = self . words [ write_index] ;
766
+ let new_word = word | with. words ( ) [ read_index] ;
767
+ self . words [ write_index] = new_word;
768
+ changed |= word != new_word;
769
+ }
770
+ changed
771
+ }
772
+
773
+ /// Sets every cell in `row` to true.
774
+ pub fn insert_all_into_row ( & mut self , row : R ) {
775
+ assert ! ( row. index( ) < self . num_rows) ;
776
+ let ( start, end) = self . range ( row) ;
777
+ let words = & mut self . words [ ..] ;
778
+ for index in start..end {
779
+ words[ index] = !0 ;
780
+ }
781
+ self . clear_excess_bits ( row) ;
782
+ }
783
+
784
+ /// Clear excess bits in the final word of the row.
785
+ fn clear_excess_bits ( & mut self , row : R ) {
786
+ let num_bits_in_final_word = self . num_columns % WORD_BITS ;
787
+ if num_bits_in_final_word > 0 {
788
+ let mask = ( 1 << num_bits_in_final_word) - 1 ;
789
+ let ( _, end) = self . range ( row) ;
790
+ let final_word_idx = end - 1 ;
791
+ self . words [ final_word_idx] &= mask;
792
+ }
793
+ }
794
+
795
+ /// Gets a slice of the underlying words.
796
+ pub fn words ( & self ) -> & [ Word ] {
797
+ & self . words
798
+ }
799
+
740
800
/// Iterates through all the columns set to true in a given row of
741
801
/// the matrix.
742
802
pub fn iter < ' a > ( & ' a self , row : R ) -> BitIter < ' a , C > {
@@ -748,6 +808,12 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
748
808
marker : PhantomData ,
749
809
}
750
810
}
811
+
812
+ /// Returns the number of elements in `row`.
813
+ pub fn count ( & self , row : R ) -> usize {
814
+ let ( start, end) = self . range ( row) ;
815
+ self . words [ start..end] . iter ( ) . map ( |e| e. count_ones ( ) as usize ) . sum ( )
816
+ }
751
817
}
752
818
753
819
/// A fixed-column-size, variable-row-size 2D bit matrix with a moderately
@@ -1057,6 +1123,7 @@ fn matrix_iter() {
1057
1123
matrix. insert ( 2 , 99 ) ;
1058
1124
matrix. insert ( 4 , 0 ) ;
1059
1125
matrix. union_rows ( 3 , 5 ) ;
1126
+ matrix. insert_all_into_row ( 6 ) ;
1060
1127
1061
1128
let expected = [ 99 ] ;
1062
1129
let mut iter = expected. iter ( ) ;
@@ -1068,6 +1135,7 @@ fn matrix_iter() {
1068
1135
1069
1136
let expected = [ 22 , 75 ] ;
1070
1137
let mut iter = expected. iter ( ) ;
1138
+ assert_eq ! ( matrix. count( 3 ) , expected. len( ) ) ;
1071
1139
for i in matrix. iter ( 3 ) {
1072
1140
let j = * iter. next ( ) . unwrap ( ) ;
1073
1141
assert_eq ! ( i, j) ;
@@ -1076,6 +1144,7 @@ fn matrix_iter() {
1076
1144
1077
1145
let expected = [ 0 ] ;
1078
1146
let mut iter = expected. iter ( ) ;
1147
+ assert_eq ! ( matrix. count( 4 ) , expected. len( ) ) ;
1079
1148
for i in matrix. iter ( 4 ) {
1080
1149
let j = * iter. next ( ) . unwrap ( ) ;
1081
1150
assert_eq ! ( i, j) ;
@@ -1084,11 +1153,24 @@ fn matrix_iter() {
1084
1153
1085
1154
let expected = [ 22 , 75 ] ;
1086
1155
let mut iter = expected. iter ( ) ;
1156
+ assert_eq ! ( matrix. count( 5 ) , expected. len( ) ) ;
1087
1157
for i in matrix. iter ( 5 ) {
1088
1158
let j = * iter. next ( ) . unwrap ( ) ;
1089
1159
assert_eq ! ( i, j) ;
1090
1160
}
1091
1161
assert ! ( iter. next( ) . is_none( ) ) ;
1162
+
1163
+ assert_eq ! ( matrix. count( 6 ) , 100 ) ;
1164
+ let mut count = 0 ;
1165
+ for ( idx, i) in matrix. iter ( 6 ) . enumerate ( ) {
1166
+ assert_eq ! ( idx, i) ;
1167
+ count += 1 ;
1168
+ }
1169
+ assert_eq ! ( count, 100 ) ;
1170
+
1171
+ if let Some ( i) = matrix. iter ( 7 ) . next ( ) {
1172
+ panic ! ( "expected no elements in row, but contains element {:?}" , i) ;
1173
+ }
1092
1174
}
1093
1175
1094
1176
#[ test]
0 commit comments