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