Perl - 包含变量的矩阵的行列式

Perl - Determinant of Matrix Containing Variables

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

我可以轻松找到矩阵的行列式 A - I where

(为0)

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

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

关于如何处理这个问题有什么建议吗?代码如下:

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

这被称为符号数学,是 tools like Mathematica. For Perl, there are packages like Math::Synbolic 的主宰,但我无法告诉您它们的易用性。

另一方面,如果您只对 R 的哪些值具有零行列式而不是对特征多项式的外观感兴趣,那么您是也在寻找 eigenvalues of A. There are some Perl libraries for that