Suppose my @G is a 5x5 matrix of all 0s.
Okay, if you are going to use a fixed-length matrix, then you could use a string and pretend that the bits in the string are the individual elements in the arrays. Use vec() to manipulate the string. The advantage of this is that creating a string will take less memory than creating an array. Also, you will be able to return the 2D matrix from the function call, because it's a simple string.
Here is an example: $a and $b are going to be the pointers in the matrix. So, instead of doing
my $VALUE = $MyMatrix[$a][$b];
you are going to do this instead:
my $VALUE = (vec($MyMatrix, ($a & 7), 8) >> $b) & 1;
Here we are assuming that your matrix has 8 elements in each row, since there are 8 bits in a byte. You can also use vec() to overwrite individual bits in the matrix. I'd write a sub that either reads from or writes to the matrix. That way you don't have to write all these calculations every time you want to address the various elements in the matrix. Your 5x5 matrix would take up 5 bytes of space in memory. So, this would be the 2D "array" that your function would return. It would be a string.
Here is a working example:
#!/usr/bin/perl -w
use strict;
use warnings;
my $i;
my $j;
# Create our test matrix
my $MyMatrix = NewMatrix();
# Shows that all matrix values are initially ZERO.
DisplayMatrix();
# Set all matrix values to ONE.
for ($i = 0; $i < 5; $i++)
{
for ($j = 0; $j < 5; $j++)
{
$MyMatrix = SetMatrixValue($MyMatrix, $i, $j, 1);
}
}
DisplayMatrix();
# Clear somes random values...
$MyMatrix = SetMatrixValue($MyMatrix, 1, 4, 0);
$MyMatrix = SetMatrixValue($MyMatrix, 2, 0, 0);
$MyMatrix = SetMatrixValue($MyMatrix, 2, 3, 0);
DisplayMatrix();
# Flip bits from zero to one and one to zero.
$MyMatrix = NOT_Matrix($MyMatrix);
DisplayMatrix();
exit;
#
# This function reads a bit from the 5x5 matrix.
# Returns either 1 or 0.
# Usage: GetMatrixValue(MATRIX_STRING, X_POS, Y_POS)
#
sub GetMatrixValue
{
my $MATRIX = GetMatrixStr(shift);
my $X = (shift) & 7;
my $Y = (shift) & 7;
# Make sure the pointers are within the right range.
$X <= 4 or $X = 4;
$Y <= 4 or $Y = 4;
return (vec($MATRIX, $Y, 8) >> $X) & 1;
}
#
# This function changes a bit in the 5x5 matrix string.
# Returns the new matrix string.
# Usage: NEW_MATRIX_STRING = SetMatrixValue(MATRIX_STRING, X_POS, Y_PO
+S, NEW_VALUE)
#
sub SetMatrixValue
{
my $MATRIX = GetMatrixStr(shift);
my $X = (shift) & 7;
my $Y = (shift) & 7;
my $NEW_VALUE = (shift) & 1;
# Make sure the pointers are within the right range.
$X <= 4 or $X = 4;
$Y <= 4 or $Y = 4;
vec($MATRIX, ($Y << 3) + $X, 1) = $NEW_VALUE;
return $MATRIX;
}
#
# This function makes sure that the matrix
# string is exactly 5 bytes long.
# Usage: MATRIX_STRING = GetMatrixStr(MATRIX_STRING)
#
sub GetMatrixStr
{
my $Z = "\0" x 5;
@_ or return $Z;
defined $_[0] or return $Z;
return (length($_[0]) == 5) ? $_[0] : substr("$_[0]$Z", 0, 5);
}
#
# This function performs bitwise NOT operation on all the
# bits of the matrix and returns the matrix string.
# Usage: MATRIX_STRING = NOT_Matrix(MATRIX_STRING)
#
sub NOT_Matrix
{
my $MATRIX = GetMatrixStr(shift);
for (my $i = 0; $i < 5; $i++)
{
vec($MATRIX, $i, 8) = ~vec($MATRIX, $i, 8);
}
return $MATRIX;
}
sub NewMatrix { return "\0" x 5; }
sub DisplayMatrix
{
my $j;
print "\n\n--- MATRIX " . ('-' x 60) . "\n\n";
for (my $i = 0; $i < 5; $i++)
{
for ($j = 0; $j < 5; $j++)
{
print "\t[$i,$j]=" . GetMatrixValue($MyMatrix, $i, $j);
}
print "\n";
}
PAUSE();
}
sub PAUSE
{
$| = 1;
print "\nPRESS ENTER TO CONTINUE...\n";
<STDIN>;
return 0;
}
|