00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _GMTL_MATRIXOPS_H_
00036 #define _GMTL_MATRIXOPS_H_
00037
00038 #include <iostream>
00039 #include <algorithm>
00040 #include <gmtl/Matrix.h>
00041 #include <gmtl/Math.h>
00042 #include <gmtl/Vec.h>
00043
00044 namespace gmtl
00045 {
00054 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00055 inline Matrix<DATA_TYPE, ROWS, COLS>& identity( Matrix<DATA_TYPE, ROWS, COLS>& result )
00056 {
00057 if(result.mState != Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY)
00058 {
00059
00060 for (unsigned int r = 0; r < ROWS; ++r)
00061 for (unsigned int c = 0; c < COLS; ++c)
00062 result( r, c ) = (DATA_TYPE)0.0;
00063
00064
00065 for (unsigned int x = 0; x < Math::Min( COLS, ROWS ); ++x)
00066 result( x, x ) = (DATA_TYPE)1.0;
00067
00068
00069 result.mState = Matrix<DATA_TYPE, ROWS, COLS>::FULL;
00070 }
00071
00072 return result;
00073 }
00074
00075
00079 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00080 inline Matrix<DATA_TYPE, ROWS, COLS>& zero( Matrix<DATA_TYPE, ROWS, COLS>& result )
00081 {
00082 if (result.mState == Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY)
00083 {
00084 for (unsigned int x = 0; x < Math::Min( ROWS, COLS ); ++x)
00085 {
00086 result( x, x ) = (DATA_TYPE)0;
00087 }
00088 }
00089 else
00090 {
00091 for (unsigned int x = 0; x < ROWS*COLS; ++x)
00092 {
00093 result.mData[x] = (DATA_TYPE)0;
00094 }
00095 }
00096 return result;
00097 }
00098
00099
00105 template <typename DATA_TYPE, unsigned ROWS, unsigned INTERNAL, unsigned COLS>
00106 inline Matrix<DATA_TYPE, ROWS, COLS>& mult( Matrix<DATA_TYPE, ROWS, COLS>& result,
00107 const Matrix<DATA_TYPE, ROWS, INTERNAL>& lhs,
00108 const Matrix<DATA_TYPE, INTERNAL, COLS>& rhs )
00109 {
00110 Matrix<DATA_TYPE, ROWS, COLS> ret_mat;
00111 zero( ret_mat );
00112
00113
00114
00115
00116 for (unsigned int i = 0; i < ROWS; ++i)
00117 for (unsigned int j = 0; j < COLS; ++j)
00118 for (unsigned int k = 0; k < INTERNAL; ++k)
00119 ret_mat( i, j ) += lhs( i, k ) * rhs( k, j );
00120
00121 return result = ret_mat;
00122 }
00123
00129 template <typename DATA_TYPE, unsigned ROWS, unsigned INTERNAL, unsigned COLS>
00130 inline Matrix<DATA_TYPE, ROWS, COLS> operator*( const Matrix<DATA_TYPE, ROWS, INTERNAL>& lhs,
00131 const Matrix<DATA_TYPE, INTERNAL, COLS>& rhs )
00132 {
00133 Matrix<DATA_TYPE, ROWS, COLS> temporary;
00134 return mult( temporary, lhs, rhs );
00135 }
00136
00142 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00143 inline Matrix<DATA_TYPE, ROWS, COLS>& sub( Matrix<DATA_TYPE, ROWS, COLS>& result,
00144 const Matrix<DATA_TYPE, ROWS, COLS>& lhs,
00145 const Matrix<DATA_TYPE, ROWS, COLS>& rhs )
00146 {
00147
00148
00149
00150 for (unsigned int i = 0; i < ROWS; ++i)
00151 for (unsigned int j = 0; j < COLS; ++j)
00152 result( i, j ) = lhs( i, j ) - rhs( i, j );
00153
00154 return result;
00155 }
00156
00162 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00163 inline Matrix<DATA_TYPE, ROWS, COLS>& add( Matrix<DATA_TYPE, ROWS, COLS>& result,
00164 const Matrix<DATA_TYPE, ROWS, COLS>& lhs,
00165 const Matrix<DATA_TYPE, ROWS, COLS>& rhs )
00166 {
00167
00168
00169
00170 for (unsigned int i = 0; i < ROWS; ++i)
00171 for (unsigned int j = 0; j < COLS; ++j)
00172 result( i, j ) = lhs( i, j ) + rhs( i, j );
00173
00174 return result;
00175 }
00176
00181 template <typename DATA_TYPE, unsigned SIZE>
00182 inline Matrix<DATA_TYPE, SIZE, SIZE>& postMult( Matrix<DATA_TYPE, SIZE, SIZE>& result,
00183 const Matrix<DATA_TYPE, SIZE, SIZE>& operand )
00184 {
00185 return mult( result, result, operand );
00186 }
00187
00192 template <typename DATA_TYPE, unsigned SIZE>
00193 inline Matrix<DATA_TYPE, SIZE, SIZE>& preMult( Matrix<DATA_TYPE, SIZE, SIZE>& result,
00194 const Matrix<DATA_TYPE, SIZE, SIZE>& operand )
00195 {
00196 return mult( result, operand, result );
00197 }
00198
00204 template <typename DATA_TYPE, unsigned SIZE>
00205 inline Matrix<DATA_TYPE, SIZE, SIZE>& operator*=( Matrix<DATA_TYPE, SIZE, SIZE>& result,
00206 const Matrix<DATA_TYPE, SIZE, SIZE>& operand )
00207 {
00208 return postMult( result, operand );
00209 }
00210
00215 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00216 inline Matrix<DATA_TYPE, ROWS, COLS>& mult( Matrix<DATA_TYPE, ROWS, COLS>& result, const Matrix<DATA_TYPE, ROWS, COLS>& mat, float scalar )
00217 {
00218 for (unsigned i = 0; i < ROWS * COLS; ++i)
00219 result.mData[i] = mat.mData[i] * scalar;
00220 return result;
00221 }
00222
00227 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00228 inline Matrix<DATA_TYPE, ROWS, COLS>& mult( Matrix<DATA_TYPE, ROWS, COLS>& result, DATA_TYPE scalar )
00229 {
00230 for (unsigned i = 0; i < ROWS * COLS; ++i)
00231 result.mData[i] *= scalar;
00232 return result;
00233 }
00234
00239 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00240 inline Matrix<DATA_TYPE, ROWS, COLS>& operator*=( Matrix<DATA_TYPE, ROWS, COLS>& result, DATA_TYPE scalar )
00241 {
00242 return mult( result, scalar );
00243 }
00244
00249 template <typename DATA_TYPE, unsigned SIZE>
00250 Matrix<DATA_TYPE, SIZE, SIZE>& transpose( Matrix<DATA_TYPE, SIZE, SIZE>& result )
00251 {
00252
00253 for (unsigned c = 0; c < SIZE; ++c)
00254 for (unsigned r = c + 1; r < SIZE; ++r)
00255 std::swap( result( r, c ), result( c, r ) );
00256
00257 return result;
00258 }
00259
00264 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00265 Matrix<DATA_TYPE, ROWS, COLS>& transpose( Matrix<DATA_TYPE, ROWS, COLS>& result, const Matrix<DATA_TYPE, COLS, ROWS>& source )
00266 {
00267
00268 Matrix<DATA_TYPE, COLS, ROWS> temp = source;
00269
00270
00271 for (unsigned i = 0; i < ROWS; ++i)
00272 {
00273 for (unsigned j = 0; j < COLS; ++j)
00274 {
00275 result( i, j ) = temp( j, i );
00276 }
00277 }
00278
00279 return result;
00280 }
00281
00282
00288 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00289 inline Matrix<DATA_TYPE, ROWS, COLS>& invertFull( Matrix<DATA_TYPE, ROWS, COLS>& result, const Matrix<DATA_TYPE, ROWS, COLS>& src )
00290 {
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 const DATA_TYPE* a = src.getData();
00303 DATA_TYPE* b = result.mData;
00304
00305 int n = 4;
00306 int i, j, k;
00307 int r[ 4], c[ 4], row[ 4], col[ 4];
00308 DATA_TYPE m[ 4][ 4*2], pivot, max_m, tmp_m, fac;
00309
00310
00311 for ( i = 0; i < n; i ++ )
00312 {
00313 r[ i] = c[ i] = 0;
00314 row[ i] = col[ i] = 0;
00315 }
00316
00317
00318 for ( i = 0; i < n; i++ )
00319 {
00320 for ( j = 0; j < n; j++ )
00321 {
00322 m[ i][ j] = a[ i * n + j];
00323 m[ i][ j + n] = ( i == j ) ? (DATA_TYPE)1.0 : (DATA_TYPE)0.0 ;
00324 }
00325 }
00326
00327
00328 for ( k = 0; k < n; k++ )
00329 {
00330
00331 for ( i = 0, max_m = 0; i < n; i++ )
00332 {
00333 if ( row[ i] )
00334 continue;
00335 for ( j = 0; j < n; j++ )
00336 {
00337 if ( col[ j] )
00338 continue;
00339 tmp_m = gmtl::Math::abs( m[ i][ j]);
00340 if ( tmp_m > max_m)
00341 {
00342 max_m = tmp_m;
00343 r[ k] = i;
00344 c[ k] = j;
00345 }
00346 }
00347 }
00348 row[ r[k] ] = col[ c[k] ] = 1;
00349 pivot = m[ r[ k] ][ c[ k] ];
00350
00351
00352 if ( gmtl::Math::abs( pivot) <= 1e-20)
00353 {
00354 std::cerr << "*** pivot = " << pivot << " in mat_inv. ***\n";
00355 result.setError();
00356 return result;
00357 }
00358
00359
00360 for ( j = 0; j < 2*n; j++ )
00361 {
00362 if ( j == c[ k] )
00363 m[ r[ k]][ j] = (DATA_TYPE)1.0;
00364 else
00365 m[ r[ k]][ j] /= pivot;
00366 }
00367
00368
00369 for ( i = 0; i < n; i++ )
00370 {
00371 if ( i == r[ k] )
00372 continue;
00373
00374 for ( j=0, fac = m[ i][ c[k]]; j < 2*n; j++ )
00375 {
00376 if ( j == c[ k] )
00377 m[ i][ j] = (DATA_TYPE)0.0;
00378 else
00379 m[ i][ j] -= fac * m[ r[k]][ j];
00380 }
00381 }
00382 }
00383
00384
00385 for ( i = 0; i < n; i++ )
00386 for ( j = 0; j < n; j++ )
00387 row[ i] = ( c[ j] == i ) ? r[ j] : row[ i];
00388
00389 for ( i = 0; i < n; i++ )
00390 for ( j = 0; j < n; j++ )
00391 b[ i * n + j] = m[ row[ i]][ j + n];
00392
00393
00394 return result;
00395 }
00396
00407 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00408 inline Matrix<DATA_TYPE, ROWS, COLS>& invert( Matrix<DATA_TYPE, ROWS, COLS>& result, const Matrix<DATA_TYPE, ROWS, COLS>& src )
00409 {
00410 if (src.mState == Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY )
00411 return result = src;
00412 else
00413 return invertFull( result, src );
00414 }
00415
00426 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00427 inline Matrix<DATA_TYPE, ROWS, COLS>& invert( Matrix<DATA_TYPE, ROWS, COLS>& result )
00428 {
00429 return invert( result, result );
00430 }
00431
00445 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00446 inline bool operator==( const Matrix<DATA_TYPE, ROWS, COLS>& lhs, const Matrix<DATA_TYPE, ROWS, COLS>& rhs )
00447 {
00448 for (unsigned int i = 0; i < ROWS*COLS; ++i)
00449 {
00450 if (lhs.mData[i] != rhs.mData[i])
00451 {
00452 return false;
00453 }
00454 }
00455
00456 return true;
00457
00458
00459
00460
00461
00462
00463 }
00464
00471 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00472 inline bool operator!=( const Matrix<DATA_TYPE, ROWS, COLS>& lhs, const Matrix<DATA_TYPE, ROWS, COLS>& rhs )
00473 {
00474 return bool( !(lhs == rhs) );
00475 }
00476
00484 template <typename DATA_TYPE, unsigned ROWS, unsigned COLS>
00485 inline bool isEqual( const Matrix<DATA_TYPE, ROWS, COLS>& lhs, const Matrix<DATA_TYPE, ROWS, COLS>& rhs, const DATA_TYPE& eps = (DATA_TYPE)0 )
00486 {
00487 gmtlASSERT( eps >= (DATA_TYPE)0 );
00488
00489 for (unsigned int i = 0; i < ROWS*COLS; ++i)
00490 {
00491 if (!Math::isEqual( lhs.mData[i], rhs.mData[i], eps ))
00492 return false;
00493 }
00494 return true;
00495 }
00498 }
00499
00500 #endif