home *** CD-ROM | disk | FTP | other *** search
-
- # Copyright (c) 1996, 1997 by Steffen Beyer. All rights reserved.
- # This package is free software; you can redistribute it and/or
- # modify it under the same terms as Perl itself.
-
- package Math::MatrixBool;
-
- use strict;
- use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
-
- require Exporter;
-
- @ISA = qw(Exporter);
-
- @EXPORT = qw();
-
- @EXPORT_OK = qw();
-
- $VERSION = '4.2';
-
- use Carp;
-
- use Bit::Vector;
-
- use overload
- 'neg' => '_complement',
- '~' => '_complement',
- 'bool' => '_boolean',
- '!' => '_not_boolean',
- '""' => '_string',
- 'abs' => '_number_of_elements',
- '+' => '_addition',
- '*' => '_multiplication',
- '|' => '_union',
- '-' => '_difference',
- '&' => '_intersection',
- '^' => '_exclusive_or',
- '+=' => '_assign_addition',
- '*=' => '_assign_multiplication',
- '|=' => '_assign_union',
- '-=' => '_assign_difference',
- '&=' => '_assign_intersection',
- '^=' => '_assign_exclusive_or',
- '==' => '_equal',
- '!=' => '_not_equal',
- '<' => '_true_sub_set',
- '<=' => '_sub_set',
- '>' => '_true_super_set',
- '>=' => '_super_set',
- 'cmp' => '_compare',
- '=' => '_clone',
- 'fallback' => undef;
-
- sub new
- {
- croak "Usage: \$new_matrix = Math::MatrixBool->new(\$rows,\$columns);"
- if (@_ != 3);
-
- my $proto = shift;
- my $class = ref($proto) || $proto || 'Math::MatrixBool';
- my $rows = shift;
- my $cols = shift;
- my $object;
- my $matrix;
-
- croak "Math::MatrixBool::new(): number of rows must be > 0"
- if ($rows <= 0);
-
- croak "Math::MatrixBool::new(): number of columns must be > 0"
- if ($cols <= 0);
-
- $matrix = Bit::Vector->new($rows * $cols);
- if ((defined $matrix) && ref($matrix) && (${$matrix} != 0))
- {
- $object = [ $matrix, $rows, $cols ];
- bless($object, $class);
- return($object);
- }
- else
- {
- croak
- "Math::MatrixBool::new(): unable to create new 'Math::MatrixBool' object";
- }
- }
-
- sub new_from_string
- {
- croak "Usage: \$new_matrix = Math::MatrixBool->new_from_string(\$string);"
- if (@_ != 2);
-
- my $proto = shift;
- my $class = ref($proto) || $proto || 'Math::MatrixBool';
- my $string = shift;
- my($line,$values);
- my($rows,$cols);
- my($row,$col);
- my($warn);
- my($object);
-
- $warn = 0;
- $rows = 0;
- $cols = 0;
- $values = [ ];
- while ($string =~ m!^\s* \[ \s+ ( (?: (?: 0|1 ) \s+ )+ ) \] \s*? \n !x)
- {
- $line = $1;
- $string = $';
- $values->[$rows] = [ ];
- @{$values->[$rows]} = split(' ', $line);
- $col = @{$values->[$rows]};
- if ($col != $cols)
- {
- unless ($cols == 0) { $warn = 1; }
- if ($col > $cols) { $cols = $col; }
- }
- $rows++;
- }
- if ($string !~ m!^\s*$!)
- {
- croak "Math::MatrixBool::new_from_string(): syntax error in input string";
- }
- if ($rows == 0)
- {
- croak "Math::MatrixBool::new_from_string(): empty input string";
- }
- if ($warn)
- {
- warn "Math::MatrixBool::new_from_string(): missing elements will be set to zero!\n";
- }
- $object = Math::MatrixBool::new($class,$rows,$cols);
- for ( $row = 0; $row < $rows; $row++ )
- {
- for ( $col = 0; $col < @{$values->[$row]}; $col++ )
- {
- if ($values->[$row][$col] != 0)
- {
- $object->[0]->Bit_On( $row * $cols + $col );
- }
- }
- }
- return($object);
- }
-
- sub Dim # Returns dimensions of a matrix
- {
- croak "Usage: (\$rows,\$columns) = \$matrix->Dim();"
- if (@_ != 1);
-
- my($matrix) = @_;
-
- return( $matrix->[1], $matrix->[2] );
- }
-
- sub Empty
- {
- croak "Usage: \$matrix->Empty();"
- if (@_ != 1);
-
- my($object) = @_;
-
- $object->[0]->Empty();
- }
-
- sub Fill
- {
- croak "Usage: \$matrix->Fill();"
- if (@_ != 1);
-
- my($object) = @_;
-
- $object->[0]->Fill();
- }
-
- sub Flip
- {
- croak "Usage: \$matrix->Flip();"
- if (@_ != 1);
-
- my($object) = @_;
-
- $object->[0]->Flip();
- }
-
- sub Zero
- {
- croak "Usage: \$matrix->Zero();"
- if (@_ != 1);
-
- my($object) = @_;
-
- $object->[0]->Empty();
- }
-
- sub One # Fills main diagonal
- {
- croak "Usage: \$matrix->One();"
- if (@_ != 1);
-
- my($object) = @_;
- my($rows,$cols) = ($object->[1],$object->[2]);
- my($i,$k);
-
- $object->[0]->Empty();
- $k = ($rows <= $cols) ? $rows : $cols;
- for ( $i = 0; $i < $k; $i++ )
- {
- $object->[0]->Bit_On( $i * $cols + $i );
- }
- }
-
- sub Bit_On
- {
- croak "Usage: \$matrix->Bit_On(\$row,\$column);"
- if (@_ != 3);
-
- my($object,$row,$col) = @_;
- my($rows,$cols) = ($object->[1],$object->[2]);
-
- croak "Math::MatrixBool::Bit_On(): row index out of range"
- if (($row < 1) || ($row > $rows));
- croak "Math::MatrixBool::Bit_On(): column index out of range"
- if (($col < 1) || ($col > $cols));
-
- $object->[0]->Bit_On( --$row * $cols + --$col );
- }
-
- sub Insert
- {
- Bit_On(@_);
- }
-
- sub Bit_Off
- {
- croak "Usage: \$matrix->Bit_Off(\$row,\$column);"
- if (@_ != 3);
-
- my($object,$row,$col) = @_;
- my($rows,$cols) = ($object->[1],$object->[2]);
-
- croak "Math::MatrixBool::Bit_Off(): row index out of range"
- if (($row < 1) || ($row > $rows));
- croak "Math::MatrixBool::Bit_Off(): column index out of range"
- if (($col < 1) || ($col > $cols));
-
- $object->[0]->Bit_Off( --$row * $cols + --$col );
- }
-
- sub Delete
- {
- Bit_Off(@_);
- }
-
- sub bit_flip
- {
- croak "Usage: \$boolean = \$matrix->bit_flip(\$row,\$column);"
- if (@_ != 3);
-
- my($object,$row,$col) = @_;
- my($rows,$cols) = ($object->[1],$object->[2]);
-
- croak "Math::MatrixBool::bit_flip(): row index out of range"
- if (($row < 1) || ($row > $rows));
- croak "Math::MatrixBool::bit_flip(): column index out of range"
- if (($col < 1) || ($col > $cols));
-
- return( $object->[0]->bit_flip( --$row * $cols + --$col ) );
- }
-
- sub flip
- {
- return( bit_flip(@_) );
- }
-
- sub bit_test
- {
- croak "Usage: \$boolean = \$matrix->bit_test(\$row,\$column);"
- if (@_ != 3);
-
- my($object,$row,$col) = @_;
- my($rows,$cols) = ($object->[1],$object->[2]);
-
- croak "Math::MatrixBool::bit_test(): row index out of range"
- if (($row < 1) || ($row > $rows));
- croak "Math::MatrixBool::bit_test(): column index out of range"
- if (($col < 1) || ($col > $cols));
-
- return( $object->[0]->bit_test( --$row * $cols + --$col ) );
- }
-
- sub contains
- {
- return( bit_test(@_) );
- }
-
- sub in
- {
- return( bit_test(@_) );
- }
-
- sub Number_of_elements # returns the number of elements which are set
- {
- croak "Usage: \$elements = \$matrix->Number_of_elements();"
- if (@_ != 1);
-
- my($object) = @_;
-
- return( $object->[0]->Norm() );
- }
-
- sub Norm_max # Maximum of sums of each row
- {
- croak "Usage: \$norm_max = \$matrix->Norm_max();"
- if (@_ != 1);
-
- my($object) = @_;
- my($rows,$cols) = ($object->[1],$object->[2]);
- my($max,$sum,$i,$j);
-
- $max = 0;
- for ( $i = 0; $i < $rows; $i++ )
- {
- $sum = 0;
- for ( $j = 0; $j < $cols; $j++ )
- {
- $sum ^= $object->[0]->bit_test( $i * $cols + $j );
- # in general, this is $sum += abs( $matrix[$i][$j] );
- }
- if ($sum > $max) { $max = $sum; }
- }
- return($max);
- }
-
- sub Norm_one # Maximum of sums of each column
- {
- croak "Usage: \$norm_one = \$matrix->Norm_one();"
- if (@_ != 1);
-
- my($object) = @_;
- my($rows,$cols) = ($object->[1],$object->[2]);
- my($max,$sum,$i,$j);
-
- $max = 0;
- for ( $j = 0; $j < $cols; $j++ )
- {
- $sum = 0;
- for ( $i = 0; $i < $rows; $i++ )
- {
- $sum ^= $object->[0]->bit_test( $i * $cols + $j );
- # in general, this is $sum += abs( $matrix[$i][$j] );
- }
- if ($sum > $max) { $max = $sum; }
- }
- return($max);
- }
-
- sub Addition
- {
- croak "Usage: \$matrix1->Addition(\$matrix2,\$matrix3);"
- if (@_ != 3);
-
- my($matrix1,$matrix2,$matrix3) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
- my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
-
- if (($rows1 == $rows2) && ($rows1 == $rows3) &&
- ($cols1 == $cols2) && ($cols1 == $cols3))
- {
- $matrix1->[0]->ExclusiveOr($matrix2->[0],$matrix3->[0]);
- }
- else
- {
- croak "Math::MatrixBool::Addition(): matrix size mismatch";
- }
- }
-
- sub Multiplication
- {
- croak "Usage: \$product_matrix = \$matrix1->Multiplication(\$matrix2);"
- if (@_ != 2);
-
- my($matrix1,$matrix2) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
- my($result);
-
- if ($cols1 == $rows2)
- {
- $result = $matrix1->new($rows1,$cols2);
- $result->[0]->Multiplication($rows1,$cols2,
- $matrix1->[0],$rows1,$cols1,
- $matrix2->[0],$rows2,$cols2);
- }
- else
- {
- croak "Math::MatrixBool::Multiplication(): matrix size mismatch";
- }
- return($result);
- }
-
- sub Kleene
- {
- croak "Usage: \$closure = \$matrix->Kleene();"
- if (@_ != 1);
-
- my($matrix) = @_;
- my($rows,$cols) = ($matrix->[1],$matrix->[2]);
- my($result);
-
- croak "Math::MatrixBool::Kleene(): matrix is not quadratic"
- if ($rows != $cols);
-
- $result = $matrix->new($rows,$cols);
- $result->Copy($matrix);
- $result->[0]->Closure($rows,$cols);
-
- return($result);
- }
-
- sub Union
- {
- croak "Usage: \$matrix1->Union(\$matrix2,\$matrix3);"
- if (@_ != 3);
-
- my($matrix1,$matrix2,$matrix3) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
- my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
-
- if (($rows1 == $rows2) && ($rows1 == $rows3) &&
- ($cols1 == $cols2) && ($cols1 == $cols3))
- {
- $matrix1->[0]->Union($matrix2->[0],$matrix3->[0]);
- }
- else
- {
- croak "Math::MatrixBool::Union(): matrix size mismatch";
- }
- }
-
- sub Intersection
- {
- croak "Usage: \$matrix1->Intersection(\$matrix2,\$matrix3);"
- if (@_ != 3);
-
- my($matrix1,$matrix2,$matrix3) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
- my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
-
- if (($rows1 == $rows2) && ($rows1 == $rows3) &&
- ($cols1 == $cols2) && ($cols1 == $cols3))
- {
- $matrix1->[0]->Intersection($matrix2->[0],$matrix3->[0]);
- }
- else
- {
- croak "Math::MatrixBool::Intersection(): matrix size mismatch";
- }
- }
-
- sub Difference
- {
- croak "Usage: \$matrix1->Difference(\$matrix2,\$matrix3);"
- if (@_ != 3);
-
- my($matrix1,$matrix2,$matrix3) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
- my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
-
- if (($rows1 == $rows2) && ($rows1 == $rows3) &&
- ($cols1 == $cols2) && ($cols1 == $cols3))
- {
- $matrix1->[0]->Difference($matrix2->[0],$matrix3->[0]);
- }
- else
- {
- croak "Math::MatrixBool::Difference(): matrix size mismatch";
- }
- }
-
- sub ExclusiveOr
- {
- croak "Usage: \$matrix1->ExclusiveOr(\$matrix2,\$matrix3);"
- if (@_ != 3);
-
- my($matrix1,$matrix2,$matrix3) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
- my($rows3,$cols3) = ($matrix3->[1],$matrix3->[2]);
-
- if (($rows1 == $rows2) && ($rows1 == $rows3) &&
- ($cols1 == $cols2) && ($cols1 == $cols3))
- {
- $matrix1->[0]->ExclusiveOr($matrix2->[0],$matrix3->[0]);
- }
- else
- {
- croak "Math::MatrixBool::ExclusiveOr(): matrix size mismatch";
- }
- }
-
- sub Complement
- {
- croak "Usage: \$matrix1->Complement(\$matrix2);"
- if (@_ != 2);
-
- my($matrix1,$matrix2) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
-
- if (($rows1 == $rows2) && ($cols1 == $cols2))
- {
- $matrix1->[0]->Complement($matrix2->[0]);
- }
- else
- {
- croak "Math::MatrixBool::Complement(): matrix size mismatch";
- }
- }
-
- sub equal
- {
- croak "Usage: \$boolean = \$matrix1->equal(\$matrix2);"
- if (@_ != 2);
-
- my($matrix1,$matrix2) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
-
- if (($rows1 == $rows2) && ($cols1 == $cols2))
- {
- return( $matrix1->[0]->equal($matrix2->[0]) );
- }
- else
- {
- croak "Math::MatrixBool::equal(): matrix size mismatch";
- }
- }
-
- sub subset
- {
- croak "Usage: \$boolean = \$matrix1->subset(\$matrix2);"
- if (@_ != 2);
-
- my($matrix1,$matrix2) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
-
- if (($rows1 == $rows2) && ($cols1 == $cols2))
- {
- return( $matrix1->[0]->subset($matrix2->[0]) );
- }
- else
- {
- croak "Math::MatrixBool::subset(): matrix size mismatch";
- }
- }
-
- sub inclusion
- {
- return( subset(@_) );
- }
-
- sub lexorder
- {
- croak "Usage: \$boolean = \$matrix1->lexorder(\$matrix2);"
- if (@_ != 2);
-
- my($matrix1,$matrix2) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
-
- if (($rows1 == $rows2) && ($cols1 == $cols2))
- {
- return( $matrix1->[0]->lexorder($matrix2->[0]) );
- }
- else
- {
- croak "Math::MatrixBool::lexorder(): matrix size mismatch";
- }
- }
-
- sub Compare
- {
- croak "Usage: \$result = \$matrix1->Compare(\$matrix2);"
- if (@_ != 2);
-
- my($matrix1,$matrix2) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
-
- if (($rows1 == $rows2) && ($cols1 == $cols2))
- {
- return( $matrix1->[0]->Compare($matrix2->[0]) );
- }
- else
- {
- croak "Math::MatrixBool::Compare(): matrix size mismatch";
- }
- }
-
- sub Copy
- {
- croak "Usage: \$matrix1->Copy(\$matrix2);"
- if (@_ != 2);
-
- my($matrix1,$matrix2) = @_;
- my($rows1,$cols1) = ($matrix1->[1],$matrix1->[2]);
- my($rows2,$cols2) = ($matrix2->[1],$matrix2->[2]);
-
- if (($rows1 == $rows2) && ($cols1 == $cols2))
- {
- $matrix1->[0]->Copy($matrix2->[0]);
- }
- else
- {
- croak "Math::MatrixBool::Copy(): matrix size mismatch";
- }
- }
-
- sub Shadow
- {
- croak "Usage: \$other_matrix = \$some_matrix->Shadow();"
- if (@_ != 1);
-
- my($matrix) = @_;
- my($result);
-
- $result = $matrix->new($matrix->[1],$matrix->[2]);
- return($result);
- }
-
- sub Clone
- {
- croak "Usage: \$twin_matrix = \$some_matrix->Clone();"
- if (@_ != 1);
-
- my($matrix) = @_;
- my($result);
-
- $result = $matrix->new($matrix->[1],$matrix->[2]);
- $result->Copy($matrix);
- return($result);
- }
-
- ########################################
- # #
- # define overloaded operators section: #
- # #
- ########################################
-
- sub _complement
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'~'"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- $result = $object->new($object->[1],$object->[2]);
- $result->Complement($object);
- return($result);
- }
-
- sub _boolean
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "bool"; #&_trace($name,$object,$argument,$flag);
-
- return( $object->[0]->Min() < $object->[1] * $object->[2] );
- }
-
- sub _not_boolean
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'!'"; #&_trace($name,$object,$argument,$flag);
-
- return( !($object->[0]->Min() < $object->[1] * $object->[2]) );
- }
-
- sub _string
- {
- my($object,$argument,$flag) = @_;
- # my($name) = '""'; #&_trace($name,$object,$argument,$flag);
- my($rows,$cols) = ($object->[1],$object->[2]);
- my($i,$j,$s);
-
- $s = '';
- for ( $i = 1; $i <= $rows; $i++ )
- {
- $s .= "[ ";
- for ( $j = 1; $j <= $cols; $j++ )
- {
- if ($object->bit_test($i,$j)) { $s .= "1 "; } else { $s .= "0 "; }
- }
- $s .= "]\n";
- }
- return($s);
- }
-
- sub _number_of_elements
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "abs"; #&_trace($name,$object,$argument,$flag);
-
- return( $object->Number_of_elements() );
- }
-
- sub _addition
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'+'"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if (defined $flag)
- {
- $result = $object->new($object->[1],$object->[2]);
- $result->ExclusiveOr($object,$argument);
- return($result);
- }
- else
- {
- $object->ExclusiveOr($object,$argument);
- return($object);
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _multiplication
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'*'"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if ((defined $flag) && $flag)
- {
- return( Multiplication($argument,$object) );
- }
- else
- {
- return( Multiplication($object,$argument) );
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _union
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'|'"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if (defined $flag)
- {
- $result = $object->new($object->[1],$object->[2]);
- $result->Union($object,$argument);
- return($result);
- }
- else
- {
- $object->Union($object,$argument);
- return($object);
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _difference
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'-'"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if (defined $flag)
- {
- $result = $object->new($object->[1],$object->[2]);
- if ($flag) { $result->Difference($argument,$object); }
- else { $result->Difference($object,$argument); }
- return($result);
- }
- else
- {
- $object->Difference($object,$argument);
- return($object);
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _intersection
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'&'"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if (defined $flag)
- {
- $result = $object->new($object->[1],$object->[2]);
- $result->Intersection($object,$argument);
- return($result);
- }
- else
- {
- $object->Intersection($object,$argument);
- return($object);
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _exclusive_or
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'^'"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if (defined $flag)
- {
- $result = $object->new($object->[1],$object->[2]);
- $result->ExclusiveOr($object,$argument);
- return($result);
- }
- else
- {
- $object->ExclusiveOr($object,$argument);
- return($object);
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _assign_addition
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'+='"; #&_trace($name,$object,$argument,$flag);
-
- return( &_addition($object,$argument,undef) );
- }
-
- sub _assign_multiplication
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'*='"; #&_trace($name,$object,$argument,$flag);
-
- return( &_multiplication($object,$argument,undef) );
- }
-
- sub _assign_union
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'|='"; #&_trace($name,$object,$argument,$flag);
-
- return( &_union($object,$argument,undef) );
- }
-
- sub _assign_difference
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'-='"; #&_trace($name,$object,$argument,$flag);
-
- return( &_difference($object,$argument,undef) );
- }
-
- sub _assign_intersection
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'&='"; #&_trace($name,$object,$argument,$flag);
-
- return( &_intersection($object,$argument,undef) );
- }
-
- sub _assign_exclusive_or
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'^='"; #&_trace($name,$object,$argument,$flag);
-
- return( &_exclusive_or($object,$argument,undef) );
- }
-
- sub _equal
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'=='"; #&_trace($name,$object,$argument,$flag);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- return( $object->equal($argument) );
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _not_equal
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'!='"; #&_trace($name,$object,$argument,$flag);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- return( !($object->equal($argument)) );
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _true_sub_set
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'<'"; #&_trace($name,$object,$argument,$flag);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if ((defined $flag) && $flag)
- {
- return( !($argument->equal($object)) &&
- ($argument->subset($object)) );
- }
- else
- {
- return( !($object->equal($argument)) &&
- ($object->subset($argument)) );
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _sub_set
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'<='"; #&_trace($name,$object,$argument,$flag);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if ((defined $flag) && $flag)
- {
- return( $argument->subset($object) );
- }
- else
- {
- return( $object->subset($argument) );
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _true_super_set
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'>'"; #&_trace($name,$object,$argument,$flag);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if ((defined $flag) && $flag)
- {
- return( !($object->equal($argument)) &&
- ($object->subset($argument)) );
- }
- else
- {
- return( !($argument->equal($object)) &&
- ($argument->subset($object)) );
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _super_set
- {
- my($object,$argument,$flag) = @_;
- my($name) = "'>='"; #&_trace($name,$object,$argument,$flag);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if ((defined $flag) && $flag)
- {
- return( $object->subset($argument) );
- }
- else
- {
- return( $argument->subset($object) );
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _compare
- {
- my($object,$argument,$flag) = @_;
- my($name) = "cmp"; #&_trace($name,$object,$argument,$flag);
-
- if ((defined $argument) && ref($argument) &&
- (ref($argument) !~ /^SCALAR$|^ARRAY$|^HASH$|^CODE$|^REF$/))
- {
- if ((defined $flag) && $flag)
- {
- return( $argument->Compare($object) );
- }
- else
- {
- return( $object->Compare($argument) );
- }
- }
- else
- {
- croak "Math::MatrixBool $name: wrong argument type";
- }
- }
-
- sub _clone
- {
- my($object,$argument,$flag) = @_;
- # my($name) = "'='"; #&_trace($name,$object,$argument,$flag);
- my($result);
-
- $result = $object->new($object->[1],$object->[2]);
- $result->Copy($object);
- return($result);
- }
-
- sub _trace
- {
- my($text,$object,$argument,$flag) = @_;
-
- unless (defined $object) { $object = 'undef'; };
- unless (defined $argument) { $argument = 'undef'; };
- unless (defined $flag) { $flag = 'undef'; };
- if (ref($object)) { $object = ref($object); }
- if (ref($argument)) { $argument = ref($argument); }
- print "$text: \$obj='$object' \$arg='$argument' \$flag='$flag'\n";
- }
-
- 1;
-
- __END__
-
- =head1 NAME
-
- Math::MatrixBool - Matrix of Booleans
-
- Easy manipulation of matrices of booleans (Boolean Algebra)
-
- =head1 SYNOPSIS
-
- =over 4
-
- =item *
-
- C<use Math::MatrixBool;>
-
- =item *
-
- C<$new_matrix = new Math::MatrixBool($rows,$columns);>
-
- the matrix object constructor method
-
- An exception is raised if the necessary memory cannot be allocated.
-
- =item *
-
- C<$new_matrix = Math::MatrixBool-E<gt>new($rows,$columns);>
-
- alternate way of calling the matrix object constructor method
-
- =item *
-
- C<$new_matrix = $some_matrix-E<gt>>C<new($rows,$columns);>
-
- still another way of calling the matrix object constructor method
- ($some_matrix is not affected by this)
-
- =item *
-
- C<$new_matrix = Math::MatrixBool-E<gt>>C<new_from_string($string);>
-
- This method allows you to read in a matrix from a string (for
- instance, from the keyboard, from a file or from your code).
-
- The syntax is simple: each row must start with "C<[ >" and end with
- "C< ]\n>" ("C<\n>" being the newline character and "C< >" a space or
- tab) and contain one or more numbers, all separated from each other
- by spaces or tabs.
-
- Additional spaces or tabs can be added at will, but no comments.
-
- Numbers are either "0" or "1".
-
- Examples:
-
- $string = "[ 1 0 0 ]\n[ 1 1 0 ]\n[ 1 1 1 ]\n";
- $matrix = Math::MatrixBool->new_from_string($string);
- print "$matrix";
-
- By the way, this prints
-
- [ 1 0 0 ]
- [ 1 1 0 ]
- [ 1 1 1 ]
-
- But you can also do this in a much more comfortable way using the
- shell-like "here-document" syntax:
-
- $matrix = Math::MatrixBool->new_from_string(<<'MATRIX');
- [ 1 0 0 0 0 0 1 ]
- [ 0 1 0 0 0 0 0 ]
- [ 0 0 1 0 0 0 0 ]
- [ 0 0 0 1 0 0 0 ]
- [ 0 0 0 0 1 0 0 ]
- [ 0 0 0 0 0 1 0 ]
- [ 1 0 0 0 0 0 1 ]
- MATRIX
-
- You can even use variables in the matrix:
-
- $c1 = $A1 * $x1 - $b1 >= 0 ?"1":"0";
- $c1 = $A2 * $x2 - $b2 >= 0 ?"1":"0";
- $c1 = $A3 * $x3 - $b3 >= 0 ?"1":"0";
-
- $matrix = Math::MatrixBool->new_from_string(<<"MATRIX");
-
- [ 1 0 0 ]
- [ 0 1 0 ]
- [ $c1 $c2 $c3 ]
-
- MATRIX
-
- (Remember that you may use spaces and tabs to format the matrix to
- your taste)
-
- Note that this method uses exactly the same representation for a
- matrix as the "stringify" operator "": this means that you can convert
- any matrix into a string with C<$string = "$matrix";> and read it back
- in later (for instance from a file!).
-
- If the string you supply (or someone else supplies) does not obey
- the syntax mentioned above, an exception is raised, which can be
- caught by "eval" as follows:
-
- print "Please enter your matrix (in one line): ";
- $string = <STDIN>;
- $string =~ s/\\n/\n/g;
- eval { $matrix = Math::MatrixBool->new_from_string($string); };
- if ($@)
- {
- print "$@";
- # ...
- # (error handling)
- }
- else
- {
- # continue...
- }
-
- or as follows:
-
- eval { $matrix = Math::MatrixBool->new_from_string(<<"MATRIX"); };
- [ 1 0 0 ]
- [ 0 1 0 ]
- [ $c1 $c2 $c3 ]
- MATRIX
- if ($@)
- # ...
-
- Actually, the method shown above for reading a matrix from the keyboard
- is a little awkward, since you have to enter a lot of "\n"'s for the
- newlines.
-
- A better way is shown in this piece of code:
-
- while (1)
- {
- print "\nPlease enter your matrix ";
- print "(multiple lines, <ctrl-D> = done):\n";
- eval { $new_matrix =
- Math::MatrixBool->new_from_string(join('',<STDIN>)); };
- if ($@)
- {
- $@ =~ s/\s+at\b.*?$//;
- print "${@}Please try again.\n";
- }
- else { last; }
- }
-
- Possible error messages of the "new_from_string()" method are:
-
- Math::MatrixBool::new_from_string(): syntax error in input string
- Math::MatrixBool::new_from_string(): empty input string
-
- If the input string has rows with varying numbers of columns,
- the following warning will be printed to STDERR:
-
- Math::MatrixBool::new_from_string(): missing elements will be set to zero!
-
- If everything is okay, the method returns an object reference to the
- (newly allocated) matrix containing the elements you specified.
-
- =item *
-
- C<($rows,$columns) = $matrix-E<gt>Dim();>
-
- returns the dimensions (= number of rows and columns) of the given matrix
-
- =item *
-
- C<$matrix-E<gt>Empty();>
-
- sets all elements in the matrix to "0"
-
- =item *
-
- C<$matrix-E<gt>Fill();>
-
- sets all elements in the matrix to "1"
-
- =item *
-
- C<$matrix-E<gt>Flip();>
-
- flips (i.e., complements) all elements in the given matrix
-
- =item *
-
- C<$matrix-E<gt>Zero();>
-
- sets all elements in the matrix to "0"
-
- =item *
-
- C<$matrix-E<gt>One();>
-
- fills the matrix with one's in the main diagonal and zero's elsewhere
-
- Note that multiplying this matrix with itself yields the same matrix again
- (provided it is quadratic)!
-
- =item *
-
- C<$matrix-E<gt>Bit_On($row,$column);>
-
- sets a given element to "1"
-
- =item *
-
- C<$matrix-E<gt>Insert($row,$column);>
-
- alias for "Bit_On()", deprecated
-
- =item *
-
- C<$matrix-E<gt>Bit_Off($row,$column);>
-
- sets a given element to "0"
-
- =item *
-
- C<$matrix-E<gt>Delete($row,$column);>
-
- alias for "Bit_Off()", deprecated
-
- =item *
-
- C<$boolean = $matrix-E<gt>>C<bit_flip($row,$column);>
-
- flips (i.e., complements) a given element and returns its new value
-
- =item *
-
- C<$boolean = $matrix-E<gt>>C<flip($row,$column);>
-
- alias for "bit_flip()", deprecated
-
- =item *
-
- C<$boolean = $matrix-E<gt>>C<bit_test($row,$column);>
-
- tests wether a given element is set
-
- =item *
-
- C<$boolean = $matrix-E<gt>>C<contains($row,$column);>
-
- tests wether a given element is set (alias for "bit_test()")
-
- =item *
-
- C<$boolean = $matrix-E<gt>>C<in($row,$column);>
-
- alias for "bit_test()", deprecated
-
- =item *
-
- C<$elements = $matrix-E<gt>Number_of_elements();>
-
- calculates the number of elements contained in the given matrix
-
- =item *
-
- C<$norm_max = $matrix-E<gt>Norm_max();>
-
- calculates the "maximum"-norm of the given matrix
-
- =item *
-
- C<$norm_one = $matrix-E<gt>Norm_one();>
-
- calculates the "1"-norm of the given matrix
-
- =item *
-
- C<$matrix1-E<gt>Addition($matrix2,$matrix3);>
-
- calculates the sum of matrix2 and matrix3 and stores the result in matrix1
- (in-place is also possible)
-
- =item *
-
- C<$product_matrix = $matrix1-E<gt>Multiplication($matrix2);>
-
- calculates the product of matrix1 and matrix2 and returns an object reference
- to a new matrix where the result is stored
-
- =item *
-
- C<$closure = $matrix-E<gt>Kleene();>
-
- computes the reflexive transitive closure of the given matrix and returns
- a new matrix containing the result. (The original matrix is not changed by
- this in any way!)
-
- Uses a variant of Kleene's algorithm. See L<Math::Kleene(3)> for more details
- about this algorithm!
-
- This algorithm is mainly used in graph theory: Each position in the matrix
- corresponds to a (directed!) possible connection ("edge") between two points
- ("vortices") of a graph. Each position in the matrix contains a "1" if the
- corresponding edge is part of the graph and a "0" if not.
-
- Computing the closure of this matrix means to find out if there is a path
- from any vortice of the graph to any other (a path consisting of one or more
- edges).
-
- Note that there are more applications of Kleene's algorithm in other fields
- as well (see also Math::MatrixReal(3), DFA::Kleene(3), Math::Kleene(3)).
-
- =item *
-
- C<$matrix1-E<gt>Union($matrix2,$matrix3);>
-
- calculates the union of matrix2 and matrix3 and stores the result in matrix1
- (in-place is also possible)
-
- =item *
-
- C<$matrix1-E<gt>Intersection($matrix2,$matrix3);>
-
- calculates the intersection of matrix2 and matrix3 and stores the result in
- matrix1 (in-place is also possible)
-
- =item *
-
- C<$matrix1-E<gt>Difference($matrix2,$matrix3);>
-
- calculates matrix2 "minus" matrix3 ( = matrix2 \ matrix3 ) and stores the
- result in matrix1 (in-place is also possible)
-
- Note that this is set difference, not matrix difference! Matrix difference
- degenerates to (= is the same as) matrix addition in a Boolean Algebra!!
-
- =item *
-
- C<$matrix1-E<gt>ExclusiveOr($matrix2,$matrix3);>
-
- calculates the exclusive-or (which in the case of a Boolean Algebra happens
- to be the same as the addition) of matrix2 and matrix3 and stores the
- result in matrix1 (in-place is also possible)
-
- =item *
-
- C<$matrix1-E<gt>Complement($matrix2);>
-
- calculates the complement of matrix2 and stores the result in matrix1
- (in-place is also possible)
-
- =item *
-
- C<$boolean = $matrix1-E<gt>equal($matrix2);>
-
- tests if matrix1 is the same as matrix2
-
- =item *
-
- C<$boolean = $matrix1-E<gt>subset($matrix2);>
-
- tests if matrix1 is a subset of matrix2
-
- =item *
-
- C<$boolean = $matrix1-E<gt>inclusion($matrix2);>
-
- alias for "subset()", deprecated
-
- =item *
-
- C<$boolean = $matrix1-E<gt>lexorder($matrix2);>
-
- tests if matrix1 comes lexically before matrix2, i.e., if (matrix1 <= matrix2)
- holds, as though the two bit vectors used to represent the two matrices were
- two large numbers in binary representation
-
- (Note that this is an B<arbitrary> order relationship!)
-
- =item *
-
- C<$result = $matrix1-E<gt>Compare($matrix2);>
-
- lexically compares matrix1 and matrix2 and returns -1, 0 or 1 if
- (matrix1 < matrix2), (matrix1 == matrix2) or (matrix1 > matrix2) holds,
- respectively
-
- (Again, the two bit vectors representing the two matrices are compared as
- though they were two large numbers in binary representation)
-
- =item *
-
- C<$matrix1-E<gt>Copy($matrix2);>
-
- copies the contents of matrix2 to an B<ALREADY EXISTING> matrix1
-
- =item *
-
- C<$new_matrix = $some_matrix-E<gt>Shadow();>
-
- returns an object reference to a B<NEW> but B<EMPTY> matrix of
- the B<SAME SIZE> as some_matrix
-
- =item *
-
- C<$twin_matrix = $some_matrix-E<gt>Clone();>
-
- returns an object reference to a B<NEW> matrix of the B<SAME SIZE> as
- some_matrix; the contents of some_matrix have B<ALREADY BEEN COPIED>
- to the new matrix
-
- =item *
-
- B<Hint: method names all in lower case indicate a boolean return value!>
-
- (Except for "C<new()>" and "C<new_from_string()>", of course!)
-
- =back
-
- Please refer to L<"OVERLOADED OPERATORS"> below for ways of using
- overloaded operators instead of explicit method calls in order to
- facilitate calculations with matrices!
-
- =head1 DESCRIPTION
-
- This class lets you dynamically create boolean matrices of arbitrary
- size and perform all the basic operations for matrices on them, like
-
- =over 4
-
- =item -
-
- setting or deleting elements,
-
- =item -
-
- testing wether a certain element is set,
-
- =item -
-
- computing the sum, difference, product, closure and complement of matrices,
-
- (you can also compute the union, intersection, difference and exclusive-or
- of the underlying bit vector)
-
- =item -
-
- copying matrices,
-
- =item -
-
- testing two matrices for equality or inclusion (subset relationship), and
-
- =item -
-
- computing the number of elements and the norm of a matrix.
-
- =back
-
- Please refer to L<"OVERLOADED OPERATORS"> below for ways of using
- overloaded operators instead of explicit method calls in order to
- facilitate calculations with matrices!
-
- =head1 OVERLOADED OPERATORS
-
- Calculations with matrices can not only be performed with explicit method
- calls using this module, but also through "magical" overloaded arithmetic
- and relational operators.
-
- For instance, instead of writing
-
- $matrix1 = Math::MatrixBool->new($rows,$columns);
- $matrix2 = Math::MatrixBool->new($rows,$columns);
- $matrix3 = Math::MatrixBool->new($rows,$columns);
-
- [...]
-
- $matrix3->Multiplication($matrix1,$matrix2);
-
- you can just say
-
- $matrix1 = Math::MatrixBool->new($rows,$columns);
- $matrix2 = Math::MatrixBool->new($rows,$columns);
-
- [...]
-
- $matrix3 = $matrix1 * $matrix2;
-
- That's all!
-
- Here is the list of all "magical" overloaded operators and their
- semantics (meaning):
-
- Unary operators: '-', '~', 'abs', testing, '!', '""'
-
- Binary (arithmetic) operators: '+', '*', '|', '-', '&', '^'
-
- Binary (relational) operators: '==', '!=', '<', '<=', '>', '>='
-
- Binary (relational) operators: 'cmp', 'eq', 'ne', 'lt', 'le', 'gt', 'ge'
-
- Note that both arguments to a binary operator from the list above must
- be matrices; numbers or other types of data are not permitted as arguments
- and will produce an error message.
-
- =over 5
-
- =item '-'
-
- Unary Minus ( C<$matrix2 = -$matrix1;> )
-
- Same as "Complement". See "Complement" below.
-
- =item '~'
-
- Complement ( C<$matrix2 = ~$matrix1;> )
-
- The operator '~' (or unary '-') computes the complement of the given matrix.
-
- =item abs
-
- Absolute Value ( C<$no_of_elem = abs($matrix);> )
-
- Here, the absolute value of a matrix has been defined as the number
- of elements the given matrix contains. This is B<NOT> the same as the
- "norm" of a matrix!
-
- =item test
-
- Boolean Test ( C<if ($matrix) { ... }> )
-
- You can actually test a matrix as though it were a boolean value.
-
- No special operator is needed for this; Perl automatically calls the
- appropriate method in this package if "$matrix" is a blessed reference
- to an object of the "Math::MatrixBool" class or one of its derived
- classes.
-
- This operation returns "true" (1) if the given matrix is not empty and
- "false" ('') otherwise.
-
- =item '!'
-
- Negated Boolean Test ( C<if (! $matrix) { ... }> )
-
- You can also perform a negated test on a matrix as though it were a boolean
- value. For example:
-
- if (! $matrix) { ... }
-
- unless ($matrix) { ... } # internally, same as above!
-
- This operation returns "true" (1) if the given matrix is empty and "false"
- ('') otherwise.
-
- =item '""""'
-
- "Stringification" ( C<print "$matrix";> )
-
- It is possible to get a string representation of a given matrix by just
- putting the matrix object reference between double quotes.
-
- Note that in general the string representation of a matrix will span over
- multiple lines (i.e., the string which is generated contains "\n" characters,
- one at the end of each row of the matrix).
-
- Example:
-
- $matrix = new Math::MatrixBool(5,6);
- $matrix->One();
- print "$matrix";
-
- This will print:
-
- [ 1 0 0 0 0 0 ]
- [ 0 1 0 0 0 0 ]
- [ 0 0 1 0 0 0 ]
- [ 0 0 0 1 0 0 ]
- [ 0 0 0 0 1 0 ]
-
- =item '+'
-
- Addition ( C<$matrix3 = $matrix1 + $matrix2;> )
-
- The '+' operator calculates the sum of two matrices.
-
- Examples:
-
- $all = $odd + $even;
-
- $all += $odd;
- $all += $even;
-
- Note that the '++' operator will produce an error message if applied
- to an object of this class because adding a number to a matrix makes
- no sense.
-
- =item '*'
-
- Multiplication ( C<$matrix3 = $matrix1 * $matrix2;> )
-
- The '*' operator calculates the matrix product of two matrices.
-
- Examples:
-
- $test = $one * $one;
-
- $test *= $one;
- $test *= $test;
-
- Note that you can use matrices of any size as long as their numbers of
- rows and columns correspond in the following way (example):
-
- $matrix_3 = $matrix_1 * $matrix_2;
-
- [ 2 2 ]
- [ 2 2 ]
- [ 2 2 ]
-
- [ 1 1 1 ] [ 3 3 ]
- [ 1 1 1 ] [ 3 3 ]
- [ 1 1 1 ] [ 3 3 ]
- [ 1 1 1 ] [ 3 3 ]
-
- I.e., the number of columns of matrix #1 is the same as the number of
- rows of matrix #2, and the number of rows and columns of the resulting
- matrix #3 is determined by the number of rows of matrix #1 and the
- number of columns of matrix #2, respectively.
-
- This way you can also perform the multiplication of a matrix with a
- vector, since a vector is just a degenerated matrix with several rows
- but only one column, or just one row and several columns.
-
- =item '|'
-
- Union ( C<$matrix3 = $matrix1 | $matrix2;> )
-
- The '|' operator is used to calculate the union of two matrices
- (of corresponding elements).
-
- Examples:
-
- $all = $odd | $even;
-
- $all |= $odd;
- $all |= $even;
-
- =item '-'
-
- Difference ( C<$matrix3 = $matrix1 - $matrix2;> )
-
- The operator '-' calculates the (dotted) difference of two matrices, i.e.,
-
- 0 - 0 == 0
- 0 - 1 == 0
- 1 - 0 == 1
- 1 - 1 == 0
-
- for each corresponding element.
-
- Examples:
-
- $odd = $all - $even;
-
- $all -= $even;
-
- Note that the '--' operator will produce an error message if applied
- to an object of this class because subtracting a number from a matrix
- makes no sense.
-
- =item '&'
-
- Intersection ( C<$matrix3 = $matrix1 & $matrix2;> )
-
- The '&' operator is used to calculate the intersection of two matrices
- (of the corresponding elements).
-
- Examples:
-
- $rest = $all & $even;
-
- $all &= $even;
-
- =item '^'
-
- ExclusiveOr ( C<$matrix3 = $matrix1 ^ $matrix2;> )
-
- The '^' operator is used to calculate the exclusive-or of two matrices
- (of their corresponding elements).
-
- In fact this operation is identical with the addition of two matrices
- in this case of a Boolean Algebra.
-
- Examples:
-
- $odd = $all ^ $even;
-
- $all ^= $even;
-
- =item '=='
-
- Test For Equality ( C<if ($matrix1 == $matrix2) { ... }> )
-
- This operator tests two matrices for equality.
-
- Note that B<without> operator overloading, C<( $matrix1 == $matrix2 )> would
- test wether the two references B<pointed to> the B<same object>! (!)
-
- B<With> operator overloading in effect, C<( $matrix1 == $matrix2 )> tests
- wether the two matrix objects B<contain> exactly the B<same elements>!
-
- =item '!='
-
- Test For Non-Equality ( C<if ($matrix1 != $matrix2) { ... }> )
-
- This operator tests wether two matrices are different.
-
- Note again that this tests wether the B<contents> of the two matrices are
- not the same, and B<not> wether the two B<references> are different!
-
- =item 'E<lt>'
-
- Test For True Subset ( C<if ($matrix1 E<lt> $matrix2) { ... }> )
-
- This operator tests wether $matrix1 is a true subset of $matrix2, i.e.
- wether the elements contained in $matrix1 are also contained in $matrix2,
- but not all elements contained in $matrix2 are contained in $matrix1.
-
- Example:
-
- [ 1 0 0 0 0 ] [ 1 0 0 0 1 ]
- [ 0 1 0 0 0 ] [ 0 1 0 0 0 ]
- [ 0 0 1 0 0 ] is a true subset of [ 0 0 1 0 0 ]
- [ 0 0 0 1 0 ] [ 0 0 0 1 0 ]
- [ 1 0 0 0 1 ] [ 1 0 0 0 1 ]
-
- [ 1 0 0 0 0 ] [ 1 0 0 0 1 ]
- [ 0 1 0 0 0 ] [ 0 1 0 0 0 ]
- but [ 0 0 1 0 0 ] is not a subset of [ 0 0 1 0 0 ]
- [ 0 0 0 1 0 ] [ 0 0 0 1 0 ]
- [ 1 0 0 0 1 ] [ 0 0 0 0 1 ]
-
- (nor vice-versa!)
-
- [ 1 0 0 0 1 ] [ 1 0 0 0 1 ]
- [ 0 1 0 0 0 ] [ 0 1 0 0 0 ]
- and [ 0 0 1 0 0 ] is a subset of [ 0 0 1 0 0 ]
- [ 0 0 0 1 0 ] [ 0 0 0 1 0 ]
- [ 1 0 0 0 1 ] [ 1 0 0 0 1 ]
-
- but not a true subset because the two matrices are identical.
-
- =item 'E<lt>='
-
- Test For Subset ( C<if ($matrix1 E<lt>= $matrix2) { ... }> )
-
- This operator tests wether $matrix1 is a subset of $matrix2, i.e.
- wether all elements contained in $matrix1 are also contained in $matrix2.
-
- This also evaluates to "true" when the two matrices are the same.
-
- =item 'E<gt>'
-
- Test For True Superset ( C<if ($matrix1 E<gt> $matrix2) { ... }> )
-
- This operator tests wether $matrix1 is a true superset of $matrix2, i.e.
- wether all elements contained in $matrix2 are also contained in $matrix1,
- but not all elements contained in $matrix1 are contained in $matrix2.
-
- Note that C<($matrix1 E<gt> $matrix2)> is exactly the same as
- C<($matrix2 E<lt> $matrix1)>.
-
- =item 'E<gt>='
-
- Test For Superset ( C<if ($matrix1 E<gt>= $matrix2) { ... }> )
-
- This operator tests wether $matrix1 is a superset of $matrix2, i.e.
- wether all elements contained in $matrix2 are also contained in $matrix1.
-
- This also evaluates to "true" when the two matrices are equal.
-
- Note that C<($matrix1 E<gt>= $matrix2)> is exactly the same as
- C<($matrix2 E<lt>= $matrix1)>.
-
- =item cmp
-
- Compare ( C<$result = $matrix1 cmp $matrix2;> )
-
- This operator compares the two matrices lexically, i.e. it regards the
- two bit vectors representing the two matrices as two large (unsigned)
- numbers in binary representation and returns "-1" if the number for
- $matrix1 is smaller than that for $matrix2, "0" if the two numbers are
- the same (i.e., when the two matrices are equal!) or "1" if the number
- representing $matrix1 is larger than the number representing $matrix2.
-
- Note that this comparison has nothing to do whatsoever with algebra,
- it is just an B<arbitrary> order relationship!
-
- It is only intended to provide an (arbitrary) order by which (for example)
- an array of matrices can be sorted, for instance to find out quickly (using
- binary search) if a specific matrix has already been produced before in some
- matrix-producing process or not.
-
- =item eq
-
- "equal"
-
- =item ne
-
- "not equal"
-
- =item lt
-
- "less than"
-
- =item le
-
- "less than or equal"
-
- =item gt
-
- "greater than"
-
- =item ge
-
- "greater than or equal"
-
- These are all operators derived from the "cmp" operator (see above).
-
- They can be used instead of the "cmp" operator to make the intended
- type of comparison more obvious in your code.
-
- For instance, C<($matrix1 le $matrix2)> is much more readable and clearer
- than C<(($matrix1 cmp $matrix2) E<lt>= 0)>!
-
- =back
-
- =head1 SEE ALSO
-
- Bit::Vector(3), Math::MatrixReal(3), DFA::Kleene(3),
- Math::Kleene(3), Set::IntegerFast(3), Set::IntegerRange(3).
-
- =head1 VERSION
-
- This man page documents "Math::MatrixBool" version 4.1.
-
- =head1 AUTHOR
-
- Steffen Beyer <sb@sdm.de>.
-
- =head1 COPYRIGHT
-
- Copyright (c) 1996, 1997 by Steffen Beyer. All rights reserved.
-
- =head1 LICENSE AGREEMENT
-
- This package is free software; you can redistribute it and/or
- modify it under the same terms as Perl itself.
-
-