0

I have a Perl program containing the following methods:

  • det To find the determinant of a matrix.
  • identityMatrix Return an n by n identity matrix (1s on the main diagnal, rest 0s).
  • matrixAdd To add two matrices together.
  • matrixScalarMultiply To multiply an integer by a matrix.

I can easily find the determinant of, for example, a matrix A - I where

enter image description here

(It is 0)

But what if I want to find the determinant of A - RI?

enter image description here

In this case, I want my program to solve for the characteristic polynomial solution (a.k.a. the determinant containing variables) along these lines instead of an integer value:

enter image description here

Any suggestions on how to handle this? Code below:

#!/usr/bin/perl
#perl Solver.pl

use strict;
use warnings;

### solve the characteristic polynomial det(A - RI) 

my @A = ( # 3x3, det = -3
   [1, 3, -3],
   [1, 0, 0],
   [0, 1, 0],
);

# test_matrix = A - I
my $test_matrix = matrixAdd( \@A, 
    matrixScalarMultiply( identityMatrix(3), -1 ) );

print "\nTest:\n";
for( my $i = 0; $i <= $#$test_matrix; $i++ ){ 
    print "[";
    for( my $j = 0; $j <= $#$test_matrix; $j++ ){
        $j == $#$test_matrix ? print $test_matrix->[$i][$j], "]\n" : 
            print $test_matrix->[$i][$j], ", ";
    }
}

my $dd = det ($test_matrix);
print "det = $dd \n";



# recursively find determinant of a real square matrix
# only call on n by n matrices where n >= 2
#
# arg0 = matrix reference
sub det{
    my ($A) = @_;

    #base: 2x2 matrix
    if( $#$A + 1 == 2 ){ #recall $#$A == last index of A
        return $A->[0][0]*$A->[1][1] - $A->[1][0]*$A->[0][1];
    }

    #cofactor expansion for matrices > 2x2
    my $answer = 0;
    for( my $col = 0; $col <= $#$A; $col++ ){
        my $m = (); #sub matrix
        my $multiplier = $A->[0][$col];
        if( $col % 2 == 1 ){    #+, -, +, -, ...
            $multiplier *= -1;
        }

        for( my $i = 1; $i <= $#$A; $i++ ){ 
            #j is indexer for A, k for m
            for( my ($j, $k) = (0, 0); $j <= $#$A; $j++ ){
                $m->[$i-1][$k++] = $A->[$i][$j] unless $j == $col;
            }
        }

        $answer += $multiplier*det( $m );
    }#end cofactor expansion

    return $answer;
}#end det()


# return reference to an n by n identity matrix
# can do this in Perl!
#
# arg0 = dimension 'n'
sub identityMatrix{
    my $n = shift;
    my @ret;

    for (my $i = 0; $i < $n; $i++ ){
        for (my $j = 0; $j < $n; $j++ ){
            $ret[$i][$j] = $i == $j ? 1 : 0;
        }
    }

    return \@ret;   
}


# return reference to an n by n matrix which is the sum
# of two different n by n matrices, "a" and "b"
#
# arg0, 1 = references to the pair of matrices to add
sub matrixAdd{
    my @ret;
    my ($a, $b) = ($_[0], $_[1]);

    for (my $i = 0; $i <= $#$a; $i++ ){
        for (my $j = 0; $j <= $#$a; $j++ ){
            $ret[$i][$j] = $a->[$i][$j] + $b->[$i][$j];
        }
    }

    return \@ret;
}


# return reference to a matrix multiplied by a given scalar
#
# arg0 = reference to matrix
# arg1 = scalar to multiply by
sub matrixScalarMultiply{
    my @ret;
    my ($a, $multiplier) = ($_[0], $_[1]);

    for (my $i = 0; $i <= $#$a; $i++ ){
        for (my $j = 0; $j <= $#$a; $j++ ){
            $ret[$i][$j] = $a->[$i][$j] * $multiplier;
        }
    }

    return \@ret;
}
Kolibrie
  • 139
  • 1
  • 13

1 Answers1

1

This is called symbolic math and is in the wheelhouse of tools like Mathematica. For Perl, there are packages like Math::Synbolic but I couldn't tell you how easy they are to use.

On the other hand, if you are just interested in what values of R have a determinant of zero and not that interested in what the characteristic polynomial looks like, then you are looking for the eigenvalues of A. There are some Perl libraries for that, too.

mob
  • 117,087
  • 18
  • 149
  • 283
  • I thought it could be a good exercise to figure out how to (1) solve for a matrix's characteristic polynomial and (2) solve for the roots (eigenvalues) without using a library, but I guess it'll be much harder than I thought. I think I'll start using some libraries soon. Thanks! – Kolibrie Jun 03 '15 at 21:59