00001 #include "sadie.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 void EIGEN (
00021 double *mat,
00022 short size,
00023 double *eig
00024
00025 ) { register short i, j, k, found;
00026 char msg[SLEN];
00027 double norm, thr, al, am, ao, sine, sinsq, cosine, cossq, at, bt, xt, temp;
00028
00029 if (TIMES) TIMING(T_EIGEN);
00030
00031
00032 for (norm=0.0,i=0; i<size; i++) {
00033 for (j=0; j<size; j++) {
00034 if (i == j) {
00035 eig[i*size+j] = 1.0;
00036 } else {
00037 eig[i*size+j] = 0.0;
00038 norm += mat[i*size+j]*mat[i*size+j];
00039 }
00040 }
00041 }
00042
00043
00044 thr = sqrt(norm);
00045 norm = 1.0E-09*sqrt(norm)/(double)size;
00046 do {
00047 thr /= (double)size;
00048 do {
00049
00050
00051 for (found=FALSE,i=1; i<size; i++) {
00052 for (j=0; j<i; j++) {
00053 if (thr <= fabs(mat[j*size+i])) {
00054
00055
00056 found = TRUE;
00057 al = -mat[j*size+i];
00058 am = (mat[j*size+j]-mat[i*size+i])/2.0;
00059 ao = am < 0.0 ? -al/sqrt(al*al+am*am) : al/sqrt(al*al+am*am);
00060 sine = ao/sqrt(2.0*(1.0+sqrt(1.0-ao*ao)));
00061 sinsq = sine*sine;
00062 cosine = sqrt(1.0-sinsq);
00063 cossq = cosine*cosine;
00064
00065
00066 for (k=0; k<size; k++) {
00067 if (k != i && k != j) {
00068 at = mat[k*size+j];
00069 mat[k*size+j] = at*cosine - mat[k*size+i]*sine;
00070 mat[k*size+i] = at*sine + mat[k*size+i]*cosine;
00071 }
00072 bt = eig[k*size+j];
00073 eig[k*size+j] = bt*cosine - eig[k*size+i]*sine;
00074 eig[k*size+i] = bt*sine + eig[k*size+i]*cosine;
00075 }
00076 at = mat[j*size+j];
00077 bt = mat[i*size+i];
00078 xt = 2.0*mat[j*size+i]*sine*cosine;
00079 mat[j*size+j] = at*cossq + bt*sinsq - xt;
00080 mat[i*size+i] = at*sinsq + bt*cossq + xt;
00081 mat[i*size+j] = mat[j*size+i] = (at-bt)*sine*cosine + mat[j*size+i]*(cossq-sinsq);
00082 for (k=0; k<size; k++) {
00083 mat[j*size+k] = mat[k*size+j];
00084 mat[i*size+k] = mat[k*size+i];
00085 }
00086 }
00087 }
00088 }
00089 } while (found);
00090 } while (thr > norm);
00091
00092
00093 for (i=1; i<size; i++) {
00094 for (j=i; j>0; j--) {
00095 if (mat[(j-1)*size+j-1] < mat[j*size+j]) {
00096 temp = mat[(j-1)*size+j-1];
00097 mat[(j-1)*size+j-1] = mat[j*size+j];
00098 mat[j*size+j] = temp;
00099 for (k=0; k<size; k++) {
00100 temp = eig[k*size+j-1];
00101 eig[k*size+j-1] = eig[k*size+j];
00102 eig[k*size+j] = temp;
00103 }
00104 }
00105 }
00106 }
00107
00108
00109 MESSAGE('I',"");
00110 MESSAGE('I'," Eigenvalues Eigenvectors");
00111 for (i=0; i<size; i++) {
00112 sprintf(msg," %d %11.4e ",i+1,mat[i*size+i]);
00113 for (j=0; j<size; j+=1) {
00114 sprintf(msg+strlen(msg),"%12.4e",eig[j*size+i]);
00115 }
00116 MESSAGE('I',msg);
00117 }
00118
00119 the_end:
00120 if (TIMES) TIMING(T_EXIT);
00121 }