Как рассчитать количество строк ссылочного массива в Perl

Часть моего кода вычисляет обратную матрицу (сгенерированную ранее в коде) с размерами более 300 X 300. Я хочу использовать элементы инвертированной матрицы далее в коде. Для этого использовали приведенный ниже код, пытаясь использовать только 5X5 матрицу для тестирования:

use strict;
use warnings;
use Math::MatrixReal;
my @a=();                           #a is the matrix obtained
$a[0][0]=0.18761134;
$a[0][1]=0.010779401;               #Have hard-coded the values here till $a[4][4] 

my $ref_a = \@a;
my $b = Math::MatrixReal->new_from_rows($ref_a);
my $b_inv = $b->inverse();
print "\n Inverse is\n",$b_inv;                      #prints correct inverse
print "\n\nTest printing elements\n";
print $$b_inv[0][1][1],"\n";                         #prints the correct element

my $row_b=scalar(@{$b});   
print "Number of rows in b: ",$row_b,"\n";           #prints 6
my $col_b=@{$$b[0]};
print "Columns in b: ",$col_b,"\n";                  #prints 5

my $row_binv=scalar(@$b_inv);
print "Number of rows in b_inv: ",$row_binv,"\n";    #prints 3
my $col_binv=@{$$b_inv[0]};
print "Number of columns in b_inv ",$col_binv,"\n";  #prints 5

Я не могу понять

  1. почему вывод числа строк для b и b_inv неправильный? Как получить правильное значение количества строк?

  2. Это, хотя синтаксис печати элементов ссылочного массива $$b_inv[1][1]Я получаю правильный вывод при использовании $$b_inv[0][1][1]

1 ответ

Решение

Вы создаете Math::MatrixReal матричный объект, а затем доступ к нему в виде простого массива Perl. Неразборчиво разбираться в объекте Perl - неправильно, и вы должны использовать методы, определенные в документации.

В частности, ваше заявление

print $$b_inv[0][1][1],"\n";    # prints the correct element

обращается к трехмерному массиву, и нет никакого способа узнать, каким должен быть "правильный элемент" для этого, не читая код модуля

Эта модификация устанавливает идентификационную матрицу 5 x 5 (в будущем, пожалуйста, предоставьте данные, которые мы можем использовать для воспроизведения ваших результатов) и использует обратную. Вывод значений выводится с использованием методов объекта, как я описал, и все они правильные. Обратите внимание, что строки и столбцы индексируются с одного, а не с нуля, что вы ожидаете для массивов Perl

use strict;
use warnings 'all';

use Math::MatrixReal;

my @arr = (
    [1, 0, 0, 0, 0],
    [0, 1, 0, 0, 0],
    [0, 0, 1, 0, 0],
    [0, 0, 0, 1, 0],
    [0, 0, 0, 0, 1],
);

my $ref_a = \@arr;
my $b = Math::MatrixReal->new_from_rows(\@arr);
my $b_inv = $b->inverse;

print "\nInverse is\n", $b_inv;
print "\n\nTest printing elements\n";
print $b_inv->element($_, $_), "\n" for 1 .. 5;

my ($row_b, $col_b) = $b->dim;;
print "Number of rows in b: $row_b\n";           # prints 5
print "Columns in b: $col_b\n";                  # prints 5

my ($row_binv, $col_binv) = $b_inv->dim;;
print "Number of rows in b_inv: $row_binv\n";    # prints 5
print "Number of columns in b_inv $col_binv\n";  # prints 5

выход

Inverse is
[  1.000000000000E+000  0.000000000000E+000  0.000000000000E+000  0.000000000000E+000  0.000000000000E+000 ]
[  0.000000000000E+000  1.000000000000E+000  0.000000000000E+000  0.000000000000E+000  0.000000000000E+000 ]
[  0.000000000000E+000  0.000000000000E+000  1.000000000000E+000  0.000000000000E+000  0.000000000000E+000 ]
[  0.000000000000E+000  0.000000000000E+000  0.000000000000E+000  1.000000000000E+000  0.000000000000E+000 ]
[  0.000000000000E+000  0.000000000000E+000  0.000000000000E+000  0.000000000000E+000  1.000000000000E+000 ]


Test printing elements
1
1
1
1
1
Number of rows in b: 5
Columns in b: 5
Number of rows in b_inv: 5
Number of columns in b_inv 5
Другие вопросы по тегам