http://qs1969.pair.com?node_id=605310

gmacfadden has asked for the wisdom of the Perl Monks concerning the following question:

Based on complex arithmetic for MX=B, for

| 1 + i , 2+i |
|.................| = A
| 1 -2i , 2-i |

| 3 + i |
|.........| = X
| 2 + i |

then
| 5 + 8i |
|...........| = B and determinant of A = -1 + 4j
| 10 - 5i |

However, when I try to calculate the determinant and / or the inverse of A in the code below to solve for X, the results are not at all what are to be expected. Please can you identify what I'm missing. Thanks.

#! /usr/bin/perl -w use strict; use CGI::Carp qw(warningsToBrowser fatalsToBrowser); use CGI qw(:standard escapeHTML); use PDL; use PDL::Complex; my $matrixM = pdl [ [ 1+1*i, 2+1*i],[ 1-2*i, 2-1*i] ]; my $matrixB = pdl [ 5+8*i, 10-5*i ]; my $matrixX = pdl [ ]; print header (), start_html (-title => "Matrix Ops"); print "<H1><center>Via Perl Data Language</center></H1><br>\n"; print "\$matrixM = ", $matrixM,"<br>\n"; print "determinant of \$matrixM = ",$matrixM->det,"<br>\n"; print "inverse of \$matrixM = ",$matrixM->det,"<br>\n"; print "\$matrixB = ", $matrixB,"<br>\n"; print "\$matrixX = ", $matrixM->inv x $matrixB,"<br>\n"; print end_html (); exit(0);
  • Comment on PDL works for real number matrix operations, but not working for complex number matrix operations.
  • Download Code

Replies are listed 'Best First'.
Re: PDL works for real number matrix operations, but not working for complex number matrix operations.
by Anno (Deacon) on Mar 17, 2007 at 22:14 UTC
    You're running under warnings, you should have seen the warnings
    Prototype mismatch: sub main::append: none vs (;@) at (eval 6) line 8 Prototype mismatch: sub main::i: none vs () at ./ttt line 10
    The second of these indicates a conflict between CGI and (presumably) PDL::Complex. Both are apparently importing a function i() in your name space. When you put CGI and HTML generation on the side for the moment (not loading CGI and CGI::Carp, and modifying the code accordingly), you avoid the conflict. The complex matrix $matrixM is printed out fine for me after that change. Expect the number you specify as "2+1*i" to be printed as "[2, 1]". The output format isn't quite as intuitive as the input format.

    I haven't followed your code further, except noting that it announces the inverse of $MatrixM, but prints its determinant.

    Anno

      Thank you for identifying the problem with the variable i when using CGI and PDL simultaneously. I eliminated the CGI loads (and therefore was forced to run the PDL scripts from my shell - wish I could have it both ways). However, there is still a problem.

      Let's suppose we want to solve two (2) complex simultaneous equations in two unknowns:

      Equation 1: (1+i)*Xsub1 + (2+i)*Xsub2 = 5+10i

      Equation 2: (1-2i)*Xsub1 + (2-i)*Xsub2 = 8 -5i

      The following code using only real PDL variables, is well-behaved and correctly solves for the variables Xsub1 and Xsub2 as 3+i, and 2+i respectively as the execution demonstrated forthwith after the code prooves.

      .
      #! /usr/bin/perl -w use warnings; use strict; use PDL; my $matrixM = pdl [ [ 1, 2,-1,-1], [ 1, 2, 2, 1], [ 1, 1, 1, 2], [-2,-1, 1, 2] ]; my $matrixB = pdl [ [5],[10], [8],[-5] ]; my $matrixX; print "\$matrixM = ", $matrixM,"<br>\n"; print "\$matrixB = ", $matrixB,"<br>\n"; print "\$matrixX = ", $matrixM->inv x $matrixB,"<br>\n"; exit(0);
      The results from running the above script are:
      $matrixM = [ [ 1 2 -1 -1] [ 1 2 2 1] [ 1 1 1 2] [-2 -1 1 2]] $matrixB = [ [ 5] [10] [ 8] [-5]] $matrixX = [ [ 3] [ 2] [ 1] [ 1]]
      This says that Xsub1 = 3+i, and Xsub2 = 2+i .....which is the correct result!

      Now, in an effort to simplify, let's use the following functionally equivalent (?) PDL with complex matrices to solve the same two same simultaneous equations; observe the results after the following code:

      #! /usr/bin/perl -w use warnings; use strict; use PDL; use PDL::Complex; my $matrixM = pdl [ [ 1+1*i, 2+1*i], [ 1-2*i, 2-1*i] ];<br> my $matrixB = pdl [ 5+8*i, 10-5*i ]; my $matrixX; print "\$matrixM = ",$matrixM,"<br>\n"; print "\$matrixB = ", $matrixB,"<br>\n"; print "\$matrixX = ", $matrixM->inv x $matrixB,"<br>\n"; exit(0);
      The results from running the above script are:
      $matrixM =[ [ [1 1] [2 1] ] [ [ 1 -2] [ 2 -1] ] ] $matrixB =[ [ 5 8] [10 -5] ] $matrixX = [ [ [ 5 -13] [ 0 21] ] [ [ 5 -6] [ 0 -7] ] ]
      So my question is why am I getting such a clearly erroneous result when I run the second piece of code?
        Ugh. Please update your writeup and put <code> tags around your code and the results. The square brackets are unreadable the way it is.

        Anno

        You wrote:

        Equation 1: (1+i)*Xsub1 + (2+i)*Xsub2 = 5+10i Equation 2: (1-2i)*Xsub1 + (2-i)*Xsub2 = 8 -5i
        [...]

        This says that Xsub1 = 3+i, and Xsub2 = 2+i .....which is the correct result!

        No, it isn't! I checked your result manually and couldn't believe what I found. So I took out PDL (which I'm not particularly familiar with) and used Math::Complex to run the following:

        use Math::Complex; my ( $m11, $m12) = ( 1 + i, 2 + i); my ( $m21, $m22) = ( 1 - 2*i, 2 - i); my $b1 = 5 + 10*i; my $b2 = 8 - 5*i; my $xsub1 = 3 + i; my $xsub2 = 2 + i; my $r1 = $m11*$xsub1 + $m12*$xsub2; my $r2 = $m21*$xsub1 + $m22*$xsub2; print "$r1 (should be $b1)\n"; print "$r2 (should be $b2)\n";
        which prints
        5+8i (should be 5+10i) 10-5i (should be 8-5i)
        Pardon me for being blunt, but you should have checked your result yourself instead of sending me (and who knows how many venerable monks more) on a wild-goose chase.

        Apart from that, I don't see how you arrive at the real 4x4 matrix that you use to represent a complex 2x2 matrix. I think there is such a representation, but the one you're using is obviously wrong.

        I have not followed your calculations any further. Very probably the result Math::Pari gave you is the correct one.

        Anno

        Update: Corrected mistaken reference to Math::Pari