-1

A part of my code calculates inverse of a matrix (generated previously in the code) with dimensions more than 300 X 300. I want to use the elements of the inversed matrix further in the code. Have used the below code for this, trying with only 5X5 matrix for testing:

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

I am not able to understand

  1. why the output of number of rows for both b and b_inv is wrong? How to get the correct value of number of rows?

  2. That although the syntax of printing elements of a referenced array is $$b_inv[1][1], I get the correct output when I use $$b_inv[0][1][1]

simbabque
  • 53,749
  • 8
  • 73
  • 136
  • 3
    Please read [mcve]. Having a samle input data and the wanted result will greatly help us provide some answer. – clt60 Mar 20 '17 at 10:40
  • Please add the *"hard-coded the values here till $a[4][4]"* so that we can run this for ourselves. 25 lines of code shouldn't be a problem. – Borodin Mar 20 '17 at 11:30

1 Answers1

1

You are creating a Math::MatrixReal matrix object, and then accessing it as a simple Perl array. Poking around inside a Perl object indiscriminately is wrong, and you must use the methods defined in the documentation

In particular, your statement

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

accesses a three-dimensional array, and there is no way of knowing what the "correct element" should be for this without reading the code of the module

This modification sets up a 5 x 5 identity matrix (in future, please provide data that we can use to reproduce your results) and takes its inverse. The values output are derived using the object's methods as I described and are all correct. Note that the rows and columns are indexed from one instead of from zero that you would expect for Perl arrays

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

output

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
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • Thank you for your reply. I have got my answer to how to obtain the number of rows of the inversed. – moherangde Mar 21 '17 at 08:23
  • I did not write all the hard-coded values as I had randomly chosen some values for testing purpose. My code was able to inverse the matrix but could neither access it's elements by the normal syntax nor was it printing the number of rows correctly. @jm666 I will definitely take care of it in future. – moherangde Mar 21 '17 at 08:32
  • @moherangde: I am glad that you have a solution. You should always post complete code that we can run ourselves with as little modification as possible. Once you have found a set of values that doesn't result in a *singular* matrix (a matrix without an inverse) whether or not they are random, it doesn't make sense to force us to repeat the process. That is why I used the identity matrix. You should read [*How to create a Minimal, Complete, and Verifiable example*](https://stackoverflow.com/help/mcve). – Borodin Mar 21 '17 at 11:49