00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __VMML__JACOBI_SOLVER__HPP__
00018 #define __VMML__JACOBI_SOLVER__HPP__
00019
00020 #include <vmmlib/vmmlib.hpp>
00021
00022 #include <cmath>
00023 #include <cassert>
00024
00025 namespace vmml
00026 {
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 template < typename float_t >
00043 bool solveJacobi3x3(
00044 matrix< 3, 3, float_t >& a,
00045 vector< 3, float_t >& d,
00046 matrix< 3, 3, float_t >& v,
00047 size_t& rotationCount )
00048 {
00049 v.identity();
00050
00051 vector< 3, float_t > b, z;
00052
00053 for ( size_t i = 0; i < 3; ++i )
00054 {
00055 b[i] = d[i] = a( i,i );
00056 z[i] = 0.0;
00057 }
00058 float_t t, theta, s, c, tau;
00059 size_t rot = 0;
00060 for ( size_t i = 1; i <= 150; ++i )
00061 {
00062 float_t sm = 0.0;
00063 for ( size_t ip = 0; ip < 2; ++ip )
00064 {
00065 for ( size_t iq = ip + 1; iq < 3; ++iq )
00066 {
00067 sm += fabs( a( iq, ip ) );
00068 }
00069 }
00070 if ( sm == 0.0 )
00071 {
00072 rotationCount = rot;
00073 return true;
00074 }
00075 float_t tresh = ( i < 4 ) ? 0.2 * sm / 9.0 : 0.0;
00076
00077 for ( ssize_t ip = 0; ip < 2; ++ip )
00078 {
00079 for ( ssize_t iq = ip + 1; iq < 3; ++iq )
00080 {
00081 float_t g = 100.0 * fabs( a( iq,ip ) );
00082
00083
00084
00085 if ( i > 4
00086 && fabs( d[ip] ) + g == fabs( d[ip] )
00087 && fabs( d[iq] ) + g == fabs( d[iq] )
00088 )
00089 {
00090 a( iq, ip ) = 0.0;
00091 }
00092 else
00093 {
00094 if ( fabs( a( iq, iq ) ) > tresh )
00095 {
00096 float_t h = d[iq] - d[ip];
00097 if ( fabs( h ) + g == fabs( h ) )
00098 {
00099 if ( h != 0.0 )
00100 t = ( a( iq, ip ) ) / h;
00101 else
00102 t = 0.0;
00103 }
00104 else
00105 {
00106 if( a( iq, ip ) != 0.0 )
00107 theta = 0.5 * h / ( a( iq, ip ) );
00108 else
00109 theta = 0.0;
00110 t = 1.0 / ( fabs( theta ) + sqrt( 1.0 + theta * theta ) );
00111 if ( theta < 0.0 )
00112 t = -t;
00113 }
00114 c = 1.0 / sqrt( 1 + t * t );
00115 s = t * c;
00116 tau = s / ( 1.0 + c );
00117 h = t * a( iq, ip );
00118 z[ip] -= h;
00119 z[iq] += h;
00120 d[ip] -= h;
00121 d[iq] += h;
00122 a( iq, ip ) = 0.0;
00123
00124 for ( ssize_t j = 0; j <= ip - 1; ++j )
00125 {
00126 g = a( ip, j );
00127 h = a( iq, j );
00128 a( ip, j ) = g - s * ( h + g * tau );
00129 a( iq, j ) = h + s * ( g - h * tau );
00130 }
00131 for ( ssize_t j = ip + 1; j <= iq - 1; ++j )
00132 {
00133 g = a( j, ip );
00134 h = a( iq, j );
00135 a( j, ip ) = g - s * ( h + g * tau );
00136 a( iq, j ) = h + s * ( g - h * tau );
00137 }
00138 for ( size_t j = iq + 1; j < 3; ++j )
00139 {
00140 g = a( j, ip );
00141 h = a( j, iq );
00142 a( j, ip ) = g - s * ( h + g * tau );
00143 a( j, iq ) = h + s * ( g - h * tau );
00144 }
00145 for ( size_t j = 0; j < 3; ++j )
00146 {
00147 g = v( ip, j );
00148 h = v( iq, j );
00149 v( ip, j ) = g - s * ( h + g * tau );
00150 v( iq, j ) = h + s * ( g - h * tau );
00151 }
00152 ++rot;
00153 }
00154 }
00155 }
00156 }
00157
00158 for ( size_t ip = 0; ip < 3; ++ip )
00159 {
00160 b[ip] += z[ip];
00161 d[ip] = b[ip];
00162 z[ip] = 0.0;
00163 }
00164 }
00165 return false;
00166
00167 }
00168
00169 }
00170
00171 #endif