File Coverage

blib/lib/Statistics/SparseVector.pm
Criterion Covered Total %
statement 93 104 89.4
branch 14 16 87.5
condition 4 6 66.6
subroutine 19 22 86.3
pod 16 18 88.8
total 146 166 87.9


line stmt bran cond sub pod time code
1             package Statistics::SparseVector;
2              
3             ##---------------------------------------------------------------------------##
4             ## Author:
5             ## Hugo WL ter Doest terdoest@cs.utwente.nl
6             ## Description: module for sparse bitvectors
7             ## method names equal that of Bit::Vector
8             ##
9             ##---------------------------------------------------------------------------##
10             ## Copyright (C) 1998 Hugo WL ter Doest terdoest@cs.utwente.nl
11             ##
12             ## This library is free software; you can redistribute it and/or modify
13             ## it under the terms of the GNU General Public License as published by
14             ## the Free Software Foundation; either version 2 of the License, or
15             ## (at your option) any later version.
16             ##
17             ## This library is distributed in the hope that it will be useful,
18             ## but WITHOUT ANY WARRANTY; without even the implied warranty of
19             ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20             ## GNU General Public License for more details.
21             ##
22             ## You should have received a copy of the GNU Library General Public
23             ## License along with this program; if not, write to the Free Software
24             ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25             ##---------------------------------------------------------------------------##
26              
27              
28 3     3   714 use strict;
  3         4  
  3         176  
29 3         3083 use vars qw($VERSION
30             @ISA
31             @EXPORT
32 3     3   16 @EXPORT_OK);
  3         7  
33             use overload
34 3         40 '++' => \&increment,
35             '=' => \&Clone,
36 3     3   9871 '""' => \&stringify;
  3         14521  
37             require Exporter;
38             require AutoLoader;
39              
40             @ISA = qw(Exporter AutoLoader);
41             # Items to export into callers namespace by default. Note: do not export
42             # names by default without a very good reason. Use EXPORT_OK instead.
43             # Do not simply export all your public functions/methods/constants.
44             @EXPORT = qw(
45            
46             );
47             $VERSION = '0.1';
48              
49              
50             # Preloaded methods go here.
51              
52             # necessary for overloading ""
53             # in turn required by Data::Dumper that wants to stringify variables
54             sub stringify {
55 0     0 0 0 my($self) = @_;
56              
57 0         0 return($self);
58             }
59              
60              
61             # create a new bitvector
62             # all bits are `off'
63             sub new {
64 6977     6977 1 9841 my($this, $n) = @_;
65              
66             # for calling $self->new($someth):
67 6977   33     23946 my $class = ref($this) || $this;
68 6977         10046 my $self = {};
69 6977         13420 bless $self, $class;
70 6977         14841 $self->{N} = $n;
71 6977         12911 return($self);
72             }
73              
74              
75             # create a copy of a bitvector and return it
76             sub Clone {
77 4804     4804 1 6124 my($self) = @_;
78              
79 4804         5120 my($new);
80              
81 4804         13503 $new = Statistics::SparseVector->new($self->{N});
82 4804         9846 bless $new, ref($self);
83 4804         5683 for (keys %{$self->{VECTOR}}) {
  4804         16345  
84 29009         70239 $new->{VECTOR}{$_} = $self->{VECTOR}{$_};
85             }
86 4804         11703 return($new);
87             }
88              
89              
90             # is called right before Perl destroys a bitvector
91             # this happens automatically if a vector has zero references
92             sub DESTROY {
93 6675     6675   34111 my($self) = @_;
94              
95             }
96              
97              
98             # creates a new vector from a bitstring
99             sub new_Bin {
100 2100     2100 1 3497 my($this, $n, $bitvector) = @_;
101              
102 2100         2103 my($i, $self);
103              
104 2100         4200 $self = $this->new($n);
105 2100         2666 $i = 0;
106 2100         3877 while ($bitvector) {
107 19102 100       35011 if (chop($bitvector) eq "1") {
108 10882         20928 $self->{VECTOR}{$i} = 1;
109             }
110 19102         31843 $i++;
111             }
112 2100         6664 return($self);
113             }
114              
115              
116             # we assume a bit is `on' if its value is defined
117             sub bit_test {
118 328320     328320 1 393047 my($self, $i) = @_;
119              
120 328320         1396408 return(defined($self->{VECTOR}{$i}));
121             }
122              
123              
124             # turning off a bit is making its value undefined
125             sub Bit_Off {
126 0     0 1 0 my($self, $i) = @_;
127              
128 0         0 undef $self->{VECTOR}{$i};
129             }
130              
131              
132             # turns on a bit
133             sub Bit_On {
134 2     2 1 10 my($self, $i) = @_;
135              
136 2         10 $self->{VECTOR}{$i} = 1;
137             }
138              
139              
140             # flips a bit, i.e. makes it undef if it is defined,
141             # and makes it defined if it is undefined
142             sub bit_flip {
143 5887     5887 1 7957 my($self, $i) = @_;
144              
145 5887 100       14020 if (defined($self->{VECTOR}{$i})) {
146 2893         9464 undef $self->{VECTOR}{$i};
147             }
148             else {
149 2994         8829 $self->{VECTOR}{$i} = 1;
150             }
151             }
152              
153              
154             # increases the integer value of the bitvector by one
155             sub increment {
156 1869824     1869824 1 2480968 my($self) = @_;
157              
158 1869824         2233147 my($carry, $i);
159              
160 1869824         2221446 $carry = 0;
161 1869824         2184737 $i = 0;
162 1869824   100     2243866 do {
163 3739542 100       8800639 if ($self->{VECTOR}{$i}) {
164 1869771         2867568 undef $self->{VECTOR}{$i};
165 1869771         2488638 $carry = 1;
166             }
167             else {
168 1869771         2967170 $self->{VECTOR}{$i} = 1;
169 1869771         2300012 $carry = 0;
170             }
171 3739542         21430967 $i++;
172             } until (($carry == 0) || ($i == $self->{N}));
173             }
174              
175              
176             # fills the set
177             sub Fill {
178 18     18 1 44 my($self) = @_;
179              
180 18         25 my $i;
181              
182 18         78 for ($i = 0; $i < $self->{N}; $i++) {
183 180         637 $self->{VECTOR}{$i} = 1;
184             }
185             }
186              
187              
188             # clears all bits, empties the set
189             sub Empty {
190 18     18 1 35 my($self) = @_;
191            
192 18         59 undef $self->{VECTOR};
193             }
194              
195              
196             # returns a bitstring
197             sub to_Bin {
198 2436     2436 1 3645 my($self) = @_;
199              
200 2436         6517 my($s, $i);
201              
202 2436         3344 $s = "";
203 2436         9198 for ($i = 0; $i < $self->{N}; $i++) {
204 25170 100       47347 if (defined($self->{VECTOR}{$i})) {
205 14671         42994 $s = "1$s";
206             }
207             else {
208 10499         31162 $s = "0$s";
209             }
210             }
211 2436         9269 return($s);
212             }
213              
214              
215             # returns a comma-separated list of features that are on
216             sub to_Enum {
217 2     2 1 11 my($self) = @_;
218              
219 2         4 return(join(',', keys(%{$self->{VECTOR}})));
  2         9  
220             }
221              
222              
223             # expects a comma-separated list of numbers
224             sub new_Enum {
225 0     0 1 0 my($this, $n, $s) = @_;
226              
227 0         0 my($self);
228              
229 0         0 $self = $this->new($n);
230 0         0 for (split(/,/,$s)) {
231 0         0 $self->{VECTOR}{$_} = 1
232             }
233 0         0 return($self);
234             }
235              
236              
237             # returns the length of the vector
238             sub Size {
239 7608     7608 1 19934 my($self) = @_;
240              
241 7608         30339 return($self->{N});
242             }
243              
244              
245             # $len1 >= 0, $len2 >= 0, $vec2->Size() >= $off2 >= 0
246             # $vec1->Size() >= $off1 >= 0
247             # $vec1 may be undefined
248             # $len1 + $off1 < $vec->Size()
249             sub Interval_Substitute {
250 4804     4804 0 8565 my($vec2, $vec1, $off2, $len2, $off1, $len1) = @_;
251              
252 4804         6611 my($i,
253             $oldvec2);
254              
255             # save $vec2 in $oldvec2
256 4804         11956 $oldvec2 = $vec2->Clone();
257             # determine the new length for $vec2
258 4804 100       10984 if ($off2 == $vec2->Size()) {
259             # we are appending bits from source $vec1
260 2802         5043 $vec2->{N} += $len1;
261             }
262             else {
263             # we are inserting bits from $vec1
264 2002         3265 $vec2->{N} += $len1 - $len2;
265             }
266             # target $vec2 changes only from $off2
267             # copy the new bits from the source $vec1
268 4804 50       11018 if (defined($vec1)) { # we have source bits
269 4804         11793 for ($i = $off2; $i < $off2 + $len1; $i++) {
270 2814 100       8801 if (defined($vec1->{VECTOR}{$i - $off2 + $off1})) {
271 315         2438 $vec2->{VECTOR}{$i} = $vec1->{VECTOR}{$i - $off2 + $off1};
272             }
273             else {
274 2499         8087 undef $vec2->{VECTOR}{$i};
275             }
276             }
277             }
278             # append the rest of $oldvec2
279             # index $i runs for $oldvec2, we correct for $vec2
280 4804         11413 for ($i = $off2 + $len2; $i < $oldvec2->{N}; $i++) {
281 1 50       4 if (defined($oldvec2->{VECTOR}{$i})) {
282 1         12 $vec2->{VECTOR}{$i-$len2+$len1} = $oldvec2->{VECTOR}{$i};
283             }
284             else {
285 0         0 undef $vec2->{VECTOR}{$i-$len2+$len1};
286             }
287             }
288 4804         14084 undef $oldvec2;
289             }
290              
291              
292             # returns an array of indices of set bits
293             sub indices {
294 23595894     23595894 1 27793984 my($self) = @_;
295              
296 23595894         26661987 return(grep($self->{VECTOR}{$_}, keys(%{$self->{VECTOR}})));
  23595894         463505165  
297             }
298              
299              
300             # the number of bits that are on
301             sub Norm {
302 19809982     19809982 1 25785948 my($self) = @_;
303              
304 19809982         19750812 my(@a);
305              
306 19809982         37165116 @a = $self->indices();
307 19809982         108098827 return($#a + 1);
308             }
309              
310              
311             # Autoload methods go after =cut, and are processed by the autosplit program.
312              
313             1;
314              
315             __END__