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

' ------------------------------------------------------------------
' Type definition
' ------------------------------------------------------------------

TYPE Complex
  X AS DOUBLE
  Y AS DOUBLE
END TYPE

' ------------------------------------------------------------------
' Global variable
' ------------------------------------------------------------------

COMMON SHARED ErrCode AS INTEGER
' Error code from the last function evaluation

' ------------------------------------------------------------------
' External functions
' ------------------------------------------------------------------

DECLARE SUB Balance(      A()     AS DOUBLE,  _ 
                    BYREF Lo      AS INTEGER, _ 
                    BYREF Hi      AS INTEGER, _ 
                          Scale() AS DOUBLE)
' Balances a matrix and tries to isolate eigenvalues

DECLARE SUB ElmHes(A()     AS DOUBLE,  _ 
                   Lo      AS INTEGER, _ 
                   Hi      AS INTEGER, _ 
                   Inter() AS INTEGER)
' Reduces a square matrix to upper Hessenberg form

DECLARE SUB Eltran(A()     AS DOUBLE,  _
                   Lo      AS INTEGER, _
                   Hi      AS INTEGER, _
                   Inter() AS INTEGER, _
                   Z()     AS DOUBLE)
' Saves transformations used by ElmHes

DECLARE SUB Hqr2(H()      AS DOUBLE,  _ 
                 Lo       AS INTEGER, _ 
                 Hi       AS INTEGER, _ 
                 Lambda() AS Complex, _ 
                 Z()      AS DOUBLE)
' Eigenvalues and eigenvectors of an upper Hessenberg matrix

DECLARE SUB BalBak(Z()     AS DOUBLE,  _ 
                   Lo      AS INTEGER, _ 
                   Hi      AS INTEGER, _ 
                   Scale() AS DOUBLE,  _ 
                   M       AS INTEGER)
' Back transformation of eigenvectors

' ******************************************************************

SUB EigenVect(A() AS DOUBLE, Lambda() AS Complex, V() AS DOUBLE)

  DIM AS INTEGER Lb, Ub, Lo, Hi, M
  
  Lb = LBOUND(A, 1)
  Ub = UBOUND(A, 1)

  DIM AS DOUBLE  Scale(Lb TO Ub)
  DIM AS INTEGER Inter(Lb TO Ub) 

  Balance A(), Lo, Hi, Scale()
  ElmHes A(), Lo, Hi, Inter()
  Eltran A(), Lo, Hi, Inter(), V()
  Hqr2 A(), Lo, Hi, Lambda(), V()
  IF ErrCode = 0 THEN BalBak V(), Lo, Hi, Scale(), M
END SUB

