From: David on 9 Aug 2010 23:25 All, I have no experience with Perl modules that do linear algebra. I've searched CPAN and see several. Can someone advise me on what to use? I'd like to have the ability to start with a matrix with integer entries, put it in reduced row echelon form, with all of the entries as rational numbers, such as: A = 4 0 0 2 -1 -3 0 1 0 2 0 -1 ans = 1 0 0 1/2 0 1 0 -1/2 0 0 0 0 Suggestions? This has to be in perl. D.
From: sln on 10 Aug 2010 09:22 On Mon, 9 Aug 2010 20:25:53 -0700 (PDT), David <dwarnold45(a)suddenlink.net> wrote: >All, > >I have no experience with Perl modules that do linear algebra. I've >searched CPAN and see several. > >Can someone advise me on what to use? I'd like to have the ability to >start with a matrix with integer entries, put it in reduced row >echelon form, with all of the entries as rational numbers, such as: > > >A = > > 4 0 0 2 > -1 -3 0 1 > 0 2 0 -1 > > >ans = > > 1 0 0 1/2 > 0 1 0 -1/2 > 0 0 0 0 > >Suggestions? This has to be in perl. > >D. Try this, only tested on your matrix. And the swapped rows (redo) didn't come into play on your matrix. I just guess its a redo but don't know. Code is based on Pseudo code from wikipedia. -sln --------------------------- use strict; use warnings; # my @Matrix = ( [ 4, 0, 0, 2 ], [ -1, -3, 0, 1 ], [ 0, 2, 0, -1 ], ); my @Mreduced = GetReducedRowEchelonForm( @Matrix); print "\n"; print "@{$_}\n" for (@Matrix); print "------ \n"; print "@{$_}\n" for (@Mreduced); exit; # sub GetReducedRowEchelonForm { return () unless @_ && ref $_[0] eq "ARRAY"; my @M; for my $k (0 .. $#_) { $M[$k] = [@{$_[$k]}]; } my $lead = 0; my $rowCount = @M - 1; my $columnCount = @{$M[0]} - 1; FUNC: for my $r (0 .. $rowCount) { last FUNC if $columnCount <= $lead; my $i = $r; while( $M[$i][$lead] == 0) { $i++; if ( $rowCount == $i) { $i = $r; $lead++; last FUNC if $columnCount == $lead; } last FUNC if $i > $rowCount; } if ($i != $r) { my $irow = $M[$i]; $M[$i] = $M[$r]; $M[$r] = $irow; redo FUNC; # swapped rows, should we redo? Don't know. } my $divisor = $M[$r][$lead]; foreach my $rowval ( @{$M[$r]} ) { $rowval /= $divisor; } for $i (0 .. $rowCount) { if ($i != $r) { my $multiplier = $M[$i][$lead]; for my $ndx (0 .. $columnCount) { $M[$i][$ndx] -= $multiplier * $M[$r][$ndx]; } } } $lead++; } return @M; } __END__ http://en.wikipedia.org/wiki/Row_echelon_form The following pseudocode converts a matrix to reduced row-echelon form: function ToReducedRowEchelonForm(Matrix M) is lead := 0 rowCount := the number of rows in M columnCount := the number of columns in M for 0 <= r < rowCount do if columnCount <= lead then stop function end if i = r while M[i, lead] = 0 do i = i + 1 if rowCount = i then i = r lead = lead + 1 if columnCount = lead then stop function end if end if end while if i != r then Swap rows i and r Divide row r by M[r, lead] for 0 <= i < rowCount do if i != r do Subtract M[i, lead] multiplied by row r from row i end if end for lead = lead + 1 end for end function
|
Pages: 1 Prev: OO instantiate Next: FAQ 1.4 What are Perl 4, Perl 5, or Perl 6? |