package jmathlib.toolbox.jmathlib.matrix._private.Jampack;
/**
Eig implements the eigenvalue-vector decomposition of
of a square matrix. Specifically given a diagonalizable
matrix A, there is a matrix nonsingular matrix X such that
<pre>
* D = X<sup>-1</sup> AX
</pre>
is diagonal. The columns of X are eigenvectors of A corresponding
to the diagonal elements of D. Eig implements X as a Zmat and
D as a Zdiagmat.
<p>
Warning: if A is defective rounding error will allow Eig to
compute a set of eigevectors. However, the matrix X will
be ill conditioned.
@version Pre-alpha
@author G. W. Stewart
*/
public class Eig{
/** The matrix of eigevectors */
public Zmat X;
/** The diagonal matrix of eigenvalues */
public Zdiagmat D;
/**
Creates an eigenvalue-vector decomposition of a square matrix A.
@param A The matrix whose decomposition is to be
computed
@exception JampackException
Thrown if A is not square. <br>
Passed from below.
*/
public Eig(Zmat A)
throws JampackException{
int i, j, k;
double norm, scale;
Z z, d;
A.getProperties();
if (A.nr != A.nc){
throw new JampackException
("Matrix not square.");
}
int n = A.nr;
/* Compute the Schur decomposition of $A$ and set up T and D. */
Schur S = new Schur(A);
Zmat T = S.T;
D = new Zdiagmat(T);
norm = Norm.fro(A);
X = new Zmat(n, n);
/* Compute the eigevectors of T */
for (k=n-1; k>=0; k--){
d = T.get0(k, k);
X.re[k][k] = 1.0;
X.im[k][k] = 0.0;
for (i=k-1; i>=0; i--){
X.re[i][k] = -T.re[i][k];
X.im[i][k] = -T.im[i][k];
for(j=i+1; j<k; j++){
X.re[i][k] = X.re[i][k] - T.re[i][j]*X.re[j][k]
+ T.im[i][j]*X.im[j][k];
X.im[i][k] = X.im[i][k] - T.re[i][j]*X.im[j][k]
- T.im[i][j]*X.re[j][k];
}
z = T.get0(i,i);
z.Minus(z, d);
if (z.re==0.0 && z.im==0.0){ // perturb zero diagonal
z.re = 1.0e-16*norm; // to avoid division by zero
}
z.Div(X.get0(i,k), z);
X.put0(i, k, z);
}
/* Scale the vector so its norm is one. */
scale = 1.0/Norm.fro(X, X.bx, X.rx, X.bx+k, X.bx+k);
for (i=0; i<X.nr; i++){
X.re[i][k] = scale*X.re[i][k];
X.im[i][k] = scale*X.im[i][k];
}
}
X = Times.o(S.U, X);
}
}