in reply to Memory Efficient Sparse Matrix Handling
Here's a simple implementation:
package Sparse; sub new { return bless [ [], [], [] ], $_[ 0 ]; } sub populateFromFH { my( $self, $fh ) = @_; my( $a, $ia, $ja ) = @$self; push @{ $ia }, 0; while( <$fh> ) { my @n = split; my $first = 0; 1 until $n[ $first++ ]; my $len = --$first; 1 while $n[ $len++ ]; --$len; $len -= $first + 1; push @{ $a }, @n[ $first .. $first + $len ]; push @{ $ja }, $first; push @{ $ia }, scalar @{ $a }; } } sub getMN{ my( $self, $m, $n ) = @_; my( $a, $ia, $ja ) = @$self; my $first = $ja->[ $m ]; my $offset = $ia->[ $m ]; my $len = $ia->[ $m + 1 ] - $offset - 1; my @nonZeroN = @{ $a }[ $offset .. $offset + $len ]; return 0 if $n < $first or $n > $first + $len; return $nonZeroN[ $n - $first ]; } 1;
And proof it works (for some definition ... blah):
#! perl -slw use strict; use Sparse; my $sa = Sparse->new; $sa->populateFromFH( \*DATA ); close DATA; for my $m ( 0 .. 2 ) { print map $sa->getMN( $m, $_ ), 0 .. 3; } __DATA__ 1 2 0 0 0 3 9 0 0 1 4 0
getNM() could be made more efficent by not extracting the whole row when you only want one value, or by returning the whole row suitably padded with leading and trailing zeros depending upon your usage requirements?
|
|---|