00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00023
00024 #ifndef GTMLIB__MATH__VMFUNCS__HXX
00025 #define GTMLIB__MATH__VMFUNCS__HXX
00026
00027 #include <iostream>
00028 #include <math.h>
00029 #include <memory.h>
00030 #include "mathdefs.h"
00031
00032 using namespace std;
00033
00034 namespace gtm
00035 {
00036
00037
00039
00040
00048 template< class T >
00049 inline
00050 void VectorPrint( std::ostream& o, T* v, uint n, bool col )
00051 {
00052 uint i;
00053
00054 o << n << ": [";
00055 if( col ) o << endl;
00056 else o << " ";
00057 for( uint i = 0; i < n; i++ ) {
00058
00059 o << v[ i ];
00060 if( col ) o << endl;
00061 else o << " ";
00062
00063 }
00064 o << "]" << endl;
00065
00066 }
00067
00068
00073 template< class T >
00074 inline
00075 T* VectorAllocateMemory( uint n )
00076 {
00077 T* v = new T[ n ];
00078
00079 memset( v, 0, sizeof( T ) * n );
00080 return( v );
00081
00082 }
00083
00084
00089 template< class T >
00090 inline
00091 void VectorFreeMemory( T* v )
00092 {
00093 if( v ) delete [] v;
00094
00095 }
00096
00097
00104 template< class T >
00105 inline
00106 void VectorAssignMemory( T* v, T* v_o, uint n )
00107 {
00108 memcpy( v, v_o, sizeof( T ) * n );
00109
00110 }
00111
00112
00118 template< class T >
00119 inline
00120 T* VectorCopyMemory( T* v, uint n )
00121 {
00122 T* n_v = VectorAllocateMemory< T >( n );
00123 VectorAssignMemory< T >( n_v, v, n );
00124 return( n_v );
00125
00126 }
00127
00128
00135 template< class T >
00136 inline
00137 void VectorAssignScalar( T* v, T s, uint n )
00138 {
00139 uint i;
00140
00141 for( i = 0; i < n; v[ i ] = s, i++ );
00142
00143 }
00144
00145
00154 template< class T >
00155 inline
00156 void VectorMatrixCast( T** ma, T* v, uint n, uint m, bool col )
00157 {
00158 uint i;
00159
00160 for( i = 0; i < ( ( col )? m: n ); i++ )
00161 ma[ ( col )? n: i ][ ( col )? i: m ] = v[ i ];
00162
00163 }
00164
00165
00173 template< class T >
00174 inline
00175 void VectorAdd( T* v, T* v_l, T* v_r, uint n )
00176 {
00177 uint i;
00178
00179 for( i = 0; i < n; v[ i ] = v_l[ i ] + v_r[ i ], i++ );
00180
00181 }
00182
00183
00191 template< class T >
00192 inline
00193 void VectorSubtract( T* v, T* v_l, T* v_r, uint n )
00194 {
00195 uint i;
00196
00197 for( i = 0; i < n; v[ i ] = v_l[ i ] - v_r[ i ], i++ );
00198
00199 }
00200
00201
00208 template< class T >
00209 inline
00210 void VectorCrossProduct( T* v, T* v_l, T* v_r )
00211 {
00212 v[ 0 ] = ( v_l[ 1 ] * v_r[ 2 ] ) - ( v_l[ 2 ] * v_r[ 1 ] );
00213 v[ 1 ] = ( v_l[ 2 ] * v_r[ 0 ] ) - ( v_l[ 0 ] * v_r[ 2 ] );
00214 v[ 2 ] = ( v_l[ 0 ] * v_r[ 1 ] ) - ( v_l[ 1 ] * v_r[ 0 ] );
00215
00216 }
00217
00218
00226 template< class T >
00227 inline
00228 T VectorDotProduct( T* v_l, T* v_r, uint n )
00229 {
00230 T ret;
00231 uint i;
00232
00233 for( i = 0, ret = ( T )0; i < n; ret = ret + ( v_l[ i ] * v_r[ i ] ), i++ );
00234 return( ret );
00235
00236 }
00237
00238
00246 template< class T >
00247 inline
00248 void VectorScalarProduct( T* v, T* v_l, T s, uint n )
00249 {
00250 uint i;
00251
00252 for( i = 0; i < n; v[ i ] = v_l[ i ] * s, i++ );
00253
00254 }
00255
00256
00262 template< class T >
00263 inline
00264 T VectorNorm( T* v, uint n )
00265 {
00266 return( ( T )( sqrt( ( double )( VectorDotProduct< T >( v, v, n ) ) ) ) );
00267
00268 }
00269
00270
00277 template< class T >
00278 inline
00279 void VectorNormalize( T* v, T* v_o, uint n )
00280 {
00281 uint i;
00282 T norm = VectorNorm< T >( v_o, n );
00283
00284 norm = ( norm == ( T )0 )? ( T )1: norm;
00285 for( i = 0; i < n; v[ i ] = v_o[ i ] / norm, i++ );
00286
00287 }
00288
00289
00291
00292
00293
00301 template< class T >
00302 inline
00303 void MatrixPrint( std::ostream& o, T** ma, uint n, uint m )
00304 {
00305 uint i, j;
00306
00307 o << n << " x " << m << endl;
00308 for( j = 0; j < m; j++ ) {
00309
00310 for( i = 0; i < n; o << ma[ i ][ j ] << " ", i++ );
00311 o << endl;
00312
00313 }
00314
00315 }
00316
00317
00323 template< class T >
00324 inline
00325 T** MatrixAllocateMemory( uint n, uint m )
00326 {
00327 uint i;
00328 T** ma = new T*[ n ];
00329
00330 for( i = 0; i < n; i++ ) {
00331
00332 ma[ i ] = new T[ m ];
00333 memset( ma[ i ], 0, sizeof( T ) * m );
00334
00335 }
00336 return( ma );
00337
00338 }
00339
00340
00348 template< class T >
00349 inline
00350 void MatrixAssignMemory( T** ma, T** ma_o, uint n, uint m )
00351 {
00352 uint i;
00353
00354 for( i = 0; i < n; i++ )
00355 memcpy( ma[ i ], ma_o[ i ], sizeof( T ) * m );
00356
00357 }
00358
00359
00366 template< class T >
00367 inline
00368 T** MatrixCopyMemory( T** ma, uint n, uint m )
00369 {
00370 T** n_ma = MatrixAllocateMemory< T >( n, m );
00371 MatrixAssignMemory< T >( n_ma, ma, n, m );
00372 return( n_ma );
00373
00374 }
00375
00376
00384 template< class T >
00385 inline
00386 void MatrixAssignScalar( T** ma, T s, uint n, uint m )
00387 {
00388 uint i, j;
00389
00390 for( i = 0; i < n; i++ )
00391 for( j = 0; j < m; j++ )
00392 ma[ i ][ j ] = s;
00393
00394 }
00395
00396
00405 template< class T >
00406 inline
00407 void MatrixVectorCast( T* v, T** ma, uint n, uint m, bool col )
00408 {
00409 uint i;
00410
00411 for( i = 0; i < ( ( col )? m: n ); i++ )
00412 v[ i ] = ma[ ( col )? n: i ][ ( col )? i: m ];
00413
00414 }
00415
00416
00422 template< class T >
00423 inline
00424 void MatrixFreeMemory( T** ma, uint n )
00425 {
00426 uint i;
00427
00428 if( ma ) {
00429
00430 for( i = 0; i < n; i++ )
00431 if( ma[ i ] ) delete [] ma[ i ];
00432 delete [] ma;
00433
00434 }
00435
00436 }
00437
00438
00447 template< class T >
00448 inline
00449 void MatrixAdd( T** ma, T** ma_l, T** ma_r, uint n, uint m )
00450 {
00451 uint i, j;
00452
00453 for( i = 0; i < n; i++ )
00454 for( j = 0; j < m; ma[ i ][ j ] = ma_l[ i ][ j ] + ma_r[ i ][ j ], j++ );
00455
00456 }
00457
00458
00467 template< class T >
00468 inline
00469 void MatrixSubtract( T** ma, T** ma_l, T** ma_r, uint n, uint m )
00470 {
00471 uint i, j;
00472
00473 for( i = 0; i < n; i++ )
00474 for( j = 0; j < m; ma[ i ][ j ] = ma_l[ i ][ j ] - ma_r[ i ][ j ], j++ );
00475
00476 }
00477
00478
00488 template< class T >
00489 inline
00490 void MatrixProduct( T** ma, T** ma_l, T** ma_r, uint n, uint m, uint nr )
00491 {
00492 unsigned i, j, k;
00493
00494 for( i = 0; i < nr; i++ )
00495 for( j = 0; j < m; j++ )
00496 for(
00497 k = 0, ma[ i ][ j ] = ( T )0;
00498 k < n;
00499 ma[ i ][ j ] = ma[ i ][ j ] + ( ma_l[ k ][ j ] * ma_r[ i ][ k ] ), k++
00500 );
00501
00502 }
00503
00504
00513 template< class T >
00514 inline
00515 void MatrixScalarProduct( T** ma, T** ma_l, T s, uint n, uint m )
00516 {
00517 uint i, j;
00518
00519 for( i = 0; i < n; i++ )
00520 for( j = 0; j < m; ma[ i ][ j ] = ma_l[ i ][ j ] * s, j++ );
00521
00522 }
00523
00524
00534 template< class T >
00535 inline
00536 void MatrixCofactor( T** ma, T** ma_o, uint i, uint j, uint n, uint m )
00537 {
00538 uint k, l;
00539
00540 for( k = 0; k < i; k++ ) {
00541
00542 for( l = 0; l < j; l++ ) ma[ k ][ l ] = ma_o[ k ][ l ];
00543 for( l = j + 1; l < m; l++ ) ma[ k ][ l - 1 ] = ma_o[ k ][ l ];
00544
00545 }
00546
00547 for( k = i + 1; k < n; k++ ) {
00548
00549 for( l = 0; l < j; l++ ) ma[ k - 1 ][ l ] = ma_o[ k ][ l ];
00550 for( l = j + 1; l < m; l++ ) ma[ k - 1 ][ l - 1 ] = ma_o[ k ][ l ];
00551
00552 }
00553
00554 }
00555
00556
00562 template< class T >
00563 inline
00564 T MatrixDeterminant( T** ma, uint n )
00565 {
00566 uint k;
00567 T** tmp = NULL;
00568 T ret = ( T )0, c;
00569
00570
00571 if( n == 1 ) {
00572
00573 ret = ma[ 0 ][ 0 ];
00574
00575 } else if( n == 2 ) {
00576
00577 ret =
00578 ( ma[ 0 ][ 0 ] * ma[ 1 ][ 1 ] ) -
00579 ( ma[ 1 ][ 0 ] * ma[ 0 ][ 1 ] );
00580
00581 } else if( n == 3 ) {
00582
00583 ret =
00584 ( ma[ 0 ][ 0 ] * ma[ 1 ][ 1 ] * ma[ 2 ][ 2 ] ) -
00585 ( ma[ 0 ][ 0 ] * ma[ 2 ][ 1 ] * ma[ 1 ][ 2 ] ) -
00586 ( ma[ 1 ][ 0 ] * ma[ 0 ][ 1 ] * ma[ 2 ][ 2 ] ) +
00587 ( ma[ 1 ][ 0 ] * ma[ 2 ][ 1 ] * ma[ 0 ][ 2 ] ) +
00588 ( ma[ 2 ][ 0 ] * ma[ 0 ][ 1 ] * ma[ 1 ][ 2 ] ) -
00589 ( ma[ 2 ][ 0 ] * ma[ 1 ][ 1 ] * ma[ 0 ][ 2 ] );
00590
00591 } else {
00592
00593 tmp = MatrixAllocateMemory< T >( n - 1, n - 1 );
00594 for( k = 0, c = ( T )1, ret = ( T )0; k < n; k++ ) {
00595
00596 MatrixCofactor< T >( tmp, ma, k, 0, n, n );
00597 ret = ret + ( c * ( ma[ k ][ 0 ] * MatrixDeterminant< T >( tmp, n - 1 ) ) );
00598 c = c * ( T )( 0 - 1 );
00599
00600 }
00601 MatrixFreeMemory< T >( tmp, n - 1 );
00602
00603 }
00604 return( ret );
00605
00606 }
00607
00608
00615 template< class T >
00616 inline
00617 void MatrixInverseAdjoint( T** ma, T** ma_o, uint n )
00618 {
00619 uint i, j;
00620 T** tmp;
00621 T c;
00622
00623 tmp = MatrixAllocateMemory< T >( n - 1, n - 1 );
00624 for( i = 0; i < n; i++ ) {
00625
00626 for( j = 0; j < n; j++ ) {
00627
00628 c = ( ( i + j ) % 2 == 0 )? ( T )1: ( T )( 0 - 1 );
00629 MatrixCofactor< T >( tmp, ma_o, i, j, n, n );
00630 ma[ j ][ i ] = c * MatrixDeterminant< T >( tmp, n - 1 );
00631
00632 }
00633
00634 }
00635 MatrixFreeMemory< T >( tmp, n - 1 );
00636
00637 c = ( T )1 / MatrixDeterminant< T >( ma_o, n );
00638 MatrixScalarProduct< T >( ma, ma, c, n, n );
00639
00640 }
00641
00642
00650 template< class T >
00651 inline
00652 void MatrixInverseGauss( T** ma, T** ma_o, uint n )
00653 {
00654 uint i, j, k, n2 = 2 * n;
00655 T** ma_a = MatrixAllocateMemory< T >( n2, n );
00656 T a, b;
00657
00658
00659 for( i = 0; i < n; i++ )
00660 for( j = 0; j < n; ma_a[ i ][ j ] = ma_o[ i ][ j ], j++ );
00661 for( i = n; i < n2; i++ )
00662 for( j = 0; j < n; ma_a[ i ][ j ] = ( i - n == j )? ( T )1: ( T )0, j++ );
00663
00664
00665 for( j = 0; j < n; j++ ) {
00666
00667 a = ma_a[ j ][ j ];
00668 if( a != 0 ) for( i = 0; i < n2; ma_a[ i ][ j ] = ma_a[ i ][ j ] / a, i++ );
00669 for( k = 0; k < n; k++ ) {
00670
00671 if( ( k - j ) != 0 ) {
00672
00673 b = ma_a[ j ][ k ];
00674 for(
00675 i = 0;
00676 i < n2;
00677 ma_a[ i ][ k ] = ma_a[ i ][ k ] - ( b * ma_a[ i ][ j ] ), i++
00678 );
00679
00680 }
00681
00682 }
00683
00684 }
00685
00686
00687 MatrixAssignMemory< T >( ma, ma_a, n, n );
00688 MatrixFreeMemory< T >( ma_a, n2 );
00689
00690 }
00691
00692
00700 template< class T >
00701 inline
00702 void MatrixTranspose( T** ma, T** ma_o, uint n, uint m )
00703 {
00704 uint i, j;
00705
00706 for( i = 0; i < m; i++ )
00707 for( j = 0; j < n; ma[ i ][ j ] = ma_o[ j ][ i ], j++ );
00708
00709 }
00710
00711
00717 template< class T >
00718 inline
00719 void MatrixLoadIdentity( T** ma, uint n )
00720 {
00721 uint i, j;
00722
00723 for( i = 0; i < n; i++ )
00724 for( j = 0; j < n; ma[ i ][ j ] = ( i == j )? ( T )1: ( T )0, j++ );
00725
00726 }
00727
00728 }
00730
00731 #endif // GTMLIB__MATH__VMFUNCS__HXX
00732
00733