' ******************************************************************
' Eigenvalues and eigenvectors of a general square matrix
' ******************************************************************

#INCLUDE "fbmath.bi"

SUB WriteNumber(Re AS DOUBLE, Im AS DOUBLE)
' Writes a real or complex number

  PRINT USING "#####.######"; Re;

  IF Im = 0 THEN
    PRINT
  ELSEIF Im > 0 THEN
    PRINT " + "; : PRINT USING "#####.######"; Im; : PRINT " * i"
  ELSE
    PRINT " - "; : PRINT USING "#####.######"; - Im; : PRINT " * i"
  END IF
END SUB

SUB WriteEigenValue(Lambda AS Complex)
' Writes eigenvalue Lambda

  PRINT : PRINT "Eigenvalue:" : PRINT
  WriteNumber Lambda.X, Lambda.Y
END SUB

SUB WriteEigenVector(Lambda() AS Complex,_
                     V()      AS DOUBLE,_
                     I        AS INTEGER)
' Writes the I-th eigenvector

  DIM AS INTEGER K, N

  N = UBOUND(Lambda)

  PRINT : PRINT "Eigenvector:" : PRINT

  IF Lambda(I).Y = 0 THEN
    ' Eigenvector is in column I of V
    FOR K = 1 TO N
      WriteNumber V(K, I), 0
    NEXT K
  ELSEIF Lambda(I).Y > 0 THEN
    ' Real and imag. parts of eigenvector are in columns I and (I+1)
    FOR K = 1 TO N
      WriteNumber V(K, I), V(K, I+1)
    NEXT K
  ELSE
    ' Conjugate of eigenvector is in columns (I-1) and I
    FOR K = 1 TO N
      WriteNumber V(K, I-1), - V(K, I)
    NEXT K
  END IF
END SUB

CONST N = 4                          ' Size of matrix

DIM AS DOUBLE A(1 TO N, 1 TO N) = _  ' Original matrix
{{ 1, 2, 0, -1},   _
 {-1, 4, 3, -0.5}, _
 { 2, 2, 1, -3},   _
 { 0, 0, 3, -4}}

DIM AS DOUBLE  V(1 TO N, 1 TO N)     ' Eigenvectors
DIM AS Complex Lambda(1 TO N)        ' Eigenvalues

DIM AS INTEGER I, ErrCode

EigenVect A(), Lambda(), V()

ErrCode = MathErr

IF ErrCode = 0 THEN
  FOR I = 1 TO N
    WriteEigenValue Lambda(I)
    WriteEigenVector Lambda(), V(), I
    PRINT : PRINT "Press a key to continue... ";
    DO : LOOP UNTIL INKEY$ <> ""
    PRINT
  NEXT I
ELSE
  PRINT "Unable to find eigenvalues Lambda(1) to Lambda("; -ErrCode; ")"
  PRINT
  IF 1 - ErrCode < N THEN
    PRINT "Eigenvalues Lambda("; 1 - ErrCode; ") to Lambda("; N; "):"
    FOR I = 1 - ErrCode TO N
      WriteEigenValue Lambda(I)
    NEXT I
  END IF
  SLEEP
END IF
