src/Matrix/h_matrix.cc
/* The inverse of a Hermitian matrix can be obtained in several ways.  For
   example (using H=Hermitian & U=unitary)

                    -1                t   -1       -1    t   -1
               H * H   = I = U * D * U * H   ==>  H   = U * D  * U

   But herein, we will use the LU decomposition to obtain the inverse. In this
   case we have (using H=Hermitian, L=lower triang., & U=upper triang.)

                               -1               -1
                          H * H  = I = L * U * H
  
   where we 1st solve L*Y=I for Y, then U*inv(H)=Y for inv(H) taking advantage
   of the special formats of L & U.

  The LU & LU inverse routines used here are derived from "Numerical Recipies",
  W.H.  Press, B.P.Flannery, S.A.Teukolsky, & W.T.Vetterling, Cambridge 
  University Press, 1989.  See pages 31 through 36. The code was extensively
  adapted for C++ and GAMMA arrays.

  The LU algorithm takes as input a Hermitian A and an integer array indx.
  It returns returns the LU decomposition of A' where A' is A with any needed
  row permutations. The latter (row permutations) are stored in the integer
  array indx (indx[0] < 0 flags no row changes).

  The LU decomposition formulates the equation (depicted for 4x4 A below) 

                                A = LU

       [A11 A12 A13 A14]   [ 1   0   0   0 ] [U11 U12 U12 U14]
       |A21 A22 A23 A24]   [L21  1   0   0 ] [ 0  U22 U23 U24|
       |A31 A32 A33 A34] = [L31 L32  1   0 ] [ 0   0  U33 U34|
       [A41 A42 A43 A44]   [L41 L42 L43  1 ] [ 0   0   0  U44]

  Neglecting implicit <i|L|i>, L & U are stored in in a single array.

                           [U11 U12 U12 U14]
                           [L21 U22 U23 U24|
                           [L31 L32 U33 U34|
                           [L41 L42 L43 U44]

  We have dropped the diagonal elements of L since we know they are always 1.
  The algorithm uses Crouts method in determining the elements of L and U
  which are stable under pivoting (row interchanges).

  The LU inverse algorithm takes an input matrix A' in its LU decomposition
  format where A' is some original matrix A with any needed row permutations
  to attain the LU form. The row permutations used to relate A to A' are stored
  in the integer array indx.  The function then proceeds to solve the following
  equation for |x> given a |b>:
                                 A|x> = |b>

  This is accomplished by considering (reformulating) the problem as

                    A|x> = (LU)|x> = L(U|x>) = L|y> = |b>

  using the LU decomposition. This is first solved for the vector |y>, where
  L|y> = |b>, easily accomplished since L is lower-triangular.  Subsequently
  the equation U|x> = |y> is solved for the desired |x>, again easily done
  since U is upper=triangular.  By repeating this process for many |x> and |b>
  pairs of columns, the inverse of the original array can be obtained.
                                    -1
        A [|xo> |x1> ... |xn>] = A A  =  [|bo> |b1> .... |bn>] = I 


    Function  Arguments               Result                      Notes
  ---------- --------- ----------------------------------- -------------------
     inv        ---    inverse(hmx) where inv(hmx)*hmx = I
     LU        int*    LU == hmx + row permutations        One Array L\U Form
     LUinv    int*, B  Solutionh X where LU*X = AX = B     Inverse if B=I


        A [|xo> |x1> ... |xn>] = A A  =  [|bo> |b1> .... |bn>] = I          */
The inverse of a Hermitian matrix can be obtained in several ways.  For
example (using H=Hermitian & U=unitary)



But herein, we will use the LU decomposition to obtain the inverse. In this
case we have (using H=Hermitian, L=lower triang., & U=upper triang.)





The LU & LU inverse routines used here are derived from "Numerical Recipies",
W.H.

The LU algorithm takes as input a Hermitian A and an integer array indx.
It returns returns the LU decomposition of A' where A' is A with any needed
row permutations. The latter (row permutations) are stored in the integer
array indx (indx[0] < 0 flags no row changes).

The LU decomposition formulates the equation (depicted for 4x4 A below)

A = LU



Neglecting implicit , L & U are stored in in a single array.



We have dropped the diagonal elements of L since we know they are always 1.
The algorithm uses Crouts method in determining the elements of L and U
which are stable under pivoting (row interchanges).

The LU inverse algorithm takes an input matrix A' in its LU decomposition
format where A' is some original matrix A with any needed row permutations
to attain the LU form. The row permutations used to relate A to A' are stored
in the integer array indx.  The function then proceeds to solve the following
equation for |x> given a |b>:
A|x> = |b>

This is accomplished by considering (reformulating) the problem as



using the LU decomposition. This is first solved for the vector |y>, where
L|y> = |b>, easily accomplished since L is lower-triangular.  Subsequently
the equation U|x> = |y> is solved for the desired |x>, again easily done
since U is upper=triangular.  By repeating this process for many |x> and |b>
pairs of columns, the inverse of the original array can be obtained.




The inverse of a Hermitian matrix can be obtained in several ways . For example ( using H = Hermitian & U = unitary ) But herein we will use the LU decomposition to obtain the inverse . In this case we have ( using H = Hermitian L = lower triang . & U = upper triang . ) The LU & LU inverse routines used here are derived from " Numerical Recipies " W . H . The LU algorithm takes as input a Hermitian A and an integer array indx . It returns returns the LU decomposition of A ' where A ' is A with any needed row permutations . The latter ( row permutations ) are stored in the integer array indx ( indx [ 0 ] < 0 flags no row changes ) . The LU decomposition formulates the equation ( depicted for 4x4 A below ) A = LU Neglecting implicit L & U are stored in in a single array . We have dropped the diagonal elements of L since we know they are always 1 . The algorithm uses Crouts method in determining the elements of L and U which are stable under pivoting ( row interchanges ) . The LU inverse algorithm takes an input matrix A ' in its LU decomposition format where A ' is some original matrix A with any needed row permutations to attain the LU form . The row permutations used to relate A to A ' are stored in the integer array indx . The function then proceeds to solve the following equation for |x > given a |b > : A|x > = |b > This is accomplished by considering ( reformulating ) the problem as using the LU decomposition . This is first solved for the vector |y > where L|y > = |b > easily accomplished since L is lower - triangular . Subsequently the equation U|x > = |y > is solved for the desired |x > again easily done since U is upper = triangular . By repeating this process for many |x > and |b > pairs of columns the inverse of the original array can be obtained .
_matrix* h_matrix::inv()
  {
  int hd = rows_;			
  i_matrix* I = new i_matrix(hd,hd);	
  int *indx;
  indx = new int[hd];
  n_matrix* hLU = (n_matrix*)LU(indx);	
  _matrix* hinvmx = I->LUinv(indx, hLU);
  delete [] indx;
  return hinvmx; 
  }
_matrix * h_matrix :: inv ( ) { int hd = rows_ ; i_matrix * I = new i_matrix ( hd , hd ) ; int * indx ; indx = new int [ hd ] ; n_matrix * hLU = ( n_matrix * ) LU ( indx ) ; _matrix * hinvmx = I -> LUinv ( indx , hLU ) ; delete [ ] indx ; return hinvmx ; }
The inverse of a Hermitian matrix can be obtained in several ways.
The inverse of a Hermitian matrix can be obtained in several ways .
// sosi - this will use up memory // Matrix dimension // Construct an Identity matrix //  int indx[hd];				// Array for any row permutations // Perform LU decomposition of hmx //  return I->LUinv(indx, hLU);		// Return the inverse via LU*hinv=I;