我有一个包含以下方法的 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;
}