File Coverage

blib/lib/Math/MatrixBool.pm
Criterion Covered Total %
statement 164 446 36.7
branch 41 198 20.7
condition 19 208 9.1
subroutine 24 70 34.2
pod 0 38 0.0
total 248 960 25.8


line stmt bran cond sub pod time code
1              
2             # Copyright (c) 1995 - 2009 by Steffen Beyer.
3             # All rights reserved.
4             # This package is free software; you can redistribute it and/or
5             # modify it under the same terms as Perl itself.
6              
7             package Math::MatrixBool;
8              
9 2     2   1915 use strict;
  2         3  
  2         73  
10 2     2   38 use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
  2         3  
  2         259  
11              
12             require Exporter;
13              
14             @ISA = qw(Exporter);
15              
16             @EXPORT = qw();
17              
18             @EXPORT_OK = qw();
19              
20             $VERSION = '5.8';
21              
22 2     2   10 use Carp;
  2         13  
  2         14810  
23              
24 2     2   3065 use Bit::Vector 7.1;
  2         3995  
  2         342  
25              
26             use overload
27 2         22 'neg' => '_complement',
28             '~' => '_transpose',
29             'bool' => '_boolean',
30             '!' => '_not_boolean',
31             '""' => '_string',
32             'abs' => '_number_of_elements',
33             '+' => '_addition',
34             '*' => '_multiplication',
35             '|' => '_union',
36             '-' => '_difference',
37             '&' => '_intersection',
38             '^' => '_exclusive_or',
39             '+=' => '_assign_addition',
40             '*=' => '_assign_multiplication',
41             '|=' => '_assign_union',
42             '-=' => '_assign_difference',
43             '&=' => '_assign_intersection',
44             '^=' => '_assign_exclusive_or',
45             '==' => '_equal',
46             '!=' => '_not_equal',
47             '<' => '_true_sub_set',
48             '<=' => '_sub_set',
49             '>' => '_true_super_set',
50             '>=' => '_super_set',
51             'cmp' => '_compare',
52             '=' => '_clone',
53 2     2   5565 'fallback' => undef;
  2         4368  
54              
55             sub new
56             {
57 75 50   75 0 149 croak "Usage: \$new_matrix = Math::MatrixBool->new(\$rows,\$columns);"
58             if (@_ != 3);
59              
60 75         86 my $proto = shift;
61 75   50     211 my $class = ref($proto) || $proto || 'Math::MatrixBool';
62 75         78 my $rows = shift;
63 75         76 my $cols = shift;
64 75         72 my $object;
65             my $matrix;
66              
67 75 50       145 croak "Math::MatrixBool::new(): number of rows must be > 0"
68             if ($rows <= 0);
69              
70 75 50       130 croak "Math::MatrixBool::new(): number of columns must be > 0"
71             if ($cols <= 0);
72              
73 75         351 $matrix = Bit::Vector->new($rows * $cols);
74 75 50 33     326 if ((defined $matrix) && ref($matrix) && (${$matrix} != 0))
  75   33     213  
75             {
76 75         235 $object = [ $matrix, $rows, $cols ];
77 75         136 bless($object, $class);
78 75         142 return($object);
79             }
80             else
81             {
82 0         0 croak
83             "Math::MatrixBool::new(): unable to create new 'Math::MatrixBool' object";
84             }
85             }
86              
87             sub new_from_string
88             {
89 10 50   10 0 105 croak "Usage: \$new_matrix = Math::MatrixBool->new_from_string(\$string);"
90             if (@_ != 2);
91              
92 10         13 my $proto = shift;
93 10   50     217 my $class = ref($proto) || $proto || 'Math::MatrixBool';
94 10         11 my $string = shift;
95 10         12 my($line,$values);
96 0         0 my($rows,$cols);
97 0         0 my($row,$col);
98 0         0 my($warn);
99 0         0 my($object);
100              
101 10         10 $warn = 0;
102 10         10 $rows = 0;
103 10         13 $cols = 0;
104 10         14 $values = [ ];
105 10         70 while ($string =~ m!^\s* \[ \s+ ( (?: (?: 0|1 ) \s+ )+ ) \] \s*? \n !x)
106             {
107 46         69 $line = $1;
108 46         66 $string = $';
109 46         65 $values->[$rows] = [ ];
110 46         103 @{$values->[$rows]} = split(' ', $line);
  46         101  
111 46         47 $col = @{$values->[$rows]};
  46         52  
112 46 100       83 if ($col != $cols)
113             {
114 10 50       21 unless ($cols == 0) { $warn = 1; }
  0         0  
115 10 50       15 if ($col > $cols) { $cols = $col; }
  10         12  
116             }
117 46         173 $rows++;
118             }
119 10 50       30 if ($string !~ m!^\s*$!)
120             {
121 0         0 croak "Math::MatrixBool::new_from_string(): syntax error in input string";
122             }
123 10 50       18 if ($rows == 0)
124             {
125 0         0 croak "Math::MatrixBool::new_from_string(): empty input string";
126             }
127 10 50       18 if ($warn)
128             {
129 0         0 warn "Math::MatrixBool::new_from_string(): missing elements will be set to zero!\n";
130             }
131 10         17 $object = Math::MatrixBool::new($class,$rows,$cols);
132 10         21 for ( $row = 0; $row < $rows; $row++ )
133             {
134 46         43 for ( $col = 0; $col < @{$values->[$row]}; $col++ )
  287         532  
135             {
136 241 100       468 if ($values->[$row][$col] != 0)
137             {
138 118         401 $object->[0]->Bit_On( $row * $cols + $col );
139             }
140             }
141             }
142 10         59 return($object);
143             }
144              
145             sub Dim # Returns dimensions of a matrix
146             {
147 0 0   0 0 0 croak "Usage: (\$rows,\$columns) = \$matrix->Dim();"
148             if (@_ != 1);
149              
150 0         0 my($matrix) = @_;
151              
152 0         0 return( $matrix->[1], $matrix->[2] );
153             }
154              
155             sub Empty
156             {
157 0 0   0 0 0 croak "Usage: \$matrix->Empty();"
158             if (@_ != 1);
159              
160 0         0 my($object) = @_;
161              
162 0         0 $object->[0]->Empty();
163             }
164              
165             sub Fill
166             {
167 1 50   1 0 13 croak "Usage: \$matrix->Fill();"
168             if (@_ != 1);
169              
170 1         3 my($object) = @_;
171              
172 1         10 $object->[0]->Fill();
173             }
174              
175             sub Flip
176             {
177 0 0   0 0 0 croak "Usage: \$matrix->Flip();"
178             if (@_ != 1);
179              
180 0         0 my($object) = @_;
181              
182 0         0 $object->[0]->Flip();
183             }
184              
185             sub Zero
186             {
187 0 0   0 0 0 croak "Usage: \$matrix->Zero();"
188             if (@_ != 1);
189              
190 0         0 my($object) = @_;
191              
192 0         0 $object->[0]->Empty();
193             }
194              
195             sub One # Fills main diagonal
196             {
197 6 50   6 0 35 croak "Usage: \$matrix->One();"
198             if (@_ != 1);
199              
200 6         9 my($object) = @_;
201 6         13 my($rows,$cols) = ($object->[1],$object->[2]);
202 6         6 my($i,$k);
203              
204 6         17 $object->[0]->Empty();
205 6 50       17 $k = ($rows <= $cols) ? $rows : $cols;
206 6         19 for ( $i = 0; $i < $k; $i++ )
207             {
208 48         193 $object->[0]->Bit_On( $i * $cols + $i );
209             }
210             }
211              
212             sub Bit_On
213             {
214 1 50   1 0 19 croak "Usage: \$matrix->Bit_On(\$row,\$column);"
215             if (@_ != 3);
216              
217 1         3 my($object,$row,$col) = @_;
218 1         3 my($rows,$cols) = ($object->[1],$object->[2]);
219              
220 1 50 33     8 croak "Math::MatrixBool::Bit_On(): row index out of range"
221             if (($row < 1) || ($row > $rows));
222 1 50 33     27 croak "Math::MatrixBool::Bit_On(): column index out of range"
223             if (($col < 1) || ($col > $cols));
224              
225 1         9 $object->[0]->Bit_On( --$row * $cols + --$col );
226             }
227              
228             sub Insert
229             {
230 0     0 0 0 Bit_On(@_);
231             }
232              
233             sub Bit_Off
234             {
235 0 0   0 0 0 croak "Usage: \$matrix->Bit_Off(\$row,\$column);"
236             if (@_ != 3);
237              
238 0         0 my($object,$row,$col) = @_;
239 0         0 my($rows,$cols) = ($object->[1],$object->[2]);
240              
241 0 0 0     0 croak "Math::MatrixBool::Bit_Off(): row index out of range"
242             if (($row < 1) || ($row > $rows));
243 0 0 0     0 croak "Math::MatrixBool::Bit_Off(): column index out of range"
244             if (($col < 1) || ($col > $cols));
245              
246 0         0 $object->[0]->Bit_Off( --$row * $cols + --$col );
247             }
248              
249             sub Delete
250             {
251 0     0 0 0 Bit_Off(@_);
252             }
253              
254             sub bit_flip
255             {
256 0 0   0 0 0 croak "Usage: \$boolean = \$matrix->bit_flip(\$row,\$column);"
257             if (@_ != 3);
258              
259 0         0 my($object,$row,$col) = @_;
260 0         0 my($rows,$cols) = ($object->[1],$object->[2]);
261              
262 0 0 0     0 croak "Math::MatrixBool::bit_flip(): row index out of range"
263             if (($row < 1) || ($row > $rows));
264 0 0 0     0 croak "Math::MatrixBool::bit_flip(): column index out of range"
265             if (($col < 1) || ($col > $cols));
266              
267 0         0 return( $object->[0]->bit_flip( --$row * $cols + --$col ) );
268             }
269              
270             sub flip
271             {
272 0     0 0 0 return( bit_flip(@_) );
273             }
274              
275             sub bit_test
276             {
277 0 0   0 0 0 croak "Usage: \$boolean = \$matrix->bit_test(\$row,\$column);"
278             if (@_ != 3);
279              
280 0         0 my($object,$row,$col) = @_;
281 0         0 my($rows,$cols) = ($object->[1],$object->[2]);
282              
283 0 0 0     0 croak "Math::MatrixBool::bit_test(): row index out of range"
284             if (($row < 1) || ($row > $rows));
285 0 0 0     0 croak "Math::MatrixBool::bit_test(): column index out of range"
286             if (($col < 1) || ($col > $cols));
287              
288 0         0 return( $object->[0]->bit_test( --$row * $cols + --$col ) );
289             }
290              
291             sub contains
292             {
293 0     0 0 0 return( bit_test(@_) );
294             }
295              
296             sub in
297             {
298 0     0 0 0 return( bit_test(@_) );
299             }
300              
301             sub Number_of_elements # returns the number of elements which are set
302             {
303 0 0   0 0 0 croak "Usage: \$elements = \$matrix->Number_of_elements();"
304             if (@_ != 1);
305              
306 0         0 my($object) = @_;
307              
308 0         0 return( $object->[0]->Norm() );
309             }
310              
311             sub Norm_max # Maximum of sums of each row
312             {
313 0 0   0 0 0 croak "Usage: \$norm_max = \$matrix->Norm_max();"
314             if (@_ != 1);
315              
316 0         0 my($object) = @_;
317 0         0 my($rows,$cols) = ($object->[1],$object->[2]);
318 0         0 my($max,$sum,$i,$j);
319              
320 0         0 $max = 0;
321 0         0 for ( $i = 0; $i < $rows; $i++ )
322             {
323 0         0 $sum = 0;
324 0         0 for ( $j = 0; $j < $cols; $j++ )
325             {
326 0         0 $sum ^= $object->[0]->bit_test( $i * $cols + $j );
327             # in general, this is $sum += abs( $matrix[$i][$j] );
328             }
329 0 0       0 if ($sum > $max) { $max = $sum; }
  0         0  
330             }
331 0         0 return($max);
332             }
333              
334             sub Norm_one # Maximum of sums of each column
335             {
336 0 0   0 0 0 croak "Usage: \$norm_one = \$matrix->Norm_one();"
337             if (@_ != 1);
338              
339 0         0 my($object) = @_;
340 0         0 my($rows,$cols) = ($object->[1],$object->[2]);
341 0         0 my($max,$sum,$i,$j);
342              
343 0         0 $max = 0;
344 0         0 for ( $j = 0; $j < $cols; $j++ )
345             {
346 0         0 $sum = 0;
347 0         0 for ( $i = 0; $i < $rows; $i++ )
348             {
349 0         0 $sum ^= $object->[0]->bit_test( $i * $cols + $j );
350             # in general, this is $sum += abs( $matrix[$i][$j] );
351             }
352 0 0       0 if ($sum > $max) { $max = $sum; }
  0         0  
353             }
354 0         0 return($max);
355             }
356              
357             sub Addition
358             {
359 0 0   0 0 0 croak "Usage: \$matrix1->Addition(\$matrix2,\$matrix3);"
360             if (@_ != 3);
361              
362 0         0 my($matrix1,$matrix2,$matrix3) = @_;
363 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
364 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
365 0         0 my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
366              
367 0 0 0     0 if (($rows1 == $rows2) && ($rows1 == $rows3) &&
      0        
      0        
368             ($cols1 == $cols2) && ($cols1 == $cols3))
369             {
370 0         0 $matrix1->[0]->ExclusiveOr($matrix2->[0],$matrix3->[0]);
371             }
372             else
373             {
374 0         0 croak "Math::MatrixBool::Addition(): matrix size mismatch";
375             }
376             }
377              
378             sub Multiplication
379             {
380 18 50   18 0 77 croak "Usage: \$product_matrix = \$matrix1->Multiplication(\$matrix2);"
381             if (@_ != 2);
382              
383 18         24 my($matrix1,$matrix2) = @_;
384 18         35 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
385 18         33 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
386 18         21 my($result);
387              
388 18 50       34 if ($cols1 == $rows2)
389             {
390 18         37 $result = $matrix1->new($rows1,$cols2);
391 18         127 $result->[0]->Multiplication($rows1,$cols2,
392             $matrix1->[0],$rows1,$cols1,
393             $matrix2->[0],$rows2,$cols2);
394             }
395             else
396             {
397 0         0 croak "Math::MatrixBool::Multiplication(): matrix size mismatch";
398             }
399 18         234 return($result);
400             }
401              
402             sub Product
403             {
404 12 50   12 0 91 croak "Usage: \$product_matrix = \$matrix1->Product(\$matrix2);"
405             if (@_ != 2);
406              
407 12         17 my($matrix1,$matrix2) = @_;
408 12         24 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
409 12         19 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
410 12         12 my($result);
411              
412 12 50       19 if ($cols1 == $rows2)
413             {
414 12         29 $result = $matrix1->new($rows1,$cols2);
415 12         88 $result->[0]->Product($rows1,$cols2,
416             $matrix1->[0],$rows1,$cols1,
417             $matrix2->[0],$rows2,$cols2);
418             }
419             else
420             {
421 0         0 croak "Math::MatrixBool::Product(): matrix size mismatch";
422             }
423 12         67 return($result);
424             }
425              
426             sub Kleene
427             {
428 2 50   2 0 33 croak "Usage: \$closure = \$matrix->Kleene();"
429             if (@_ != 1);
430              
431 2         5 my($matrix) = @_;
432 2         9 my($rows,$cols) = ($matrix->[1],$matrix->[2]);
433 2         4 my($result);
434              
435 2 50       7 croak "Math::MatrixBool::Kleene(): not a square matrix"
436             if ($rows != $cols);
437              
438 2         8 $result = $matrix->new($rows,$cols);
439 2         9 $result->Copy($matrix);
440 2         17 $result->[0]->Closure($rows,$cols);
441              
442 2         4 return($result);
443             }
444              
445             sub Union
446             {
447 16 50   16 0 76 croak "Usage: \$matrix1->Union(\$matrix2,\$matrix3);"
448             if (@_ != 3);
449              
450 16         24 my($matrix1,$matrix2,$matrix3) = @_;
451 16         33 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
452 16         26 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
453 16         25 my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
454              
455 16 50 33     129 if (($rows1 == $rows2) && ($rows1 == $rows3) &&
      33        
      33        
456             ($cols1 == $cols2) && ($cols1 == $cols3))
457             {
458 16         117 $matrix1->[0]->Union($matrix2->[0],$matrix3->[0]);
459             }
460             else
461             {
462 0         0 croak "Math::MatrixBool::Union(): matrix size mismatch";
463             }
464             }
465              
466             sub Intersection
467             {
468 0 0   0 0 0 croak "Usage: \$matrix1->Intersection(\$matrix2,\$matrix3);"
469             if (@_ != 3);
470              
471 0         0 my($matrix1,$matrix2,$matrix3) = @_;
472 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
473 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
474 0         0 my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
475              
476 0 0 0     0 if (($rows1 == $rows2) && ($rows1 == $rows3) &&
      0        
      0        
477             ($cols1 == $cols2) && ($cols1 == $cols3))
478             {
479 0         0 $matrix1->[0]->Intersection($matrix2->[0],$matrix3->[0]);
480             }
481             else
482             {
483 0         0 croak "Math::MatrixBool::Intersection(): matrix size mismatch";
484             }
485             }
486              
487             sub Difference
488             {
489 0 0   0 0 0 croak "Usage: \$matrix1->Difference(\$matrix2,\$matrix3);"
490             if (@_ != 3);
491              
492 0         0 my($matrix1,$matrix2,$matrix3) = @_;
493 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
494 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
495 0         0 my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
496              
497 0 0 0     0 if (($rows1 == $rows2) && ($rows1 == $rows3) &&
      0        
      0        
498             ($cols1 == $cols2) && ($cols1 == $cols3))
499             {
500 0         0 $matrix1->[0]->Difference($matrix2->[0],$matrix3->[0]);
501             }
502             else
503             {
504 0         0 croak "Math::MatrixBool::Difference(): matrix size mismatch";
505             }
506             }
507              
508             sub ExclusiveOr
509             {
510 0 0   0 0 0 croak "Usage: \$matrix1->ExclusiveOr(\$matrix2,\$matrix3);"
511             if (@_ != 3);
512              
513 0         0 my($matrix1,$matrix2,$matrix3) = @_;
514 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
515 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
516 0         0 my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
517              
518 0 0 0     0 if (($rows1 == $rows2) && ($rows1 == $rows3) &&
      0        
      0        
519             ($cols1 == $cols2) && ($cols1 == $cols3))
520             {
521 0         0 $matrix1->[0]->ExclusiveOr($matrix2->[0],$matrix3->[0]);
522             }
523             else
524             {
525 0         0 croak "Math::MatrixBool::ExclusiveOr(): matrix size mismatch";
526             }
527             }
528              
529             sub Complement
530             {
531 0 0   0 0 0 croak "Usage: \$matrix1->Complement(\$matrix2);"
532             if (@_ != 2);
533              
534 0         0 my($matrix1,$matrix2) = @_;
535 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
536 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
537              
538 0 0 0     0 if (($rows1 == $rows2) && ($cols1 == $cols2))
539             {
540 0         0 $matrix1->[0]->Complement($matrix2->[0]);
541             }
542             else
543             {
544 0         0 croak "Math::MatrixBool::Complement(): matrix size mismatch";
545             }
546             }
547              
548             sub Transpose
549             {
550 25 50   25 0 93 croak "Usage: \$matrix1->Transpose(\$matrix2);"
551             if (@_ != 2);
552              
553 25         25 my($matrix1,$matrix2) = @_;
554 25         42 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
555 25         28 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
556              
557 25 100 66     78 if (($rows1 == $cols2) && ($cols1 == $rows2))
558             {
559 24         90 $matrix1->[0]->Transpose($rows1,$cols1,$matrix2->[0],$rows2,$cols2);
560             }
561             else
562             {
563 1         196 croak "Math::MatrixBool::Transpose(): matrix size mismatch";
564             }
565             }
566              
567             sub equal
568             {
569 60 50   60 0 328 croak "Usage: \$boolean = \$matrix1->equal(\$matrix2);"
570             if (@_ != 2);
571              
572 60         74 my($matrix1,$matrix2) = @_;
573 60         87 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
574 60         114 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
575              
576 60 50 33     223 if (($rows1 == $rows2) && ($cols1 == $cols2))
577             {
578 60         277 return( $matrix1->[0]->equal($matrix2->[0]) );
579             }
580             else
581             {
582 0         0 croak "Math::MatrixBool::equal(): matrix size mismatch";
583             }
584             }
585              
586             sub subset
587             {
588 0 0   0 0 0 croak "Usage: \$boolean = \$matrix1->subset(\$matrix2);"
589             if (@_ != 2);
590              
591 0         0 my($matrix1,$matrix2) = @_;
592 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
593 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
594              
595 0 0 0     0 if (($rows1 == $rows2) && ($cols1 == $cols2))
596             {
597 0         0 return( $matrix1->[0]->subset($matrix2->[0]) );
598             }
599             else
600             {
601 0         0 croak "Math::MatrixBool::subset(): matrix size mismatch";
602             }
603             }
604              
605             sub inclusion
606             {
607 0     0 0 0 return( subset(@_) );
608             }
609              
610             sub lexorder
611             {
612 0 0   0 0 0 croak "Usage: \$boolean = \$matrix1->lexorder(\$matrix2);"
613             if (@_ != 2);
614              
615 0         0 my($matrix1,$matrix2) = @_;
616 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
617 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
618              
619 0 0 0     0 if (($rows1 == $rows2) && ($cols1 == $cols2))
620             {
621 0         0 return( $matrix1->[0]->lexorder($matrix2->[0]) );
622             }
623             else
624             {
625 0         0 croak "Math::MatrixBool::lexorder(): matrix size mismatch";
626             }
627             }
628              
629             sub Compare
630             {
631 0 0   0 0 0 croak "Usage: \$result = \$matrix1->Compare(\$matrix2);"
632             if (@_ != 2);
633              
634 0         0 my($matrix1,$matrix2) = @_;
635 0         0 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
636 0         0 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
637              
638 0 0 0     0 if (($rows1 == $rows2) && ($cols1 == $cols2))
639             {
640 0         0 return( $matrix1->[0]->Compare($matrix2->[0]) );
641             }
642             else
643             {
644 0         0 croak "Math::MatrixBool::Compare(): matrix size mismatch";
645             }
646             }
647              
648             sub Copy
649             {
650 8 50   8 0 26 croak "Usage: \$matrix1->Copy(\$matrix2);"
651             if (@_ != 2);
652              
653 8         11 my($matrix1,$matrix2) = @_;
654 8         15 my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
655 8         10 my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
656              
657 8 50 33     35 if (($rows1 == $rows2) && ($cols1 == $cols2))
658             {
659 8         33 $matrix1->[0]->Copy($matrix2->[0]);
660             }
661             else
662             {
663 0         0 croak "Math::MatrixBool::Copy(): matrix size mismatch";
664             }
665             }
666              
667             sub Shadow
668             {
669 18 50   18 0 122 croak "Usage: \$other_matrix = \$some_matrix->Shadow();"
670             if (@_ != 1);
671              
672 18         24 my($matrix) = @_;
673 18         22 my($result);
674              
675 18         37 $result = $matrix->new($matrix->[1],$matrix->[2]);
676 18         41 return($result);
677             }
678              
679             sub Clone
680             {
681 4 50   4 0 41 croak "Usage: \$twin_matrix = \$some_matrix->Clone();"
682             if (@_ != 1);
683              
684 4         6 my($matrix) = @_;
685 4         5 my($result);
686              
687 4         11 $result = $matrix->new($matrix->[1],$matrix->[2]);
688 4         18 $result->Copy($matrix);
689 4         9 return($result);
690             }
691              
692             ########################################
693             # #
694             # define overloaded operators section: #
695             # #
696             ########################################
697              
698             sub _complement
699             {
700 0     0   0 my($object,$argument,$flag) = @_;
701             # my($name) = "neg"; #&_trace($name,$object,$argument,$flag);
702 0         0 my($result);
703              
704 0         0 $result = $object->new($object->[1],$object->[2]);
705 0         0 $result->Complement($object);
706 0         0 return($result);
707             }
708              
709             sub _transpose
710             {
711 11     11   56 my($object,$argument,$flag) = @_;
712             # my($name) = "'~'"; #&_trace($name,$object,$argument,$flag);
713 11         11 my($result);
714              
715 11         18 $result = $object->new($object->[2],$object->[1]);
716 11         20 $result->Transpose($object);
717 11         24 return($result);
718             }
719              
720             sub _boolean
721             {
722 0     0   0 my($object,$argument,$flag) = @_;
723             # my($name) = "bool"; #&_trace($name,$object,$argument,$flag);
724              
725 0         0 return( $object->[0]->Min() < $object->[1] * $object->[2] );
726             }
727              
728             sub _not_boolean
729             {
730 0     0   0 my($object,$argument,$flag) = @_;
731             # my($name) = "'!'"; #&_trace($name,$object,$argument,$flag);
732              
733 0         0 return( !($object->[0]->Min() < $object->[1] * $object->[2]) );
734             }
735              
736             sub _string
737             {
738 0     0   0 my($object,$argument,$flag) = @_;
739             # my($name) = '""'; #&_trace($name,$object,$argument,$flag);
740 0         0 my($rows,$cols) = ($object->[1],$object->[2]);
741 0         0 my($i,$j,$s);
742              
743 0         0 $s = '';
744 0         0 for ( $i = 1; $i <= $rows; $i++ )
745             {
746 0         0 $s .= "[ ";
747 0         0 for ( $j = 1; $j <= $cols; $j++ )
748             {
749 0 0       0 if ($object->bit_test($i,$j)) { $s .= "1 "; } else { $s .= "0 "; }
  0         0  
  0         0  
750             }
751 0         0 $s .= "]\n";
752             }
753 0         0 return($s);
754             }
755              
756             sub _number_of_elements
757             {
758 0     0   0 my($object,$argument,$flag) = @_;
759             # my($name) = "abs"; #&_trace($name,$object,$argument,$flag);
760              
761 0         0 return( $object->Number_of_elements() );
762             }
763              
764             sub _addition
765             {
766 0     0   0 my($object,$argument,$flag) = @_;
767 0         0 my($name) = "'+'"; #&_trace($name,$object,$argument,$flag);
768 0         0 my($result);
769              
770 0 0 0     0 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
771             {
772 0 0       0 if (defined $flag)
773             {
774 0         0 $result = $object->new($object->[1],$object->[2]);
775 0         0 $result->ExclusiveOr($object,$argument);
776 0         0 return($result);
777             }
778             else
779             {
780 0         0 $object->ExclusiveOr($object,$argument);
781 0         0 return($object);
782             }
783             }
784             else
785             {
786 0         0 croak "Math::MatrixBool $name: wrong argument type";
787             }
788             }
789              
790             sub _multiplication
791             {
792 10     10   31 my($object,$argument,$flag) = @_;
793 10         16 my($name) = "'*'"; #&_trace($name,$object,$argument,$flag);
794 10         12 my($result);
795              
796 10 50 33     89 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      33        
797             {
798 10 50 66     35 if ((defined $flag) && $flag)
799             {
800 0         0 return( Multiplication($argument,$object) );
801             }
802             else
803             {
804 10         25 return( Multiplication($object,$argument) );
805             }
806             }
807             else
808             {
809 0         0 croak "Math::MatrixBool $name: wrong argument type";
810             }
811             }
812              
813             sub _union
814             {
815 7     7   17 my($object,$argument,$flag) = @_;
816 7         13 my($name) = "'|'"; #&_trace($name,$object,$argument,$flag);
817 7         11 my($result);
818              
819 7 50 33     69 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      33        
820             {
821 7 50       17 if (defined $flag)
822             {
823 0         0 $result = $object->new($object->[1],$object->[2]);
824 0         0 $result->Union($object,$argument);
825 0         0 return($result);
826             }
827             else
828             {
829 7         18 $object->Union($object,$argument);
830 7         33 return($object);
831             }
832             }
833             else
834             {
835 0         0 croak "Math::MatrixBool $name: wrong argument type";
836             }
837             }
838              
839             sub _difference
840             {
841 0     0   0 my($object,$argument,$flag) = @_;
842 0         0 my($name) = "'-'"; #&_trace($name,$object,$argument,$flag);
843 0         0 my($result);
844              
845 0 0 0     0 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
846             {
847 0 0       0 if (defined $flag)
848             {
849 0         0 $result = $object->new($object->[1],$object->[2]);
850 0 0       0 if ($flag) { $result->Difference($argument,$object); }
  0         0  
851 0         0 else { $result->Difference($object,$argument); }
852 0         0 return($result);
853             }
854             else
855             {
856 0         0 $object->Difference($object,$argument);
857 0         0 return($object);
858             }
859             }
860             else
861             {
862 0         0 croak "Math::MatrixBool $name: wrong argument type";
863             }
864             }
865              
866             sub _intersection
867             {
868 0     0   0 my($object,$argument,$flag) = @_;
869 0         0 my($name) = "'&'"; #&_trace($name,$object,$argument,$flag);
870 0         0 my($result);
871              
872 0 0 0     0 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
873             {
874 0 0       0 if (defined $flag)
875             {
876 0         0 $result = $object->new($object->[1],$object->[2]);
877 0         0 $result->Intersection($object,$argument);
878 0         0 return($result);
879             }
880             else
881             {
882 0         0 $object->Intersection($object,$argument);
883 0         0 return($object);
884             }
885             }
886             else
887             {
888 0         0 croak "Math::MatrixBool $name: wrong argument type";
889             }
890             }
891              
892             sub _exclusive_or
893             {
894 0     0   0 my($object,$argument,$flag) = @_;
895 0         0 my($name) = "'^'"; #&_trace($name,$object,$argument,$flag);
896 0         0 my($result);
897              
898 0 0 0     0 if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
899             {
900 0 0       0 if (defined $flag)
901             {
902 0         0 $result = $object->new($object->[1],$object->[2]);
903 0         0 $result->ExclusiveOr($object,$argument);
904 0         0 return($result);
905             }
906             else
907             {
908 0         0 $object->ExclusiveOr($object,$argument);
909 0         0 return($object);
910             }
911             }
912             else
913             {
914 0         0 croak "Math::MatrixBool $name: wrong argument type";
915             }
916             }
917              
918             sub _assign_addition
919             {
920 0     0   0 my($object,$argument,$flag) = @_;
921             # my($name) = "'+='"; #&_trace($name,$object,$argument,$flag);
922              
923 0         0 return( &_addition($object,$argument,undef) );
924             }
925              
926             sub _assign_multiplication
927             {
928 7     7   64 my($object,$argument,$flag) = @_;
929             # my($name) = "'*='"; #&_trace($name,$object,$argument,$flag);
930              
931 7         19 return( &_multiplication($object,$argument,undef) );
932             }
933              
934             sub _assign_union
935             {
936 7     7   54 my($object,$argument,$flag) = @_;
937             # my($name) = "'|='"; #&_trace($name,$object,$argument,$flag);
938              
939 7         17 return( &_union($object,$argument,undef) );
940             }
941              
942             sub _assign_difference
943             {
944 0     0     my($object,$argument,$flag) = @_;
945             # my($name) = "'-='"; #&_trace($name,$object,$argument,$flag);
946              
947 0           return( &_difference($object,$argument,undef) );
948             }
949              
950             sub _assign_intersection
951             {
952 0     0     my($object,$argument,$flag) = @_;
953             # my($name) = "'&='"; #&_trace($name,$object,$argument,$flag);
954              
955 0           return( &_intersection($object,$argument,undef) );
956             }
957              
958             sub _assign_exclusive_or
959             {
960 0     0     my($object,$argument,$flag) = @_;
961             # my($name) = "'^='"; #&_trace($name,$object,$argument,$flag);
962              
963 0           return( &_exclusive_or($object,$argument,undef) );
964             }
965              
966             sub _equal
967             {
968 0     0     my($object,$argument,$flag) = @_;
969 0           my($name) = "'=='"; #&_trace($name,$object,$argument,$flag);
970              
971 0 0 0       if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
972             {
973 0           return( $object->equal($argument) );
974             }
975             else
976             {
977 0           croak "Math::MatrixBool $name: wrong argument type";
978             }
979             }
980              
981             sub _not_equal
982             {
983 0     0     my($object,$argument,$flag) = @_;
984 0           my($name) = "'!='"; #&_trace($name,$object,$argument,$flag);
985              
986 0 0 0       if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
987             {
988 0           return( !($object->equal($argument)) );
989             }
990             else
991             {
992 0           croak "Math::MatrixBool $name: wrong argument type";
993             }
994             }
995              
996             sub _true_sub_set
997             {
998 0     0     my($object,$argument,$flag) = @_;
999 0           my($name) = "'<'"; #&_trace($name,$object,$argument,$flag);
1000              
1001 0 0 0       if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
1002             {
1003 0 0 0       if ((defined $flag) && $flag)
1004             {
1005 0   0       return( !($argument->equal($object)) &&
1006             ($argument->subset($object)) );
1007             }
1008             else
1009             {
1010 0   0       return( !($object->equal($argument)) &&
1011             ($object->subset($argument)) );
1012             }
1013             }
1014             else
1015             {
1016 0           croak "Math::MatrixBool $name: wrong argument type";
1017             }
1018             }
1019              
1020             sub _sub_set
1021             {
1022 0     0     my($object,$argument,$flag) = @_;
1023 0           my($name) = "'<='"; #&_trace($name,$object,$argument,$flag);
1024              
1025 0 0 0       if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
1026             {
1027 0 0 0       if ((defined $flag) && $flag)
1028             {
1029 0           return( $argument->subset($object) );
1030             }
1031             else
1032             {
1033 0           return( $object->subset($argument) );
1034             }
1035             }
1036             else
1037             {
1038 0           croak "Math::MatrixBool $name: wrong argument type";
1039             }
1040             }
1041              
1042             sub _true_super_set
1043             {
1044 0     0     my($object,$argument,$flag) = @_;
1045 0           my($name) = "'>'"; #&_trace($name,$object,$argument,$flag);
1046              
1047 0 0 0       if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
1048             {
1049 0 0 0       if ((defined $flag) && $flag)
1050             {
1051 0   0       return( !($object->equal($argument)) &&
1052             ($object->subset($argument)) );
1053             }
1054             else
1055             {
1056 0   0       return( !($argument->equal($object)) &&
1057             ($argument->subset($object)) );
1058             }
1059             }
1060             else
1061             {
1062 0           croak "Math::MatrixBool $name: wrong argument type";
1063             }
1064             }
1065              
1066             sub _super_set
1067             {
1068 0     0     my($object,$argument,$flag) = @_;
1069 0           my($name) = "'>='"; #&_trace($name,$object,$argument,$flag);
1070              
1071 0 0 0       if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
1072             {
1073 0 0 0       if ((defined $flag) && $flag)
1074             {
1075 0           return( $object->subset($argument) );
1076             }
1077             else
1078             {
1079 0           return( $argument->subset($object) );
1080             }
1081             }
1082             else
1083             {
1084 0           croak "Math::MatrixBool $name: wrong argument type";
1085             }
1086             }
1087              
1088             sub _compare
1089             {
1090 0     0     my($object,$argument,$flag) = @_;
1091 0           my($name) = "cmp"; #&_trace($name,$object,$argument,$flag);
1092              
1093 0 0 0       if ((defined $argument) && ref($argument) && (ref($argument) !~ /^[A-Z]+$/))
      0        
1094             {
1095 0 0 0       if ((defined $flag) && $flag)
1096             {
1097 0           return( $argument->Compare($object) );
1098             }
1099             else
1100             {
1101 0           return( $object->Compare($argument) );
1102             }
1103             }
1104             else
1105             {
1106 0           croak "Math::MatrixBool $name: wrong argument type";
1107             }
1108             }
1109              
1110             sub _clone
1111             {
1112 0     0     my($object,$argument,$flag) = @_;
1113             # my($name) = "'='"; #&_trace($name,$object,$argument,$flag);
1114 0           my($result);
1115              
1116 0           $result = $object->new($object->[1],$object->[2]);
1117 0           $result->Copy($object);
1118 0           return($result);
1119             }
1120              
1121             sub _trace
1122             {
1123 0     0     my($text,$object,$argument,$flag) = @_;
1124              
1125 0 0         unless (defined $object) { $object = 'undef'; };
  0            
1126 0 0         unless (defined $argument) { $argument = 'undef'; };
  0            
1127 0 0         unless (defined $flag) { $flag = 'undef'; };
  0            
1128 0 0         if (ref($object)) { $object = ref($object); }
  0            
1129 0 0         if (ref($argument)) { $argument = ref($argument); }
  0            
1130 0           print "$text: \$obj='$object' \$arg='$argument' \$flag='$flag'\n";
1131             }
1132              
1133             1;
1134              
1135             __END__