How to resolve the algorithm Matrix-exponentiation operator step by step in the Perl programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Matrix-exponentiation operator step by step in the Perl programming language
Table of Contents
Problem Statement
Most programming languages have a built-in implementation of exponentiation for integers and reals only.
Demonstrate how to implement matrix exponentiation as an operator.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Matrix-exponentiation operator step by step in the Perl programming language
Source code in the perl programming language
use strict;
package SquareMatrix;
use Carp; # standard, "it's not my fault" module
use overload (
'""' => \&_string, # overload string operator so we can just print
'*' => \&_mult, # multiplication, needed for expo
'*=' => \&_mult, # ditto, explicitly defined to trigger copy
'**' => \&_expo, # overload exponentiation
'=' => \&_copy, # copy operator
);
sub make {
my $cls = shift;
my $n = @_;
for (@_) {
# verify each row given is the right length
confess "Bad data @$_: matrix must be square "
if @$_ != $n;
}
bless [ map [@$_], @_ ] # important: actually copy all the rows
}
sub identity {
my $self = shift;
my $n = @$self - 1;
my @rows = map [ (0) x $_, 1, (0) x ($n - $_) ], 0 .. $n;
bless \@rows
}
sub zero {
my $self = shift;
my $n = @$self;
bless [ map [ (0) x $n ], 1 .. $n ]
}
sub _string {
"[ ".join("\n " =>
map join(" " => map(sprintf("%12.6g", $_), @$_)), @{+shift}
)." ]\n";
}
sub _mult {
my ($a, $b) = @_;
my $x = $a->zero;
my @idx = (0 .. $#$x);
for my $j (@idx) {
my @col = map($a->[$_][$j], @idx);
for my $i (@idx) {
my $row = $b->[$i];
$x->[$i][$j] += $row->[$_] * $col[$_] for @idx;
}
}
$x
}
sub _expo {
my ($self, $n) = @_;
confess "matrix **: must be non-negative integer power"
unless $n >= 0 && $n == int($n);
my ($tmp, $out) = ($self, $self->identity);
do {
$out *= $tmp if $n & 1;
$tmp *= $tmp;
} while $n >>= 1;
$out
}
sub _copy { bless [ map [ @$_ ], @{+shift} ] }
# now use our matrix class
package main;
my $m = SquareMatrix->make(
[1, 2, 0],
[0, 3, 1],
[1, 0, 0] );
print "### Order $_\n", $m ** $_ for 0 .. 10;
$m = SquareMatrix->make(
[ 1.0001, 0, 0, 1 ],
[ 0, 1.001, 0, 0 ],
[ 0, 0, 1, 0.99998 ],
[ 1e-8, 0, 0, 1.0002 ]);
print "\n### Matrix is now\n", $m;
print "\n### Big power:\n", $m ** 100_000;
print "\n### Too big:\n", $m ** 1_000_000;
print "\n### WAY too big:\n", $m ** 1_000_000_000_000;
print "\n### But identity matrix can handle that\n",
$m->identity ** 1_000_000_000_000;
You may also check:How to resolve the algorithm Send an unknown method call step by step in the Factor programming language
You may also check:How to resolve the algorithm Sorting algorithms/Cocktail sort with shifting bounds step by step in the ALGOL W programming language
You may also check:How to resolve the algorithm Pell's equation step by step in the jq programming language
You may also check:How to resolve the algorithm Gaussian primes step by step in the 11l programming language
You may also check:How to resolve the algorithm Loops/Break step by step in the Yabasic programming language