Hi PerlMonks,

I am interested to get the inverse of a square matrix (given below) using perl script. I have
written a script i.e. inv1.pl (given below) where the matrix is placed in the script itself
at specific location. It makes use of the math_module.pm. The script inv1.pl works well and it gives
the correct result for inverse matrix.

But I want to input the square matrix from a text file (d1.txt) using <STDIN> in the script inv2.pl. The matrix is easily uploaded in the inv2.pl but it does not give the
result. I am at my wit's end to solve this problem. I request the perl monks to look into the
problem and provide constructive suggestions. I want to input the matrix as a text file in the
script inv2.pl so that I can use it for getting the inverse of any higher order matrix like 12x12.
It will be easy for me if only the matrix values are written as comma separated values in input text file without writing the $m2= and braces i.e.`[ ]` with values in d1.txt file.

Here goes the script inv1.pl which gives correct result:

`#!/usr/bin/perl
use warnings;
use math_module;
### TO PRODUCE THE INVERSE OF A SQUARE MATRIX in PERL:
# In a square matrix the number of rows and columns are equal.
# Here we intend to get the inverse of a 4x4 square matrix.
######################################################
print"\n Here we intend to get the inverse of a 4x4 square matrix.\n";
print"\n Enter the Number of Rows i.e 4: ";
$n= <STDIN>; chomp$n;
$N=$n;
# Input the matrix below:
$m2[0]=[3,2,1,1];
$m2[1]=[1,0,2,2];
$m2[2]=[4,1,3,3];
$m2[3]=[1,2,3,4];
### Data Ends Here ###########################
@inv=math_module::get_inverse($N,@m2);
##############################################
# Checking if the inverse matrix is correct:
##############################################
for ($i=0; $i<$N; $i++)
{
for ($j=0; $j<$N; $j++)
{
$t=0;
for($k=0; $k<$N; $k++)
{
$t=$t+ $m2[$i][$k]*$inv[$k][$j];
}
}
}
#################################################
print "\n\n The Inverse Matrix is:\n\n";
## Use of for LOOP:
for ($i=0; $i<$N; $i++)
{
for ($j=0; $j<$N; $j++)
{
print $inv[$i][$j];
print " ";
}
print "\n\n";
}
exit;
`

The math_module.pm is given below:

`package math_module;
sub get_det($\@)
{
my ($m__size, $m_matrix)=@_;
my $m_det=0;
my @new_matrix;
my $i_mat;
if ($m__size ==1)
{
return $$m_matrix[0][0]; # Line 10
}
if ( $m__size ==2)
{
$m_det=$$m_matrix[0][0]*$$m_matrix[1][1]-$$m_matrix[0][1]*$$m_m
+atrix[1][0];
return $m_det;
}
else
{
for ($i_mat=0; $i_mat<$m__size; $i_mat++)
{ # Line 20
for ($m_r=1; $m_r<$m__size; $m_r++)
{
my $k_ajust=0; # Line 23
for ($m_k=0; $m_k < $m__size; $m_k++)
{
if ($m_k != $i_mat)
{
$new_matrix[$m_r-1][$m_k-$k_ajust] =$$m_matrix[
+$m_r][$m_k];
}
else # Line 30
{
$k_ajust=1;
}
}
}
$m_det=$m_det + (-1)**(2+$i_mat) * $$m_matrix[0][$i_mat] * get_
+det($m__size-1, \@new_matrix);
}
return $m_det;
}
} # Line 40
sub get_inverse ($\@)
{
my ($matrix_size, $m) =@_;
for ($i=0; $i<$matrix_size; $i++)
{
for ($j=0; $j<$matrix_size; $j++)
{
$m5[$i][$j]=$$m[$i][$j];
$mt[$i][$j]=$$m[$j][$i];
} # Line 50
}
for ($ii=0; $ii<$matrix_size; $ii++)
{
for ($jj=0; $jj<$matrix_size; $jj++)
{
@aa=remove_row_col($ii,$jj,$matrix_size, @m5);
$inverse_matrix[$ii][$jj]=math_module::get_det($matrix_size-1, @a
+a) / math_module::get_det($matrix_size,@mt);
$inverse_matrix[$ii][$jj]=((-1)**($ii+$jj+2))*$inverse_matrix[$ii
+][$jj];
}
} # Line 60
for ($ii=0; $ii<$matrix_size; $ii++)
{
for ($jj=0; $jj<$matrix_size; $jj++)
{
$inverse_matrix1[$ii][$jj]=$inverse_matrix[$jj][$ii];
}
}
return @inverse_matrix1;
}
sub remove_row_col ($$$@)
{
my ($X_X, $Y_Y, $matrix_size, @matrix) =@_;
for($i_i=0; $i_i < $matrix_size-1; $i_i++)
{
for($j_j=0; $j_j < $matrix_size; $j_j++)
{
if ($i_i < $X_X)
{
$new_matrix[$i_i][$j_j]=$matrix[$i_i][$j_j];
}
if ($i_i >= $X_X)
{
$new_matrix[$i_i][$j_j]=$matrix[$i_i+1][$j_j];
}
}
}
for($i_i=0; $i_i < $matrix_size-1; $i_i++)
{
for($j_j=0; $j_j < $matrix_size-1; $j_j++)
{
if ($j_j < $Y_Y)
{
$new_matrix[$i_i][$j_j]=$new_matrix[$i_i][$j_j];
}
if ($j_j >= $Y_Y)
{
$new_matrix[$i_i][$j_j]=$new_matrix[$i_i][$j_j+1];
}
}
$new_matrix[$i_i][$matrix_size-1]="";
}
return @new_matrix;
}
return 1;
`

Here goes the correct results of inv1.pl

`C:\Users\x>cd desktop
C:\Users\x\Desktop>inv1.pl
Here we intend to get the inverse of a 4x4 square matrix.
Enter the Number of Rows i.e 4: 4
The Inverse Matrix is:
-0.4 -1 0.8 0
1 1 -1 0
2.4 5 -2.8 -1
-2.2 -4 2.4 1
`

I have written the script inv2.pl as follows but it does not work with input file d1.txt:

`#!/usr/bin/perl
### TO PRODUCE THE INVERSE OF A SQUARE MATRIX (ANY SIZE) in PERL:
use warnings;
use math_module;
##################################
# Inverse matrix calculation:
##################################
print"\n Enter the Number of Rows i.e. 4 here: ";
$n= <STDIN>; chomp$n;
$N=$n;
## Input the matrix text file:
print "\n\n Please type the filename(.txt) i.e. d1.txt: ";
$DNAfilename = <STDIN>;
chomp $DNAfilename;
## To remove white space:
$DNAfilename=~ s/\s//gis;
# open the file, or exit
unless ( open(DNAFILE, $DNAfilename) ) {
print "Cannot open file \"$DNAfilename\"\n\n";
exit;
} # Line 10
@a = <DNAFILE>;
@m2=@a;
print"\n The contents of input matrix file are (array m2):\n\n
@m2\n";
### Data Ends Here ###########################
@inv=math_module::get_inverse($N,@m2);
##############################################
# Checking if the inverse matrix is correct:
##############################################
for ($i=0; $i<$N; $i++)
{
for ($j=0; $j<$N; $j++)
{
$t=0;
for($k=0; $k<$N; $k++)
{
$t=$t+ $m2[$i][$k]*$inv[$k][$j];
}
}
}
#################################################
# Output inverse matrix:
##################################################
print "\n\n The Inverse Matrix is:\n\n";
## Use of for LOOP:
for ($i=0; $i<$N; $i++)
{
for ($j=0; $j<$N; $j++)
{
print $inv[$i][$j];
print " ";
}
print "\n\n";
}
exit;
`

The contents of text file d1.txt is given below. It will be easy for me if only the comma separated values

of the matrix like

` 3,2,1,1 ` are used in input file d1.txt without writing the $m2= and braces i.e.

`[ ]` with values in d1.txt file.

`$m2[0]=[3,2,1,1];
$m2[1]=[1,0,2,2];
$m2[2]=[4,1,3,3];
$m2[3]=[1,2,3,4];
`

The incorrect results of inv2.pl goes like:

`C:\Users\x>cd desktop
C:\Users\x\Desktop>inv2.pl
Enter the Number of Rows i.e. 4 here: 4
Please type the filename(.txt) i.e. d1.txt: d1.txt
The contents of input matrix file are (array m2):
$m2[0]=[3,2,1,1];
$m2[1]=[1,0,2,2];
$m2[2]=[4,1,3,3];
$m2[3]=[1,2,3,4];
Illegal division by zero at C:/Perl/lib/math_module.pm line 60, <DNAFI
+LE>line 4.
`

The input file d1.txt for inv2.pl should look like:

`3,2,1,1
1,0,2,2
4,1,3,3
1,2,3,4
`