Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Multiplying matrices

by madM (Beadle)
on Mar 10, 2014 at 08:41 UTC ( [id://1077660]=perlquestion: print w/replies, xml ) Need Help??

madM has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks.. I am trying to multiply matrices but i want someway to calculate the matrix to the power of x .. like matrix ^4 or something like this... i have build a subroutine that accepts a matrix as argument and can multiply itself.. the matrix structure looks like this(just an example)
my %data = ( A => { A => 5, R => -2, N => -1 }, R => { A => -2, R => 7, N => -1 }, N => { A => -1, R => -1, N => 7 }, );
any ideas?
my @aminos= qw(A R N D C Q E G H I L K M F P S T W Y V B Z X); sub multiplyRates { my $M1= @_ ; foreach my $key1 (@aminos) { foreach my $key2 (@aminos) { my $prod; foreach my $key (@aminos) { $prod += $M1->{$key1}->{$key} * $M1->{$key}->{$key2}; } $multiplyrate->{$key1}->{$key2} = $prod; } $multiplyrate1->{$key1} = $newMutationmatrix1->{$key1}; } return \%$multiplyrate; }

Replies are listed 'Best First'.
Re: Multiplying matrices
by moritz (Cardinal) on Mar 10, 2014 at 10:28 UTC
    Hi Monks.. I am trying to multiply matrices but i want someway to calculate the matrix to the power of x

    If your matrices are square, you can decompose your matrix into a product of the form M = U * D * U^T where U is a unitary matrix, U^T is its transposition, and D is a diagonal matrix. Calculating M^x then becomes M^x = U * D^x * U^T, and since D is diagonal calculating the xth power is the same as taking each component to the xth power.

    How does the magical decomposition work? My linear algebra fu is a bit rusty, but Matrix decomposition says the singular value decomposition (SVD) can help.

Re: Multiplying matrices
by zentara (Archbishop) on Mar 10, 2014 at 10:00 UTC
      For many years, I too have suggested people look at PDL, but it's only now reflecting on zentara's suggestion that I see PDL could really use some example code up on perlmonks. Unfortunately, I'm not a big PDL user, so you might want to jump onto the PDL mailing list or peruse the Quantified Onion for more knowledgeable answers.

      Taking a stab at an example, would the PDL code look something like this?

      use PDL; # amino acids in this order in the reaction rates pdl # A R N D C Q E G H I L K M F P S T W Y V B Z X $rates = pdl [ [ 5, -2, -1 ], [ -2, 7, -1 ], [ -1, -1, 7 ], ]; $multiplied_rates = $rates x $rates; print $multiplied_rates;
      My calculation by hand seems to agree with the first two values. The rest is left as an exercise for the user.

      Looks a lot easier than the OP's code, if you can overcome the fear of the new. And it's kinda cool :)

      Edit:If I'd checked before posting, I would have linked to The Perl Data Language (PDL): A Quick Reference Guide or RFC: Getting Started with PDL (the Perl Data Language) both of which have lots of examples.

      Sometimes I can think of 6 impossible LDAP attributes before breakfast.
Re: Multiplying matrices
by Bloodnok (Vicar) on Mar 10, 2014 at 12:44 UTC
    Hmmm, I wonder how far you've looked - I would refer you to Chapter 7 of Mastering Algorithms with Perl (referred to directly in Mastering Algorithms with Perl) - which refers to Math::MatrixReal & PDL (PDL having been mentioned elsewhere (Re: Multiplying matrices by zentara) in this thread) and I also found this (Math::GSL::Matrix) on the 3rd page of a search within CPAN - but these all concern mathematical matrices i.e. grids of numbers, whereas your example data isn't actually a matrix.

    A user level that continues to overstate my experience :-))
Re: Multiplying matrices
by Lennotoecom (Pilgrim) on Mar 10, 2014 at 14:58 UTC
    I know this is super ugly, though working.
    @a = qw/2 2 2 5/; #@a = qw/3 3 3 2 2 2 4 4 4/; $n = 4; powMatrix(\@a, $n); sub powMatrix { $m = shift; @f = @$m; $i = shift; $l = sqrt(@$m); while(--$i){ for($k = 0; $k < @$m; $k+=$l){ for($c = 0; $c < $l; $c++){ $o = $c; $z = 0; for($b = $k; $b < $k+$l; $b++){ $z += $f[$b] * $m->[$o]; $o += $l; } push (@g, $z); } } @f = @g; @g = (); } print "@f\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1077660]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2024-04-20 16:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found