0

我有一个包含以下方法的 Perl 程序:

  • det求矩阵的行列式。
  • identityMatrix返回一个 n × n 单位矩阵(主对角线为 1,其余为 0)。
  • matrixAdd将两个矩阵相加。
  • matrixScalarMultiply将整数乘以矩阵。

例如,我可以很容易地找到矩阵A - I的行列式,其中

在此处输入图像描述

(为 0)

但是如果我想找到A-RI的行列式呢?

在此处输入图像描述

在这种情况下,我希望我的程序沿着这些线求解特征多项式解(也就是包含变量的行列式),而不是整数值:

在此处输入图像描述

有关如何处理此问题的任何建议?下面的代码:

#!/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;
}
4

1 回答 1

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.

于 2015-06-03T21:54:36.030 回答