00001 #ifndef __VMML__SINGULAR_VALUE_DECOMPOSITION__H__
00002 #define __VMML__SINGULAR_VALUE_DECOMPOSITION__H__
00003
00004 #include <vmmlib/vmmlib.h>
00005 #include <vmmlib/helperFunctions.h>
00006
00007 namespace vmml
00008 {
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 template < class T >
00019 void svdecompose( T **a, int m, size_t n, T w[], T **v)
00020 {
00021 int flag, i, its, j, jj, k, l, nm;
00022 T anorm, c, f, g, h, s, scale, x, y, z;
00023
00024 T* rv1 = (T*)calloc(n, sizeof(T));
00025 g = scale = anorm = 0.0;
00026 for ( i = 0; i < n; ++i )
00027 {
00028 l = i + 1;
00029 rv1[i] = scale * g;
00030 g = s = scale = 0.0;
00031 if ( i < m )
00032 {
00033 for ( k = i; k < m; ++k )
00034 scale += fabs(a[k][i]);
00035 if ( scale )
00036 {
00037 for ( k = i; k < m; ++k )
00038 {
00039 a[k][i] /= scale;
00040 s += a[k][i] * a[k][i];
00041 }
00042 f = a[i][i];
00043 g = -sign(sqrt(s), f);
00044 h = f * g - s;
00045 a[i][i] = f - g;
00046 for ( j = l; j < n; ++j )
00047 {
00048 for ( s = 0.0, k = i; k < m; ++k )
00049 s += a[k][i] * a[k][j];
00050 f = s / h;
00051 for ( k = i; k < m; ++k )
00052 a[k][j] += f * a[k][i];
00053 }
00054 for ( k = i; k < m; ++k )
00055 a[k][i] *= scale;
00056 }
00057 }
00058 w[i] = scale * g;
00059 g = s = scale = 0.0;
00060 if ( i < m && i != n-1 )
00061 {
00062 for ( k = l; k < n; ++k )
00063 scale += fabs(a[i][k]);
00064 if ( scale )
00065 {
00066 for ( k = l; k < n; ++k )
00067 {
00068 a[i][k] /= scale;
00069 s += a[i][k] * a[i][k];
00070 }
00071 f = a[i][l];
00072 g = -sign(sqrt(s), f);
00073 h = f * g - s;
00074 a[i][l] = f - g;
00075 for ( k = l; k < n; ++k )
00076 rv1[k] = a[i][k] / h;
00077 for ( j = l; j < m; ++j )
00078 {
00079 for ( s = 0.0, k = l; k < n; ++k )
00080 s += a[j][k] * a[i][k];
00081 for ( k = l; k < n; ++k )
00082 a[j][k] += s * rv1[k];
00083 }
00084 for ( k = l; k < n; ++k )
00085 a[i][k] *= scale;
00086 }
00087 }
00088 anorm = max( anorm, ( fabs( w[i] ) + fabs( rv1[i] ) ) );
00089 }
00090 for ( i = n-1; i >= 0; --i )
00091 {
00092 if ( i < n )
00093 {
00094 if ( g )
00095 {
00096 for ( j = l; j < n; ++j )
00097 v[j][i] = (a[i][j] / a[i][l]) / g;
00098 for ( j = l; j < n; ++j )
00099 {
00100 for ( s = 0.0, k = l; k < n; ++k )
00101 s += a[i][k] * v[k][j];
00102 for ( k = l; k < n; ++k )
00103 v[k][j] += s * v[k][i];
00104 }
00105 }
00106 for ( j = l; j < n; ++j )
00107 v[i][j] = v[j][i] = 0.0;
00108 }
00109 v[i][i] = 1.0;
00110 g = rv1[i];
00111 l = i;
00112 }
00113 i = ( m < n ) ? m - 1 : n - 1;
00114 for ( ; i >= 0; --i )
00115 {
00116 l = i + 1;
00117 g = w[i];
00118 for ( j = l; j < n; ++j )
00119 a[i][j] = 0.0;
00120 if ( g )
00121 {
00122 g = 1.0 / g;
00123 for ( j = l; j < n; ++j )
00124 {
00125 for ( s = 0.0, k = l; k < m; ++k )
00126 s += a[k][i] * a[k][j];
00127 f = (s / a[i][i]) * g;
00128 for ( k = i; k < m; ++k )
00129 a[k][j] += f * a[k][i];
00130 }
00131 for ( j = i; j < m; ++j )
00132 a[j][i] *= g;
00133 }
00134 else
00135 for ( j = i; j < m; ++j )
00136 a[j][i] = 0.0;
00137 ++a[i][i];
00138 }
00139 for ( k = n-1; k >= 0; --k )
00140 {
00141
00142 for ( its = 0; its < 30; ++its )
00143 {
00144 flag = 1;
00145 for ( l = k; l >= 0; --l )
00146 {
00147 nm = l - 1;
00148 if ( ( fabs( rv1[l] ) + anorm ) == anorm )
00149 {
00150 flag = 0;
00151 break;
00152 }
00153 if ( ( fabs( w[nm] ) + anorm ) == anorm )
00154 break;
00155 }
00156 if ( flag )
00157 {
00158 c = 0.0;
00159 s = 1.0;
00160 for ( i = l; i <= k; ++i )
00161 {
00162 f = s * rv1[i];
00163 rv1[i] = c * rv1[i];
00164 if ( ( fabs(f) + anorm ) == anorm )
00165 break;
00166 g = w[i];
00167 h = pythag(f, g);
00168 w[i] = h;
00169 h = 1.0 / h;
00170 c = g * h;
00171 s = -f * h;
00172 for ( j = 0; j < m; ++j )
00173 {
00174 y = a[j][nm];
00175 z = a[j][i];
00176 a[j][nm] = y * c + z * s;
00177 a[j][i] = z * c - y * s;
00178 }
00179 }
00180 }
00181 z = w[k];
00182 if ( l == k )
00183 {
00184 if ( z < 0.0 )
00185 {
00186 w[k] = -z;
00187 for ( j = 0; j < n; ++j )
00188 v[j][k] = -v[j][k];
00189 }
00190 break;
00191 }
00192 if ( its == 30 )
00193 {
00194
00195 std::cerr << "SingularValueDecomposition - Warning: no convergence in 30 iterations." << std::endl;
00196 }
00197 x = w[l];
00198 nm = k - 1;
00199 y = w[nm];
00200 g = rv1[nm];
00201 h = rv1[k];
00202 f = ( (y-z) * (y+z) + (g-h) * (g+h) ) / (2.0 * h * y );
00203 g = pythag( f, 1.0 );
00204 f = ( ( x - z ) * ( x + z ) + h * ( ( y / ( f + sign( g, f ) ) ) - h ) ) / x;
00205 c = s = 1.0;
00206
00207 for ( j = l; j <= nm; ++j )
00208 {
00209 i = j + 1;
00210 g = rv1[i];
00211 y = w[i];
00212 h = s * g;
00213 g = c * g;
00214 z = pythag( f, h );
00215 rv1[j] = z;
00216 c = f / z;
00217 s = h / z;
00218 f = x * c + g * s;
00219 g = g * c - x * s;
00220 h = y * s;
00221 y *= c;
00222 for ( jj = 0; jj < n; ++jj )
00223 {
00224 x = v[jj][j];
00225 z = v[jj][i];
00226 v[jj][j] = x * c + z * s;
00227 v[jj][i] = z * c - x * s;
00228 }
00229 z = pythag( f, h );
00230 w[j] = z;
00231 if ( z )
00232 {
00233 z = 1.0 / z;
00234 c = f * z;
00235 s = h * z;
00236 }
00237 f = c * g + s * y;
00238 x = c * y - s * g;
00239 for ( jj = 0; jj < m; ++jj )
00240 {
00241 y = a[jj][j];
00242 z = a[jj][i];
00243 a[jj][j] = y * c + z * s;
00244 a[jj][i] = z * c - y * s;
00245 }
00246 }
00247 rv1[l] = 0.0;
00248 rv1[k] = f;
00249 w[k] = x;
00250 }
00251
00252 }
00253 free(rv1);
00254 for ( i = 0; i < 3; ++i )
00255 for ( j = 0; j < 3; ++j )
00256 if ( i < j && w[i] < w[j] )
00257 {
00258 double t = w[i];
00259 double u = w[j];
00260 w[i] = u;
00261 w[j] = t;
00262
00263 for ( k = 0; k < 3; ++k )
00264 {
00265 t = v[i][k];
00266 u = v[j][k];
00267 v[i][k] = u * pow( -1, i );
00268 v[j][k] = t * pow( -1, j );
00269 t = a[k][i];
00270 u = a[k][j];
00271 a[k][i] = u * pow( -1, i );
00272 a[k][j] = t * pow( -1, j );
00273 }
00274 }
00275
00276 }
00277
00278 }
00279
00280 #endif
00281
00282