00001 #ifndef Eigensystems_H
00002 #define Eigensystems_H
00003
00004 #include <math.h>
00005 #include "util.h"
00006
00007 #define ROTATE( a, i, j, k, l) g=a[i][j]; h=a[k][l];a[i][j]=g-s*(h+g*tau); a[k][l]=h+s*(g-h*tau);
00008
00009 void jacobi( TMatrix a, int n, Value_Type d[], TMatrix v, int *nrot )
00010
00011
00012
00013
00014
00015
00016
00017 {
00018 int j, iq, ip, i;
00019 Value_Type tresh, theta, tau, t, sm, s, h, g, c, *b, *z;
00020
00021 b = create_vector(1, n );
00022 z = create_vector(1, n);
00023 for (ip=1; ip<=n; ip++) {
00024 for (iq=1; iq<=n; iq++) v[ip][iq] = 0.0;
00025 v[ip][ip] = 1.0;
00026 };
00027 for (ip=1; ip<=n; ip++) {
00028 b[ip] = d[ip] = a[ip][ip];
00029 z[ip] = 0.0;
00030 };
00031
00032 for (i=1; i<= 50; i++) {
00033 sm = 0.0;
00034 for (ip=1; ip<=n-1; ip++) {
00035 for (iq=ip+1; iq<=n; iq++)
00036 sm += fabs( a[ip][iq] );
00037 };
00038 if ( sm == 0.0 ) {
00039 free_vector( z, 1, n );
00040 free_vector( b, 1, n );
00041 return;
00042 };
00043 if ( i < 4 )
00044 tresh = 0.2*sm/(n*n);
00045 else
00046 tresh = 0.0;
00047 for (ip=1; ip<=n-1; ip++) {
00048 for (iq=ip+1; iq<=n; iq++) {
00049 g = 100.0*fabs( a[ip][iq]);
00050 if ( i > 4 && (Value_Type)(fabs(d[ip])+g) == (Value_Type)fabs(d[ip]) && (Value_Type)(fabs(d[iq])+g) == (Value_Type)fabs(d[iq]))
00051 a[ip][iq] = 0.0;
00052 else if (fabs(a[ip][iq]) > tresh) {
00053 h = d[iq]-d[ip];
00054 if ((Value_Type)(fabs(h)+g) == (Value_Type)fabs(h))
00055 t = (a[ip][iq])/h;
00056 else {
00057 theta = 0.5*h/(a[ip][iq]);
00058 t = 1.0/(fabs(theta)+sqrt( 1.0+theta*theta));
00059 if (theta < 0.0) t = -t;
00060 }
00061 c = 1.0/sqrt(1+t*t);
00062 s = t*c;
00063 tau = s/(1.0 + c);
00064 h = t*a[ip][iq];
00065 z[ip] -= h;
00066 z[iq] += h;
00067 d[ip] -= h;
00068 d[iq] += h;
00069 a[ip][iq] = 0.0;
00070 for ( j=1; j<ip-1; j++) {
00071 ROTATE( a, j, ip, j, iq );
00072 }
00073 for (j=ip+1; j<= iq-1; j++) {
00074 ROTATE( a, ip, j, j, iq );
00075 }
00076 for (j=iq+1; j<=n; j++) {
00077 ROTATE( a, ip, j, iq, j);
00078 }
00079 for (j=1; j<=n; j++ ) {
00080 ROTATE(v, j, ip, j, iq );
00081 }
00082
00083 }
00084
00085 };
00086 };
00087 for (ip=1; ip<=n; ip++) {
00088 b[ip] += z[ip];
00089 d[ip] = b[ip];
00090 z[ip] = 0.0;
00091 }
00092 };
00093 };
00094
00095
00096
00097 void eigsrt( Value_Type d[], TMatrix v, int n )
00098
00099
00100
00101 {
00102 int k, j, i;
00103 Value_Type p;
00104
00105 for (i=1; i<n; i++) {
00106 p = d[k=i];
00107 for (j=i+1; j<=n; j++ )
00108 if ( d[j] >= p) p = d[k=j];
00109 if (k != i ) {
00110 d[k] = d[i];
00111 d[i] = p;
00112 for (j=1; j<=n; j++) {
00113 p = v[j][i];
00114 v[j][i] = v[j][k];
00115 v[j][k] = p;
00116 };
00117 };
00118 };
00119 };
00120
00121 #endif