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?
In reply to Re: Memory Efficient Sparse Matrix Handling
by BrowserUk
in thread Memory Efficient Sparse Matrix Handling
by neversaint
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |