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 #include <creaSystem.h>
00033
00034 using namespace std;
00035
00036 namespace gtm
00037 {
00038
00039
00041
00042
00050 template< class T >
00051 inline
00052 void VectorPrint( std::ostream& o, T* v, uint32_t n, bool col )
00053 {
00054 uint32_t i;
00055
00056 o << n << ": [";
00057 if( col ) o << endl;
00058 else o << " ";
00059 for( uint32_t i = 0; i < n; i++ ) {
00060
00061 o << v[ i ];
00062 if( col ) o << endl;
00063 else o << " ";
00064
00065 }
00066 o << "]" << endl;
00067
00068 }
00069
00070
00075 template< class T >
00076 inline
00077 T* VectorAllocateMemory( uint32_t n )
00078 {
00079 T* v = new T[ n ];
00080
00081 memset( v, 0, sizeof( T ) * n );
00082 return( v );
00083
00084 }
00085
00086
00091 template< class T >
00092 inline
00093 void VectorFreeMemory( T* v )
00094 {
00095 if( v ) delete [] v;
00096
00097 }
00098
00099
00106 template< class T >
00107 inline
00108 void VectorAssignMemory( T* v, T* v_o, uint32_t n )
00109 {
00110 memcpy( v, v_o, sizeof( T ) * n );
00111
00112 }
00113
00114
00120 template< class T >
00121 inline
00122 T* VectorCopyMemory( T* v, uint32_t n )
00123 {
00124 T* n_v = VectorAllocateMemory< T >( n );
00125 VectorAssignMemory< T >( n_v, v, n );
00126 return( n_v );
00127
00128 }
00129
00130
00137 template< class T >
00138 inline
00139 void VectorAssignScalar( T* v, T s, uint32_t n )
00140 {
00141 uint32_t i;
00142
00143 for( i = 0; i < n; v[ i ] = s, i++ );
00144
00145 }
00146
00147
00156 template< class T >
00157 inline
00158 void VectorMatrixCast( T** ma, T* v, uint32_t n, uint32_t m, bool col )
00159 {
00160 uint32_t i;
00161
00162 for( i = 0; i < ( ( col )? m: n ); i++ )
00163 ma[ ( col )? n: i ][ ( col )? i: m ] = v[ i ];
00164
00165 }
00166
00167
00175 template< class T >
00176 inline
00177 void VectorAdd( T* v, T* v_l, T* v_r, uint32_t n )
00178 {
00179 uint32_t i;
00180
00181 for( i = 0; i < n; v[ i ] = v_l[ i ] + v_r[ i ], i++ );
00182
00183 }
00184
00185
00193 template< class T >
00194 inline
00195 void VectorSubtract( T* v, T* v_l, T* v_r, uint32_t n )
00196 {
00197 uint32_t i;
00198
00199 for( i = 0; i < n; v[ i ] = v_l[ i ] - v_r[ i ], i++ );
00200
00201 }
00202
00203
00210 template< class T >
00211 inline
00212 void VectorCrossProduct( T* v, T* v_l, T* v_r )
00213 {
00214 v[ 0 ] = ( v_l[ 1 ] * v_r[ 2 ] ) - ( v_l[ 2 ] * v_r[ 1 ] );
00215 v[ 1 ] = ( v_l[ 2 ] * v_r[ 0 ] ) - ( v_l[ 0 ] * v_r[ 2 ] );
00216 v[ 2 ] = ( v_l[ 0 ] * v_r[ 1 ] ) - ( v_l[ 1 ] * v_r[ 0 ] );
00217
00218 }
00219
00220
00228 template< class T >
00229 inline
00230 T VectorDotProduct( T* v_l, T* v_r, uint32_t n )
00231 {
00232 T ret;
00233 uint32_t i;
00234
00235 for( i = 0, ret = ( T )0; i < n; ret = ret + ( v_l[ i ] * v_r[ i ] ), i++ );
00236 return( ret );
00237
00238 }
00239
00240
00248 template< class T >
00249 inline
00250 void VectorScalarProduct( T* v, T* v_l, T s, uint32_t n )
00251 {
00252 uint32_t i;
00253
00254 for( i = 0; i < n; v[ i ] = v_l[ i ] * s, i++ );
00255
00256 }
00257
00258
00264 template< class T >
00265 inline
00266 T VectorNorm( T* v, uint32_t n )
00267 {
00268 return( ( T )( sqrt( ( double )( VectorDotProduct< T >( v, v, n ) ) ) ) );
00269
00270 }
00271
00272
00279 template< class T >
00280 inline
00281 void VectorNormalize( T* v, T* v_o, uint32_t n )
00282 {
00283 uint32_t i;
00284 T norm = VectorNorm< T >( v_o, n );
00285
00286 norm = ( norm == ( T )0 )? ( T )1: norm;
00287 for( i = 0; i < n; v[ i ] = v_o[ i ] / norm, i++ );
00288
00289 }
00290
00291
00293
00294
00295
00303 template< class T >
00304 inline
00305 void MatrixPrint( std::ostream& o, T** ma, uint32_t n, uint32_t m )
00306 {
00307 uint32_t i, j;
00308
00309 o << n << " x " << m << endl;
00310 for( j = 0; j < m; j++ ) {
00311
00312 for( i = 0; i < n; o << ma[ i ][ j ] << " ", i++ );
00313 o << endl;
00314
00315 }
00316
00317 }
00318
00319
00325 template< class T >
00326 inline
00327 T** MatrixAllocateMemory( uint32_t n, uint32_t m )
00328 {
00329 uint32_t i;
00330 T** ma = new T*[ n ];
00331
00332 for( i = 0; i < n; i++ ) {
00333
00334 ma[ i ] = new T[ m ];
00335 memset( ma[ i ], 0, sizeof( T ) * m );
00336
00337 }
00338 return( ma );
00339
00340 }
00341
00342
00350 template< class T >
00351 inline
00352 void MatrixAssignMemory( T** ma, T** ma_o, uint32_t n, uint32_t m )
00353 {
00354 uint32_t i;
00355
00356 for( i = 0; i < n; i++ )
00357 memcpy( ma[ i ], ma_o[ i ], sizeof( T ) * m );
00358
00359 }
00360
00361
00368 template< class T >
00369 inline
00370 T** MatrixCopyMemory( T** ma, uint32_t n, uint32_t m )
00371 {
00372 T** n_ma = MatrixAllocateMemory< T >( n, m );
00373 MatrixAssignMemory< T >( n_ma, ma, n, m );
00374 return( n_ma );
00375
00376 }
00377
00378
00386 template< class T >
00387 inline
00388 void MatrixAssignScalar( T** ma, T s, uint32_t n, uint32_t m )
00389 {
00390 uint32_t i, j;
00391
00392 for( i = 0; i < n; i++ )
00393 for( j = 0; j < m; j++ )
00394 ma[ i ][ j ] = s;
00395
00396 }
00397
00398
00407 template< class T >
00408 inline
00409 void MatrixVectorCast( T* v, T** ma, uint32_t n, uint32_t m, bool col )
00410 {
00411 uint32_t i;
00412
00413 for( i = 0; i < ( ( col )? m: n ); i++ )
00414 v[ i ] = ma[ ( col )? n: i ][ ( col )? i: m ];
00415
00416 }
00417
00418
00424 template< class T >
00425 inline
00426 void MatrixFreeMemory( T** ma, uint32_t n )
00427 {
00428 uint32_t i;
00429
00430 if( ma ) {
00431
00432 for( i = 0; i < n; i++ )
00433 if( ma[ i ] ) delete [] ma[ i ];
00434 delete [] ma;
00435
00436 }
00437
00438 }
00439
00440
00449 template< class T >
00450 inline
00451 void MatrixAdd( T** ma, T** ma_l, T** ma_r, uint32_t n, uint32_t m )
00452 {
00453 uint32_t i, j;
00454
00455 for( i = 0; i < n; i++ )
00456 for( j = 0; j < m; ma[ i ][ j ] = ma_l[ i ][ j ] + ma_r[ i ][ j ], j++ );
00457
00458 }
00459
00460
00469 template< class T >
00470 inline
00471 void MatrixSubtract( T** ma, T** ma_l, T** ma_r, uint32_t n, uint32_t m )
00472 {
00473 uint32_t i, j;
00474
00475 for( i = 0; i < n; i++ )
00476 for( j = 0; j < m; ma[ i ][ j ] = ma_l[ i ][ j ] - ma_r[ i ][ j ], j++ );
00477
00478 }
00479
00480
00490 template< class T >
00491 inline
00492 void MatrixProduct( T** ma, T** ma_l, T** ma_r, uint32_t n, uint32_t m, uint32_t nr )
00493 {
00494 unsigned i, j, k;
00495
00496 for( i = 0; i < nr; i++ )
00497 for( j = 0; j < m; j++ )
00498 for(
00499 k = 0, ma[ i ][ j ] = ( T )0;
00500 k < n;
00501 ma[ i ][ j ] = ma[ i ][ j ] + ( ma_l[ k ][ j ] * ma_r[ i ][ k ] ), k++
00502 );
00503
00504 }
00505
00506
00515 template< class T >
00516 inline
00517 void MatrixScalarProduct( T** ma, T** ma_l, T s, uint32_t n, uint32_t m )
00518 {
00519 uint32_t i, j;
00520
00521 for( i = 0; i < n; i++ )
00522 for( j = 0; j < m; ma[ i ][ j ] = ma_l[ i ][ j ] * s, j++ );
00523
00524 }
00525
00526
00536 template< class T >
00537 inline
00538 void MatrixCofactor( T** ma, T** ma_o, uint32_t i, uint32_t j, uint32_t n, uint32_t m )
00539 {
00540 uint32_t k, l;
00541
00542 for( k = 0; k < i; k++ ) {
00543
00544 for( l = 0; l < j; l++ ) ma[ k ][ l ] = ma_o[ k ][ l ];
00545 for( l = j + 1; l < m; l++ ) ma[ k ][ l - 1 ] = ma_o[ k ][ l ];
00546
00547 }
00548
00549 for( k = i + 1; k < n; k++ ) {
00550
00551 for( l = 0; l < j; l++ ) ma[ k - 1 ][ l ] = ma_o[ k ][ l ];
00552 for( l = j + 1; l < m; l++ ) ma[ k - 1 ][ l - 1 ] = ma_o[ k ][ l ];
00553
00554 }
00555
00556 }
00557
00558
00564 template< class T >
00565 inline
00566 T MatrixDeterminant( T** ma, uint32_t n )
00567 {
00568 uint32_t k;
00569 T** tmp = NULL;
00570 T ret = ( T )0, c;
00571
00572
00573 if( n == 1 ) {
00574
00575 ret = ma[ 0 ][ 0 ];
00576
00577 } else if( n == 2 ) {
00578
00579 ret =
00580 ( ma[ 0 ][ 0 ] * ma[ 1 ][ 1 ] ) -
00581 ( ma[ 1 ][ 0 ] * ma[ 0 ][ 1 ] );
00582
00583 } else if( n == 3 ) {
00584
00585 ret =
00586 ( ma[ 0 ][ 0 ] * ma[ 1 ][ 1 ] * ma[ 2 ][ 2 ] ) -
00587 ( ma[ 0 ][ 0 ] * ma[ 2 ][ 1 ] * ma[ 1 ][ 2 ] ) -
00588 ( ma[ 1 ][ 0 ] * ma[ 0 ][ 1 ] * ma[ 2 ][ 2 ] ) +
00589 ( ma[ 1 ][ 0 ] * ma[ 2 ][ 1 ] * ma[ 0 ][ 2 ] ) +
00590 ( ma[ 2 ][ 0 ] * ma[ 0 ][ 1 ] * ma[ 1 ][ 2 ] ) -
00591 ( ma[ 2 ][ 0 ] * ma[ 1 ][ 1 ] * ma[ 0 ][ 2 ] );
00592
00593 } else {
00594
00595 tmp = MatrixAllocateMemory< T >( n - 1, n - 1 );
00596 for( k = 0, c = ( T )1, ret = ( T )0; k < n; k++ ) {
00597
00598 MatrixCofactor< T >( tmp, ma, k, 0, n, n );
00599 ret = ret + ( c * ( ma[ k ][ 0 ] * MatrixDeterminant< T >( tmp, n - 1 ) ) );
00600 c = c * ( T )( 0 - 1 );
00601
00602 }
00603 MatrixFreeMemory< T >( tmp, n - 1 );
00604
00605 }
00606 return( ret );
00607
00608 }
00609
00610
00617 template< class T >
00618 inline
00619 void MatrixInverseAdjoint( T** ma, T** ma_o, uint32_t n )
00620 {
00621 uint32_t i, j;
00622 T** tmp;
00623 T c;
00624
00625 tmp = MatrixAllocateMemory< T >( n - 1, n - 1 );
00626 for( i = 0; i < n; i++ ) {
00627
00628 for( j = 0; j < n; j++ ) {
00629
00630 c = ( ( i + j ) % 2 == 0 )? ( T )1: ( T )( 0 - 1 );
00631 MatrixCofactor< T >( tmp, ma_o, i, j, n, n );
00632 ma[ j ][ i ] = c * MatrixDeterminant< T >( tmp, n - 1 );
00633
00634 }
00635
00636 }
00637 MatrixFreeMemory< T >( tmp, n - 1 );
00638
00639 c = ( T )1 / MatrixDeterminant< T >( ma_o, n );
00640 MatrixScalarProduct< T >( ma, ma, c, n, n );
00641
00642 }
00643
00644
00652 template< class T >
00653 inline
00654 void MatrixInverseGauss( T** ma, T** ma_o, uint32_t n )
00655 {
00656 uint32_t i, j, k, n2 = 2 * n;
00657 T** ma_a = MatrixAllocateMemory< T >( n2, n );
00658 T a, b;
00659
00660
00661 for( i = 0; i < n; i++ )
00662 for( j = 0; j < n; ma_a[ i ][ j ] = ma_o[ i ][ j ], j++ );
00663 for( i = n; i < n2; i++ )
00664 for( j = 0; j < n; ma_a[ i ][ j ] = ( i - n == j )? ( T )1: ( T )0, j++ );
00665
00666
00667 for( j = 0; j < n; j++ ) {
00668
00669 a = ma_a[ j ][ j ];
00670 if( a != 0 ) for( i = 0; i < n2; ma_a[ i ][ j ] = ma_a[ i ][ j ] / a, i++ );
00671 for( k = 0; k < n; k++ ) {
00672
00673 if( ( k - j ) != 0 ) {
00674
00675 b = ma_a[ j ][ k ];
00676 for(
00677 i = 0;
00678 i < n2;
00679 ma_a[ i ][ k ] = ma_a[ i ][ k ] - ( b * ma_a[ i ][ j ] ), i++
00680 );
00681
00682 }
00683
00684 }
00685
00686 }
00687
00688
00689 MatrixAssignMemory< T >( ma, ma_a, n, n );
00690 MatrixFreeMemory< T >( ma_a, n2 );
00691
00692 }
00693
00694
00702 template< class T >
00703 inline
00704 void MatrixTranspose( T** ma, T** ma_o, uint32_t n, uint32_t m )
00705 {
00706 uint32_t i, j;
00707
00708 for( i = 0; i < m; i++ )
00709 for( j = 0; j < n; ma[ i ][ j ] = ma_o[ j ][ i ], j++ );
00710
00711 }
00712
00713
00719 template< class T >
00720 inline
00721 void MatrixLoadIdentity( T** ma, uint32_t n )
00722 {
00723 uint32_t i, j;
00724
00725 for( i = 0; i < n; i++ )
00726 for( j = 0; j < n; ma[ i ][ j ] = ( i == j )? ( T )1: ( T )0, j++ );
00727
00728 }
00729
00730 }
00732
00733 #endif // GTMLIB__MATH__VMFUNCS__HXX
00734
00735