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