00001 #ifndef ____________animal_linear_h________________
00002 #define ____________animal_linear_h________________
00003
00014 #include <animal/container_traits.h>
00015 #include <assert.h>
00016 #include <math.h>
00017
00018
00019 namespace animal {
00020
00047
00048
00053
00058 template<class Cont, class Value> inline
00059 void v_assign( Cont& v, const Value& a )
00060 {
00061 typename container_traits<Cont>::iterator Yi = begin(v), Yend=end(v);
00062 for( ; Yi!=Yend; ++Yi )
00063 *(Yi) = a;
00064 }
00065
00070 template<class Cont, class Value> inline
00071 void v_addall( Cont& v, const Value& a )
00072 {
00073 typename container_traits<Cont>::iterator Yi = begin(v), Yend=end(v);
00074 for( ; Yi!=Yend; ++Yi )
00075 *(Yi) += a;
00076 }
00077
00082 template<class Cont,class Real> inline
00083 void v_teq ( Cont& v, const Real& a )
00084 {
00085 typename container_traits<Cont>::iterator Yi = begin(v), Yend=end(v);
00086 for( ; Yi!=Yend; ++Yi )
00087 *(Yi) *= a;
00088 }
00089
00094 template<class Cont> inline
00095
00096 typename value_type<Cont>::type v_norm( const Cont& v )
00097 {
00098
00099 return sqrt(v_dot(v,v));
00100 }
00101
00105 template<class Cont> inline
00106 void v_normalize( Cont& v )
00107 {
00108 v_teq(v,1/v_norm(v));
00109 }
00110
00115 template<class Cont> inline
00116 typename container_traits<Cont>::value_type v_norm1( const Cont& v )
00117 {
00118 typename container_traits<Cont const>::iterator xi = begin(v), xend=end(v);
00119 typename container_traits<Cont>::value_type d = 0;
00120 for( ; xi!=xend; ++xi )
00121 d += fabs(*xi);
00122 return d;
00123 }
00124
00129 template<class Cont> inline
00130 typename container_traits<Cont>::value_type v_normInf( const Cont& v )
00131 {
00132 typename container_traits<Cont const>::iterator xi = begin(v), xend=end(v);
00133 typename container_traits<Cont>::value_type d = 0;
00134 for( ; xi!=xend; ++xi )
00135 if( fabs(*xi) > d ) d = fabs(*xi);
00136 return d;
00137 }
00138
00139
00144 template<class Cont> inline
00145 typename container_traits<Cont>::value_type v_sum( const Cont& v )
00146 {
00147 typename container_traits<Cont const>::iterator xi = begin(v), xend=end(v);
00148 typename container_traits<Cont>::value_type d = 0;
00149 for( ; xi!=xend; ++xi )
00150 d += (*xi);
00151 return d;
00152 }
00153
00158 template<class Cont> inline
00159 typename container_traits<Cont>::value_type v_sqsum( const Cont& v )
00160 {
00161 typename container_traits<Cont const>::iterator xi = begin(v), xend=end(v);
00162 typename container_traits<Cont>::value_type d = 0;
00163 for( ; xi!=xend; ++xi )
00164 d += (*xi)*(*xi);
00165 return d;
00166 }
00167
00172 template<class Cont> inline
00173 typename container_traits<Cont>::value_type v_mean( const Cont& v )
00174 {
00175 return v_sum(v)/size(v);
00176 }
00177
00181 template<class Cont> inline
00182 typename container_traits<Cont>::value_type v_variance( const Cont& v )
00183 {
00184 typename container_traits<Cont const>::iterator xi = begin(v), xend=end(v);
00185 typename container_traits<Cont>::value_type m = v_mean(v);
00186 typename container_traits<Cont>::value_type d = 0;
00187 for( ; xi!=xend; ++xi )
00188 {
00189 typename container_traits<Cont>::value_type tmp = (*xi)-m;
00190 tmp*=tmp;
00191 d+=tmp;
00192 }
00193 return d/size(v);
00194 }
00195
00197
00202
00204 template<class Cont1, class Cont2> inline
00205 void v_eq ( Cont1& Y, const Cont2& X )
00206 {
00207 assert( size(Y)==size(X) );
00208 typename container_traits<Cont1>::iterator Yi = begin(Y), Yend=end(Y);
00209 typename container_traits<Cont2 const>::iterator Xi = begin(X);
00210 for( ; Yi!=Yend; ++Yi, ++Xi )
00211 *(Yi) = (*Xi);
00212 }
00213
00215 template<class Cont1, class Cont2> inline
00216 void v_eq_minus ( Cont1& Y, const Cont2& X )
00217 {
00218 assert( size(Y)==size(X) );
00219 typename container_traits<Cont1>::iterator Yi = begin(Y), Yend=end(Y);
00220 typename container_traits<Cont2 const>::iterator Xi = begin(X);
00221 for( ; Yi!=Yend; ++Yi, ++Xi )
00222 *(Yi) = -(*Xi);
00223 }
00224
00226 template<class Cont1, class Cont2, class Real> inline
00227 void v_eq_ab ( Cont1& Y, const Real& a, const Cont2& X )
00228 {
00229 assert( size(Y)==size(X) );
00230 typename container_traits<Cont1>::iterator Yi = begin(Y), Yend=end(Y);
00231 typename container_traits<Cont2 const>::iterator Xi = begin(X);
00232 for( ; Yi!=Yend; ++Yi, ++Xi )
00233 *(Yi) = a*(*Xi);
00234 }
00235
00237 template<class Cont1, class Cont2, class Cont3> inline
00238 void v_eq_apb ( Cont1& Y, const Cont2& W, const Cont3& X )
00239 {
00240 assert( size(Y)==size(X) );
00241 assert( size(Y)==size(W) );
00242 typename container_traits<Cont1>::iterator Yi = begin(Y), Yend=end(Y);
00243 typename container_traits<Cont2 const>::iterator Wi=begin(W);
00244 typename container_traits<Cont3 const>::iterator Xi = begin(X);
00245 for( ; Yi!=Yend; ++Yi, ++Xi, ++Wi )
00246 *(Yi) = (*Wi)+(*Xi);
00247 }
00248
00250 template<class Cont1, class Cont2, class Cont3> inline
00251 void v_eq_amb ( Cont1& Y, const Cont2& W, const Cont3& X )
00252 {
00253 assert( size(Y)==size(X) );
00254 assert( size(Y)==size(W) );
00255 typename container_traits<Cont1>::iterator Yi = begin(Y), Yend=end(Y);
00256 typename container_traits<Cont2 const>::iterator Wi=begin(W);
00257 typename container_traits<Cont3 const>::iterator Xi = begin(X);
00258 for( ; Yi!=Yend; ++Yi, ++Xi, ++Wi )
00259 *(Yi) = (*Wi)-(*Xi);
00260 }
00261
00263 template<class Cont1, class Cont2, class Cont3, class Entry> inline
00264 void v_eq ( Cont1& Y, const Cont2& W, const Entry& a, const Cont3& X )
00265 {
00266 assert( size(Y)==size(X) );
00267 assert( size(Y)==size(W) );
00268 typename container_traits<Cont1>::iterator Yi = begin(Y), Yend=end(Y);
00269 typename container_traits<Cont3 const>::iterator Xi = begin(X);
00270 typename container_traits<Cont2 const>::iterator Wi=begin(W);
00271 for( ; Yi!=Yend; ++Yi, ++Xi, ++Wi )
00272 *(Yi) = (*Wi)+a*(*Xi);
00273 }
00274
00276 template<class Cont1, class Cont2> inline
00277 void v_peq ( Cont1& Y, const Cont2& X )
00278 {
00279 assert( size(Y)==size(X) );
00280 typename container_traits<Cont1>::iterator Yi = begin(Y), Yend=end(Y);
00281 typename container_traits<Cont2 const>::iterator Xi = begin(X);
00282 for( ; Yi!=Yend; ++Yi, ++Xi )
00283 *(Yi) += (*Xi);
00284 }
00285
00287 template<class Cont> inline
00288 void v_meq ( Cont& Y, const Cont& X )
00289 {
00290 assert( size(Y)==size(X) );
00291 typename container_traits<Cont>::iterator Yi = begin(Y), Yend=end(Y);
00292 typename container_traits<Cont const>::iterator Xi = begin(X);
00293 for( ; Yi!=Yend; ++Yi, ++Xi )
00294 *(Yi) -= (*Xi);
00295 }
00296
00298 template<class Cont> inline
00299 void v_peq ( Cont& y, typename container_traits<Cont>::value_type a, const Cont& x )
00300 {
00301 assert( size(y)==size(x) );
00302 typename container_traits<Cont>::iterator yi = begin(y), yend=end(y);
00303 typename container_traits<Cont const>::iterator xi = begin(x);
00304 for( ; yi!=yend; ++xi, ++yi )
00305 *(yi) += a * (*xi);
00306 }
00307
00309 template<class Cont> inline
00310 void v_meq ( Cont& y, typename container_traits<Cont>::value_type a, const Cont& x )
00311 {
00312 assert( size(y)==size(x) );
00313 typename container_traits<Cont>::iterator yi = begin(y), yend=end(y);
00314 typename container_traits<Cont const>::iterator xi = begin(x);
00315 for( ; yi!=yend; ++xi, ++yi )
00316 *(yi) -= a * (*xi);
00317 }
00318
00320 template<class Cont,class Real> inline
00321 void v_peq_ab ( Cont& y, Real a, const Cont& x )
00322 {
00323 assert( size(y)==size(x) );
00324 typename container_traits<Cont>::iterator yi = begin(y), yend=end(y);
00325 typename container_traits<Cont const>::iterator xi = begin(x);
00326 for( ; yi!=yend; ++xi, ++yi )
00327 *(yi) += a * (*xi);
00328 }
00329
00331 template<class V1, class V2, class V3> inline
00332 void v_eq_cross ( V1&u, const V2& v, const V3& w )
00333 {
00334 assert( static_cast<const void*>(&u) != static_cast<const void*>(&v) );
00335 assert( static_cast<const void*>(&u) != static_cast<const void*>(&w) );
00336 assert( size(u)==size(v) );
00337 assert( size(u)==size(w) );
00338 const int n = size(u);
00339 for( int i=0, iend=n; i!=iend; ++i )
00340 u[(i+2)%n] = v[i]*w[(i+1)%n] -v[(i+1)%n]*w[i];
00341 }
00342
00344 template<class V1, class V2, class V3> inline
00345 void v_peq_cross ( V1&u, const V2& v, const V3& w )
00346 {
00347 assert( static_cast<const void*>(&u) != static_cast<const void*>(&v) );
00348 assert( static_cast<const void*>(&u) != static_cast<const void*>(&w) );
00349 assert( size(u)==size(v) );
00350 assert( size(u)==size(w) );
00351 const int n = size(u);
00352 for( int i=0, iend=n; i!=iend; ++i )
00353 u[(i+2)%n] += v[i]*w[(i+1)%n] -v[(i+1)%n]*w[i];
00354 }
00355
00357 template<class V1, class V2, class V3> inline
00358 void v_meq_cross ( V1&u, const V2& v, const V3& w )
00359 {
00360 assert( static_cast<const void*>(&u) != static_cast<const void*>(&v) );
00361 assert( static_cast<const void*>(&u) != static_cast<const void*>(&w) );
00362 assert( size(u)==size(v) );
00363 assert( size(u)==size(w) );
00364 const int n = size(u);
00365 for( int i=0, iend=n; i!=iend; ++i )
00366 u[(i+2)%n] -= v[i]*w[(i+1)%n] -v[(i+1)%n]*w[i];
00367 }
00368
00370 template<class Cont> inline
00371
00372 typename value_type<Cont>::type v_dot( const Cont& x, const Cont& y )
00373 {
00374 assert( size(x)==size(x) );
00375 typename container_traits<Cont const>::iterator yi = begin(y), yend=end(y);
00376 typename container_traits<Cont const>::iterator xi = begin(x);
00377 typename container_traits<Cont>::value_type d = 0;
00378 for( ; yi!=yend; ++xi, ++yi )
00379 d += *(yi) * (*xi);
00380 return d;
00381 }
00382
00384
00385
00391
00393 template<class M> inline
00394 std::size_t nrows( const M& m )
00395 {
00396 return container_traits<M const>::size(m);
00397 }
00398
00400 template<class M> inline
00401 std::size_t ncols( const M& m )
00402 {
00403 return container_traits<typename container_traits<M const>::value_type const>::size(m[0]);
00404 }
00405
00406
00408 template<class M>
00409 struct matrix_traits
00410 {
00412 typedef typename container_traits<typename container_traits<M>::value_type>::value_type value_type;
00413 };
00414
00415
00417 template<class Cont, class Value> inline
00418 void m_assign( Cont& M, const Value& a )
00419 {
00420
00421
00422
00423 for( int i=0, iend=nrows(M); i!=iend; ++i )
00424 for( int j=0, jend=ncols(M); j!=jend; ++j )
00425 M[i][j] =a;
00426 }
00427
00428
00430 template<class Cont, class Val> inline
00431
00432 void m_teq ( Cont& M, const Val& a )
00433 {
00434
00435
00436
00437 for( int i=0, iend=nrows(M); i!=iend; ++i )
00438 for( int j=0, jend=ncols(M); j!=jend; ++j )
00439 M[i][j] *=a;
00440 }
00441
00442
00444 template<class Cont, class Val> inline
00445 void m_deq ( Cont& M, const Val& a )
00446 {
00447 for( int i=0, iend=nrows(M); i!=iend; ++i )
00448 for( int j=0, jend=ncols(M); j!=jend; ++j )
00449 M[i][j] /=a;
00450 }
00451
00452
00453
00454
00455
00457 template<class Cont1, class Cont2> inline
00458 void m_eq_A ( Cont1& M, const Cont2& A )
00459 {
00460 assert( nrows(M)==nrows(A) );
00461 assert( ncols(M)==ncols(A) );
00462
00463 for( int i=0, iend=nrows(M); i!=iend; ++i )
00464 for( int j=0, jend=ncols(M); j!=jend; ++j )
00465 M[i][j] = A[i][j];
00466
00467 }
00468
00470 template<class Cont1, class Cont2> inline
00471
00472 void m_eq_aA ( Cont1& M, typename matrix_traits<Cont2>::value_type a, const Cont2& A )
00473 {
00474 assert( nrows(M)==nrows(A) );
00475 assert( ncols(M)==ncols(A) );
00476 for( int i=0, iend=nrows(M); i!=iend; ++i )
00477 for( int j=0, jend=ncols(M); j!=jend; ++j )
00478 M[i][j] = a * A[i][j];
00479 }
00480
00482 template<class Cont1, class Cont2> inline
00483 void m_peq_A ( Cont1& M, const Cont2& A )
00484 {
00485 assert( nrows(M)==nrows(A) );
00486 assert( ncols(M)==ncols(A) );
00487 for( int i=0, iend=nrows(M); i!=iend; ++i )
00488 for( int j=0, jend=ncols(M); j!=jend; ++j )
00489 M[i][j] += A[i][j];
00490 }
00491
00493 template<class Cont1, class Cont2> inline
00494 void m_peq_aA ( Cont1& M, typename matrix_traits<Cont2>::value_type a, const Cont2& A )
00495 {
00496 assert( nrows(M)==nrows(A) );
00497 assert( ncols(M)==ncols(A) );
00498 for( int i=0, iend=nrows(M); i!=iend; ++i )
00499 for( int j=0, jend=ncols(M); j!=jend; ++j )
00500 M[i][j] += a * A[i][j];
00501 }
00502
00504 template<class Cont1, class Cont2> inline
00505 void m_meq_A ( Cont1& M, const Cont2& A )
00506 {
00507 assert( nrows(M)==nrows(A) );
00508 assert( ncols(M)==ncols(A) );
00509 for( int i=0, iend=nrows(M); i!=iend; ++i )
00510 for( int j=0, jend=ncols(M); j!=jend; ++j )
00511 M[i][j] -= A[i][j];
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00552 template<class Cont1, class Cont2> inline
00553 void m_eq_At ( Cont1& M, const Cont2& A )
00554 {
00555 assert( nrows(M)==ncols(A) );
00556 assert( ncols(M)==nrows(A) );
00557 for( int i=0, iend=nrows(M); i!=iend; ++i )
00558 for( int j=0, jend=ncols(M); j!=jend; ++j )
00559 M[i][j] = A[j][i];
00560 }
00561
00563 template<class Cont1, class Cont2> inline
00564 void m_eq_aAt ( Cont1& M, typename matrix_traits<Cont2>::value_type a, const Cont2& A )
00565 {
00566 assert( nrows(M)==ncols(A) );
00567 assert( ncols(M)==nrows(A) );
00568 for( int i=0, iend=nrows(M); i!=iend; ++i )
00569 for( int j=0, jend=ncols(M); j!=jend; ++j )
00570 M[i][j] = a * A[j][i];
00571 }
00572
00574 template<class Cont1, class Cont2> inline
00575 void m_peq_At ( Cont1& M, const Cont2& A )
00576 {
00577 assert( nrows(M)==ncols(A) );
00578 assert( ncols(M)==nrows(A) );
00579 for( int i=0, iend=nrows(M); i!=iend; ++i )
00580 for( int j=0, jend=ncols(M); j!=jend; ++j )
00581 M[i][j] += A[j][i];
00582 }
00583
00585 template<class Cont1, class Cont2> inline
00586 void m_peq_aAt ( Cont1& M, const typename matrix_traits<Cont2>::value_type a, const Cont2& A )
00587 {
00588 assert( nrows(M)==ncols(A) );
00589 assert( ncols(M)==nrows(A) );
00590 for( int i=0, iend=nrows(M); i!=iend; ++i )
00591 for( int j=0, jend=ncols(M); j!=jend; ++j )
00592 M[i][j] += a * A[j][i];
00593 }
00594
00596 template<class Cont1, class Cont2> inline
00597 void m_meq_At ( Cont1& M, const Cont2& A )
00598 {
00599 assert( nrows(M)==ncols(A) );
00600 assert( ncols(M)==nrows(A) );
00601 for( int i=0, iend=nrows(M); i!=iend; ++i )
00602 for( int j=0, jend=ncols(M); j!=jend; ++j )
00603 M[i][j] -= A[j][i];
00604 }
00605
00606
00607
00608
00610
00615
00616
00618 template<class M1,class M2, class M3> inline
00619 void m_eq_AB ( M1& C, const M2& A, const M3& B )
00620 {
00621 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00622 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00623 assert( nrows(A)==nrows(C) );
00624 assert( ncols(B)==ncols(C) );
00625 assert( nrows(B)==ncols(A) );
00626 typedef std::size_t Int;
00627 for( Int i=0, n=nrows(A); i<n; ++i )
00628 for( Int j=0, m=ncols(B); j<m; ++j ){
00629 C[i][j] = 0;
00630 for( Int k=0, p=ncols(A); k<p; ++k )
00631 C[i][j] += A[i][k] * B[k][j];
00632 }
00633 }
00634
00636 template<class M1,class M2, class M3> inline
00637 void m_eq_aAB ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00638 {
00639 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00640 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00641 assert( nrows(A)==nrows(C) );
00642 assert( ncols(B)==ncols(C) );
00643 assert( nrows(B)==ncols(A) );
00644 typedef std::size_t Int;
00645 for( Int i=0, n=nrows(A); i<n; ++i )
00646 for( Int j=0, m=ncols(B); j<m; ++j ){
00647 C[i][j] = 0;
00648 for( Int k=0, p=ncols(A); k<p; ++k )
00649 C[i][j] += a * A[i][k] * B[k][j];
00650 }
00651 }
00652
00654 template<class M1,class M2, class M3> inline
00655 void m_peq_AB ( M1& C, const M2& A, const M3& B )
00656 {
00657 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00658 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00659 assert( nrows(A)==nrows(C) );
00660 assert( ncols(B)==ncols(C) );
00661 assert( nrows(B)==ncols(A) );
00662 typedef std::size_t Int;
00663 for( Int i=0, n=nrows(A); i<n; ++i )
00664 for( Int j=0, m=ncols(B); j<m; ++j )
00665 for( Int k=0, p=ncols(A); k<p; ++k )
00666 C[i][j] += A[i][k] * B[k][j];
00667 }
00668
00670 template<class M1,class M2, class M3> inline
00671 void m_peq_aAB ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00672 {
00673 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00674 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00675 assert( nrows(A)==nrows(C) );
00676 assert( ncols(B)==ncols(C) );
00677 assert( nrows(B)==ncols(A) );
00678 typedef std::size_t Int;
00679 for( Int i=0, n=nrows(A); i<n; ++i )
00680 for( Int j=0, m=ncols(B); j<m; ++j )
00681 for( Int k=0, p=ncols(A); k<p; ++k )
00682 C[i][j] += a * A[i][k] * B[k][j];
00683 }
00684
00686 template<class M1,class M2, class M3> inline
00687 void m_meq_AB ( M1& C, const M2& A, const M3& B )
00688 {
00689 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00690 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00691 assert( nrows(A)==nrows(C) );
00692 assert( ncols(B)==ncols(C) );
00693 assert( nrows(B)==ncols(A) );
00694 typedef std::size_t Int;
00695 for( Int i=0, n=nrows(A); i<n; ++i )
00696 for( Int j=0, m=ncols(B); j<m; ++j )
00697 for( Int k=0, p=ncols(A); k<p; ++k )
00698 C[i][j] -= A[i][k] * B[k][j];
00699 }
00700
00701
00702
00703
00705 template<class M1,class M2, class M3> inline
00706 void m_eq_ABt ( M1& C, const M2& A, const M3& B )
00707 {
00708 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00709 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00710 assert( nrows(A)==nrows(C) );
00711 assert( nrows(B)==ncols(C) );
00712 assert( ncols(B)==ncols(A) );
00713 typedef std::size_t Int;
00714 for( Int i=0, n=nrows(A); i<n; ++i )
00715 for( Int j=0, m=nrows(B); j<m; ++j )
00716 {
00717 C[i][j] = 0;
00718 for( Int k=0, p=ncols(A); k<p; ++k )
00719 C[i][j] += A[i][k] * B[j][k];
00720 }
00721 }
00722
00724 template<class M1,class M2, class M3> inline
00725 void m_eq_aABt ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00726 {
00727 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00728 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00729 assert( nrows(A)==nrows(C) );
00730 assert( nrows(B)==ncols(C) );
00731 assert( ncols(B)==ncols(A) );
00732 typedef std::size_t Int;
00733 for( Int i=0, n=nrows(A); i<n; ++i )
00734 for( Int j=0, m=nrows(B); j<m; ++j )
00735 {
00736 C[i][j] = 0;
00737 for( Int k=0, p=ncols(A); k<p; ++k )
00738 C[i][j] += a * A[i][k] * B[j][k];
00739 }
00740 }
00741
00743 template<class M1,class M2, class M3> inline
00744 void m_peq_ABt ( M1& C, const M2& A, const M3& B )
00745 {
00746 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00747 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00748 assert( nrows(A)==nrows(C) );
00749 assert( nrows(B)==ncols(C) );
00750 assert( ncols(B)==ncols(A) );
00751 typedef std::size_t Int;
00752 for( Int i=0, n=nrows(A); i<n; ++i )
00753 for( Int j=0, m=nrows(B); j<m; ++j )
00754 for( Int k=0, p=ncols(A); k<p; ++k )
00755 C[i][j] += A[i][k] * B[j][k];
00756 }
00757
00759 template<class M1,class M2, class M3> inline
00760 void m_peq_aABt ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00761 {
00762 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00763 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00764 assert( nrows(A)==nrows(C) );
00765 assert( nrows(B)==ncols(C) );
00766 assert( ncols(B)==ncols(A) );
00767 typedef std::size_t Int;
00768 for( Int i=0, n=nrows(A); i<n; ++i )
00769 for( Int j=0, m=nrows(B); j<m; ++j )
00770 for( Int k=0, p=ncols(A); k<p; ++k )
00771 C[i][j] += a * A[i][k] * B[j][k];
00772 }
00773
00775 template<class M1,class M2, class M3> inline
00776 void m_meq_ABt ( M1& C, const M2& A, const M3& B )
00777 {
00778 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00779 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00780 assert( nrows(A)==nrows(C) );
00781 assert( nrows(B)==ncols(C) );
00782 assert( ncols(B)==ncols(A) );
00783 typedef std::size_t Int;
00784 for( Int i=0, n=nrows(A); i<n; ++i )
00785 for( Int j=0, m=nrows(B); j<m; ++j )
00786 for( Int k=0, p=ncols(A); k<p; ++k )
00787 C[i][j] -= A[i][k] * B[j][k];
00788 }
00789
00790
00791
00793 template<class M1,class M2, class M3> inline
00794 void m_eq_AtB ( M1& C, const M2& A, const M3& B )
00795 {
00796 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00797 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00798 assert( ncols(A)==nrows(C) );
00799 assert( ncols(B)==ncols(C) );
00800 assert( nrows(B)==nrows(A) );
00801 typedef std::size_t Int;
00802 for( Int i=0, n=ncols(A); i<n; ++i )
00803 for( Int j=0, m=ncols(B); j<m; ++j ){
00804 C[i][j] = 0;
00805 for( Int k=0, p=nrows(A); k<p; ++k )
00806 C[i][j] += A[k][i] * B[k][j];
00807 }
00808 }
00809
00811 template<class M1,class M2, class M3> inline
00812 void m_eq_aAtB ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00813 {
00814 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00815 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00816 assert( ncols(A)==nrows(C) );
00817 assert( ncols(B)==ncols(C) );
00818 assert( nrows(B)==nrows(A) );
00819 typedef std::size_t Int;
00820 for( Int i=0, n=ncols(A); i<n; ++i )
00821 for( Int j=0, m=ncols(B); j<m; ++j ){
00822 C[i][j] = 0;
00823 for( Int k=0, p=nrows(A); k<p; ++k )
00824 C[i][j] += a * A[k][i] * B[k][j];
00825 }
00826 }
00827
00829 template<class M1,class M2, class M3> inline
00830 void m_peq_AtB ( M1& C, const M2& A, const M3& B )
00831 {
00832 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00833 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00834 assert( ncols(A)==nrows(C) );
00835 assert( ncols(B)==ncols(C) );
00836 assert( nrows(B)==nrows(A) );
00837 typedef std::size_t Int;
00838 for( Int i=0, n=ncols(A); i<n; ++i )
00839 for( Int j=0, m=ncols(B); j<m; ++j ){
00840 for( Int k=0, p=nrows(A); k<p; ++k )
00841 C[i][j] += A[k][i] * B[k][j];
00842 }
00843 }
00844
00846 template<class M1,class M2, class M3> inline
00847 void m_peq_aAtB ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00848 {
00849 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00850 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00851 assert( ncols(A)==nrows(C) );
00852 assert( ncols(B)==ncols(C) );
00853 assert( nrows(B)==nrows(A) );
00854 typedef std::size_t Int;
00855 for( Int i=0, n=ncols(A); i<n; ++i )
00856 for( Int j=0, m=ncols(B); j<m; ++j ){
00857 for( Int k=0, p=nrows(A); k<p; ++k )
00858 C[i][j] += a * A[k][i] * B[k][j];
00859 }
00860 }
00861
00863 template<class M1,class M2, class M3> inline
00864 void m_meq_AtB ( M1& C, const M2& A, const M3& B )
00865 {
00866 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00867 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00868 assert( ncols(A)==nrows(C) );
00869 assert( ncols(B)==ncols(C) );
00870 assert( nrows(B)==nrows(A) );
00871 typedef std::size_t Int;
00872 for( Int i=0, n=ncols(A); i<n; ++i )
00873 for( Int j=0, m=ncols(B); j<m; ++j ){
00874 for( Int k=0, p=nrows(A); k<p; ++k )
00875 C[i][j] -= A[k][i] * B[k][j];
00876 }
00877 }
00878
00879
00880
00882 template<class M1,class M2, class M3> inline
00883 void m_eq_AtBt ( M1& C, const M2& A, const M3& B )
00884 {
00885 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00886 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00887 assert( ncols(A)==nrows(C) );
00888 assert( nrows(B)==ncols(C) );
00889 assert( ncols(B)==nrows(A) );
00890 typedef std::size_t Int;
00891 for( Int i=0, n=ncols(A); i<n; ++i )
00892 for( Int j=0, m=nrows(B); j<m; ++j ){
00893 C[i][j] = 0;
00894 for( Int k=0, p=nrows(A); k<p; ++k )
00895 C[i][j] += A[k][i] * B[j][k];
00896 }
00897 }
00898
00900 template<class M1,class M2, class M3> inline
00901 void m_eq_aAtBt ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00902 {
00903 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00904 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00905 assert( ncols(A)==nrows(C) );
00906 assert( nrows(B)==ncols(C) );
00907 assert( ncols(B)==nrows(A) );
00908 typedef std::size_t Int;
00909 for( Int i=0, n=ncols(A); i<n; ++i )
00910 for( Int j=0, m=nrows(B); j<m; ++j ){
00911 C[i][j] = 0;
00912 for( Int k=0, p=nrows(A); k<p; ++k )
00913 C[i][j] += a * A[k][i] * B[j][k];
00914 }
00915 }
00916
00918 template<class M1,class M2, class M3> inline
00919 void m_peq_AtBt ( M1& C, const M2& A, const M3& B )
00920 {
00921 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00922 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00923 assert( ncols(A)==nrows(C) );
00924 assert( nrows(B)==ncols(C) );
00925 assert( ncols(B)==nrows(A) );
00926 typedef std::size_t Int;
00927 for( Int i=0, n=ncols(A); i<n; ++i )
00928 for( Int j=0, m=nrows(B); j<m; ++j ){
00929 for( Int k=0, p=nrows(A); k<p; ++k )
00930 C[i][j] += A[k][i] * B[j][k];
00931 }
00932 }
00933
00935 template<class M1,class M2, class M3> inline
00936 void m_peq_aAtBt ( M1& C, const typename matrix_traits<M2>::value_type a, const M2& A, const M3& B )
00937 {
00938 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00939 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00940 assert( ncols(A)==nrows(C) );
00941 assert( nrows(B)==ncols(C) );
00942 assert( ncols(B)==nrows(A) );
00943 typedef std::size_t Int;
00944 for( Int i=0, n=ncols(A); i<n; ++i )
00945 for( Int j=0, m=nrows(B); j<m; ++j ){
00946 for( Int k=0, p=nrows(A); k<p; ++k )
00947 C[i][j] += a * A[k][i] * B[j][k];
00948 }
00949 }
00950
00952 template<class M1,class M2, class M3> inline
00953 void m_meq_AtBt ( M1& C, const M2& A, const M3& B )
00954 {
00955 assert( static_cast<const void*>(&C) != static_cast<const void*>(&A) );
00956 assert( static_cast<const void*>(&C) != static_cast<const void*>(&B) );
00957 assert( ncols(A)==nrows(C) );
00958 assert( nrows(B)==ncols(C) );
00959 assert( ncols(B)==nrows(A) );
00960 typedef std::size_t Int;
00961 for( Int i=0, n=ncols(A); i<n; ++i )
00962 for( Int j=0, m=nrows(B); j<m; ++j ){
00963 for( Int k=0, p=nrows(A); k<p; ++k )
00964 C[i][j] -= A[k][i] * B[j][k];
00965 }
00966 }
00967
00969
00974
00975
00976
00977
00978
00979
00981 template<class V1, class M, class V2> inline
00982 void v_eq_Ab ( V1& v, const M& A, const V2& b )
00983 {
00984 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
00985 assert( ncols(A)==size(b) );
00986 assert( nrows(A)==size(v) );
00987 typedef std::size_t Int;
00988 for( Int i=0, n=nrows(A); i<n; ++i ){
00989 v[i] = 0;
00990 for( Int k=0, p=ncols(A); k<p; ++k )
00991 v[i] += A[i][k] * b[k];
00992 }
00993 }
00994
00996 template<class V1, class M, class V2> inline
00997 void v_eq_aAb ( V1& v, const typename matrix_traits<M>::value_type a, const M& A, const V2& b )
00998 {
00999 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01000 assert( ncols(A)==size(b) );
01001 assert( nrows(A)==size(v) );
01002 typedef std::size_t Int;
01003 for( Int i=0, n=nrows(A); i<n; ++i ){
01004 v[i] = 0;
01005 for( Int k=0, p=ncols(A); k<p; ++k )
01006 v[i] += a * A[i][k] * b[k];
01007 }
01008 }
01009
01011 template<class V1, class M, class V2> inline
01012 void v_peq_aAb ( V1& v, const typename matrix_traits<M>::value_type a, const M& A, const V2& b )
01013 {
01014 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01015 assert( ncols(A)==size(b) );
01016 assert( nrows(A)==size(v) );
01017 typedef std::size_t Int;
01018 for( Int i=0, n=nrows(A); i<n; ++i ){
01019 for( Int k=0, p=ncols(A); k<p; ++k )
01020 v[i] += a * A[i][k] * b[k];
01021 }
01022 }
01023
01025 template<class V1, class M, class V2> inline
01026 void v_peq_Ab ( V1& v, const M& A, const V2& b )
01027 {
01028 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01029 assert( ncols(A)==size(b) );
01030 assert( nrows(A)==size(v) );
01031 typedef std::size_t Int;
01032 for( Int i=0, n=nrows(A); i<n; ++i ){
01033 for( Int k=0, p=ncols(A); k<p; ++k )
01034 v[i] += A[i][k] * b[k];
01035 }
01036 }
01037
01039 template<class V1, class M, class V2> inline
01040 void v_meq_Ab ( V1& v, const M& A, const V2& b )
01041 {
01042 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01043 assert( ncols(A)==size(b) );
01044 assert( nrows(A)==size(v) );
01045 typedef std::size_t Int;
01046 for( Int i=0, n=nrows(A); i<n; ++i ){
01047 for( Int k=0, p=ncols(A); k<p; ++k )
01048 v[i] -= A[i][k] * b[k];
01049 }
01050 }
01051
01052
01053
01054
01056 template<class V1, class M, class V2> inline
01057 void v_eq_Atb ( V1& v, const M& A, const V2& b )
01058 {
01059 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01060 assert( nrows(A)==size(b) );
01061 assert( ncols(A)==size(v) );
01062 typedef std::size_t Int;
01063 for( Int i=0, n=ncols(A); i<n; ++i ){
01064 v[i] = 0;
01065 for( Int k=0, p=nrows(A); k<p; ++k )
01066 v[i] += A[k][i] * b[k];
01067 }
01068 }
01069
01071 template<class V1, class M, class V2> inline
01072 void v_eq_aAtb ( V1& v, const typename matrix_traits<M>::value_type a, const M& A, const V2& b )
01073 {
01074 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01075 assert( nrows(A)==size(b) );
01076 assert( ncols(A)==size(v) );
01077 typedef std::size_t Int;
01078 for( Int i=0, n=ncols(A); i<n; ++i ){
01079 v[i] = 0;
01080 for( Int k=0, p=nrows(A); k<p; ++k )
01081 v[i] += a * A[k][i] * b[k];
01082 }
01083 }
01084
01086 template<class V1, class M, class V2> inline
01087 void v_peq_aAtb ( V1& v, const typename matrix_traits<M>::value_type a, const M& A, const V2& b )
01088 {
01089 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01090 assert( nrows(A)==size(b) );
01091 assert( ncols(A)==size(v) );
01092 typedef std::size_t Int;
01093 for( Int i=0, n=ncols(A); i<n; ++i ){
01094 for( Int k=0, p=nrows(A); k<p; ++k )
01095 v[i] += a * A[k][i] * b[k];
01096 }
01097 }
01098
01100 template<class V1, class M, class V2> inline
01101 void v_peq_Atb ( V1& v, const M& A, const V2& b )
01102 {
01103 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01104 assert( nrows(A)==size(b) );
01105 assert( ncols(A)==size(v) );
01106 typedef std::size_t Int;
01107 for( Int i=0, n=ncols(A); i<n; ++i ){
01108 for( Int k=0, p=nrows(A); k<p; ++k )
01109 v[i] += A[k][i] * b[k];
01110 }
01111 }
01112
01114 template<class V1, class M, class V2> inline
01115 void v_meq_Atb ( V1& v, const M& A, const V2& b )
01116 {
01117 assert( static_cast<const void*>(&v) != static_cast<const void*>(&b) );
01118 assert( nrows(A)==size(b) );
01119 assert( ncols(A)==size(v) );
01120 typedef std::size_t Int;
01121 for( Int i=0, n=ncols(A); i<n; ++i ){
01122 for( Int k=0, p=nrows(A); k<p; ++k )
01123 v[i] -= A[k][i] * b[k];
01124 }
01125 }
01126
01128
01129
01133
01134
01139 template <class M1, class M2>
01140 void m_eq_ludcmp( M1& LU, const M2& A )
01141 {
01142 assert( static_cast<const void*>(&LU) != static_cast<const void*>(&A) );
01143 assert( nrows(A) == ncols(A) );
01144 assert( nrows(A) == ncols(LU) );
01145 assert( nrows(A) == nrows(LU) );
01146
01147 int i,j,k,n = nrows(A);
01148 for( i=0; i<n; ++i )
01149 {
01150 for (j=i; j<n; ++j)
01151 {
01152 LU[j][i] = A[j][i];
01153 for (k=0; k<i; ++k)
01154 {
01155 LU[j][i] -= LU[j][k]*LU[k][i];
01156 }
01157 }
01158 for (j=i+1; j<n; ++j)
01159 {
01160 LU[i][j] = A[i][j];
01161 for (k=0; k<i; ++k)
01162 {
01163 LU[i][j] -= LU[i][k]*LU[k][j];
01164 }
01165 LU[i][j] /= LU[i][i];
01166 }
01167 }
01168
01169 }
01170
01171
01172
01173
01174
01175
01179 template <class M, class V1, class V2> inline
01180 void v_eq_lusolve( V1& x, const M& LU, const V2& b )
01181 {
01182 assert( static_cast<const void*>(&x) != static_cast<const void*>(&b) );
01183 assert( nrows(LU) == ncols(LU) );
01184 assert( size(x) == ncols(LU) );
01185 assert( size(b) == nrows(LU) );
01186
01187 int i,j,n=nrows(LU);
01188 for( i=0; i<n; ++i )
01189 {
01190 x[i] = b[i];
01191 for( j=0; j<i; ++j )
01192 {
01193 x[i] -= LU[i][j]*x[j];
01194 }
01195 x[i] /= LU[i][i];
01196 }
01197 for( i=n-1; i>=0; --i )
01198 {
01199 for( j=i+1; j<n; ++j )
01200 {
01201 x[i] -= LU[i][j]*x[j];
01202 }
01203 }
01204 }
01205
01212 template <class M, class M2, class Vec>
01213 void m_eq_luinv( M& Inv, const M2& LU, Vec& aux )
01214 {
01215 assert( static_cast<const void*>(&Inv) != static_cast<const void*>(&LU));
01216 assert( nrows(LU) == ncols(LU) );
01217 assert( nrows(LU) == nrows(Inv) );
01218 assert( nrows(LU) == ncols(Inv) );
01219 assert( nrows(LU) == size(aux) );
01220
01221 int n=size(aux),i,j,k;
01222 for( k=0; k<n; ++k )
01223 {
01224 v_assign( aux, 0 ); aux[k] = 1;
01225 for( i=0; i<n; ++i )
01226 {
01227 Inv[i][k] = aux[i];
01228 for( j=0; j<i; ++j )
01229 {
01230 Inv[i][k] -= LU[i][j]*Inv[j][k];
01231 }
01232 Inv[i][k] /= LU[i][i];
01233 }
01234 for( i=n-1; i>=0; --i )
01235 {
01236 for( j=i+1; j<n; ++j )
01237 {
01238 Inv[i][k] -= LU[i][j]*Inv[j][k];
01239 }
01240 }
01241 }
01242 }
01243
01244
01245
01246
01247 template <class M, class M2>
01248 int ludcmp(M &a, M2 indx )
01249 {
01250 double d;
01251 int i, imax = 0, j, k;
01252 double big, dum, sum, temp;
01253 int n = nrows(a);
01254 typedef typename matrix_traits<M>::value_type Real;
01255 Real vv[n];
01256 d = 1.0;
01257 for (i = 0; i < n; i++)
01258 { big = 0.0;
01259 for (j = 0; j < n; j++)
01260 if ((temp = fabs(a[i][j])) > big)
01261 big = temp;
01262 if (big == 0.0)
01263 return -1;
01264 vv[i] = 1.0/big;
01265 }
01266 for (j = 0; j < n; j++)
01267 { for (i = 0; i < j; i++)
01268 { sum = a[i][j];
01269 for (k = 0; k < i; k++)
01270 sum -= a[i][k]*a[k][j];
01271 a[i][j] = sum;
01272 }
01273 big = 0.0;
01274 for (i = j; i < n; i++)
01275 { sum = a[i][j];
01276 for (k = 0; k < j; k++)
01277 sum -= a[i][k]*a[k][j];
01278 a[i][j] = sum;
01279 if ((dum = vv[i]*fabs(sum)) >= big)
01280 { big = dum;
01281 imax = i;
01282 }
01283 }
01284 if (j != imax)
01285 { for (k = 0; k < n; k++)
01286 { dum = a[imax][k];
01287 a[imax][k] = a[j][k];
01288 a[j][k] = dum;
01289 }
01290 d = -d;
01291 vv[imax] = vv[j];
01292 }
01293 indx[j] = imax;
01294 if (a[j][j] == 0.0)
01295 a[j][j] = 1.0e-20;
01296 if (j != n)
01297 { dum = 1.0/a[j][j];
01298 for (i = j+1; i < n; i++)
01299 a[i][j] *= dum;
01300 }
01301 }
01302 for (i = 0; i < n; i++)
01303 { for (j = 0; j < n; j++)
01304 if (fabs(a[i][j]) > 1.0e-15)
01305 break;
01306 for (k = n-1; k > j; k--)
01307 if (fabs(a[i][k]) > 1.0e-15)
01308 break;
01309 }
01310 return 0;
01311 }
01312
01313 template <class M, class M2, class M3>
01314 int lubksb(M &a, M2 indx, M3 b)
01315 { int i, j, k, ip, m, ii = 0;
01316 double sum;
01317 int n = nrows(a);
01318 for (i = 0; i < n; i++)
01319 { ip = indx[i];
01320 sum = b[ip];
01321 b[ip] = b[i];
01322 if (ii)
01323 { k = 0;
01324 if (ii > k)
01325 k = ii;
01326 m = n;
01327 if (i-1 < m)
01328 m = i-1;
01329 for (j = k; j < m; j++)
01330 sum -= a[i][j]*b[j];
01331 }
01332 else if (sum)
01333 ii = i;
01334 b[i] = sum;
01335 }
01336 for (i = n-1; i >= 0; i--)
01337 { sum = 0;
01338 k = 0;
01339 if (i+1 > k)
01340 k = i+1;
01341 m = n;
01342 if (n < m)
01343 m = n;
01344 for (j = k; j < m; j++)
01345 sum -= a[i][j]*b[j];
01346 b[i] = sum/a[i][i];
01347 }
01348 return 0;
01349 }
01350
01351 template <class M>
01352 int ns1__luinv(M &a, M &b)
01353 {
01354 int n = nrows(a);
01355 typedef typename matrix_traits<M>::value_type Real;
01356
01357 Real col[n];
01358 int indx[n];
01359 int i, j, k;
01360 if (ludcmp(a, indx))
01361 return 1;
01362 for (j = 0; j < n; j++)
01363 { for (i = 0; i < n; i++)
01364 col[i] = 0.0;
01365 col[j] = 1.0;
01366 lubksb(a, indx, col);
01367 for (i = 0; i < n; i++)
01368 b[i][j] = col[i];
01369 }
01370 for (i = 0; i < n; i++)
01371 { for (j = 0; j < n; j++)
01372 if (fabs(b[i][j]) > 1.0e-15)
01373 break;
01374 for (k = n-1; k > j; k--)
01375 if (fabs(b[i][k]) > 1.0e-15)
01376 break;
01377
01378 }
01379 return 0;
01380 }
01381
01382
01383
01384
01385
01386
01387
01388
01394 template <class M1, class M2> inline
01395 void m_eq_modchol( M1& L, const M2& A )
01396 {
01397 assert( static_cast<const void*>(&L) != static_cast<const void*>(&A) );
01398 assert( nrows(A) == ncols(A) );
01399 assert( nrows(A) == ncols(L) );
01400 assert( nrows(A) == nrows(L) );
01401
01402 typedef int Int;
01403
01404 typedef typename matrix_traits<M1>::value_type Real;
01405
01406 Int n = nrows(A);
01407 for( Int i=0; i<n; ++i )
01408 {
01409 Real sum = A[i][i];
01410 for( Int k=i-1; k>=0; --k )
01411 sum -= L[i][k]*L[i][k];
01412 if( sum <= 0 ) std::cerr<<"animal::m_eq_modchol nonpositive value " << sum << std::endl;
01413 L[i][i] = 1.0/sqrt(sum);
01414
01415 for( Int j=i+1; j<n; ++j )
01416 {
01417 Real sum = A[i][j];
01418 for( Int k=i-1; k>=0; --k )
01419 sum -= L[i][k]*L[j][k];
01420 L[j][i] = sum * L[i][i];
01421 }
01422 }
01423 }
01424
01425
01429 template <class M, class V1, class V2> inline
01430 void v_eq_cholsolve( V1& x, const M& L, const V2& b )
01431 {
01432 assert( static_cast<const void*>(&x) != static_cast<const void*>(&b) );
01433 assert( nrows(L) == ncols(L) );
01434 assert( size(x) == ncols(L) );
01435 assert( size(b) == nrows(L) );
01436
01437 typedef typename container_traits<V1>::value_type Real;
01438
01439 int i,k,n = size(x);
01440 for( i=0; i<n; ++i )
01441 {
01442 Real sum = b[i];
01443 for( k=i-1; k>=0; --k )
01444 sum -= L[i][k]*x[k];
01445 x[i] = sum * L[i][i];
01446 }
01447 for( i=n-1; i>=0; --i )
01448 {
01449 Real sum = x[i];
01450 for( k=i+1; k<n; ++k )
01451 sum -= L[k][i]*x[k];
01452 x[i] = sum * L[i][i];
01453 }
01454 }
01455
01464 template <class M, class M2, class M3> inline
01465 void m_eq_cholinv( M& Inv, const M2& A, M3& Tmp )
01466 {
01467 assert( static_cast<const void*>(&A) != static_cast<const void*>(&Tmp));
01468 assert( static_cast<const void*>(&Inv) != static_cast<const void*>(&Tmp));
01469 m_eq_invsqrt(Tmp,A);
01470 m_eq_AtB( Inv, Tmp, Tmp );
01471 }
01472
01473
01478 template <class M1, class M2> inline
01479 void m_eq_invsqrt(M1& B , const M2& A)
01480 {
01481 assert( static_cast<const void*>(&B) != static_cast<const void*>(&A) );
01482 assert( nrows(A) == ncols(A) );
01483 assert( nrows(B) == ncols(A) );
01484 assert( ncols(B) == ncols(A) );
01485
01486
01487 typedef typename matrix_traits<M1>::value_type Real;
01488
01489 m_eq_modchol(B,A);
01490
01491 int n=nrows(A);
01492 for( int i=0; i<n; ++i )
01493 for( int j=i+1; j<n; ++j )
01494 {
01495 Real sum = 0.0;
01496 for( int k=i; k<j; ++k )
01497 sum -= B[j][k]*B[k][i];
01498 B[j][i] = sum * B[j][j];
01499 B[i][j] = 0.0;
01500 }
01501 }
01502
01503
01504
01505
01506
01512 template <class M1, class M2> inline
01513 void m_eq_cholfactor( M1& L, const M2& A )
01514 {
01515 assert( static_cast<const void*>(&L) != static_cast<const void*>(&A) );
01516 assert( nrows(A) == ncols(A) );
01517 assert( nrows(A) == ncols(L) );
01518 assert( nrows(A) == nrows(L) );
01519
01520 int n = nrows(A);
01521 typedef typename matrix_traits<M1>::value_type Real;
01522
01523 for( int i = 0 ; i<n ; ++i)
01524 for( int j = 0 ; j<n ; ++j)
01525 L[i][j]=0;
01526
01527 for (int x = 0;x<n;x++)
01528 {
01529
01530 Real sum = A[x][x];
01531 for (int y = 0;y<x;y++)
01532 {
01533 Real value = L[x][y];
01534 sum -= value*value;
01535 }
01536 L[x][x] = sqrt(sum);
01537
01538
01539 for (int y = x+1;y<n;y++)
01540 {
01541 sum = A[y][x];
01542 for (int i = 0;i < x;i++)
01543 sum -= L[y][i]*L[x][i];
01544 L[y][x] = sum/L[x][x];
01545 }
01546 }
01547 }
01548
01549
01550
01551
01552
01553
01558 template <class M1, class M2> inline
01559 void m_eq_invsqrt2(M1& B , const M2& A)
01560 {
01561 assert( static_cast<const void*>(&B) != static_cast<const void*>(&A) );
01562 assert( nrows(A) == ncols(A) );
01563 assert( nrows(B) == ncols(A) );
01564 assert( ncols(B) == ncols(A) );
01565
01566
01567 typedef typename matrix_traits<M1>::value_type Real;
01568
01569 m_eq_cholfactor(B,A);
01570
01571 int n=nrows(A);
01572 for( int i=0; i<n; ++i )
01573 {
01574 B[i][i] = 1.0/A[i][i];
01575 for( int j=i+1; j<n; ++j )
01576 {
01577 Real sum = 0.0;
01578 for( int k=i; k<j-1; ++k )
01579 sum -= A[j][k]*A[k][i];
01580
01581 B[j][i] = sum / A[j][j];
01582 B[i][j] = 0.0;
01583 }
01584 }
01585 }
01586
01587
01588
01589
01594 template <class M1, class M2> inline
01595 void m_eq_inv(M1& B , const M2& A)
01596 {
01597 assert( static_cast<const void*>(&B) != static_cast<const void*>(&A) );
01598 assert( nrows(A) == 3 );
01599 assert( nrows(A) == 3 );
01600 assert( nrows(A) == ncols(A) );
01601 assert( nrows(B) == ncols(A) );
01602 assert( ncols(B) == ncols(A) );
01603
01604 typedef typename matrix_traits<M1>::value_type Real;
01605
01606
01607 float detval = (A[0][0]*A[1][1]*A[2][2] + A[1][0]*A[2][1]*A[0][2] + A[0][1]*A[1][2]*A[2][0]) - (A[2][0]*A[1][1]*A[0][2]+A[1][0]*A[0][1]*A[2][2]+A[2][1]*A[1][2]*A[0][0]);
01608
01609 if (detval==0) cerr<<"Cannot inverse a Singular Matrix."<<endl;
01610 else
01611 {
01612
01613
01614 B[0][0] = (A[1][1]*A[2][2] - A[1][2]*A[2][1]);
01615 B[0][1] = -1 * (A[0][1]*A[2][2] - A[0][2]*A[2][1]);
01616 B[0][2] = (A[0][1]*A[1][2] - A[0][2]*A[1][1]);
01617
01618 B[1][0] = -1 * (A[1][0]*A[2][2] - A[1][2]*A[2][0]);
01619 B[1][1] = (A[0][0]*A[2][2] - A[0][2]*A[2][0]);
01620 B[1][2] = -1 * (A[0][0]*A[1][2] - A[1][0]*A[0][2]);
01621
01622 B[2][0] = (A[1][0]*A[2][1] - A[1][1]*A[2][0]);
01623 B[2][1] = -1 * (A[0][0]*A[2][1] -A[0][1]*A[2][0]);
01624 B[2][2] = (A[0][0]*A[1][1] - A[0][1]*A[1][0]);
01625
01626
01627 B[0][0] = B[0][0] / detval;
01628 B[0][1] = B[0][1] / detval;
01629 B[0][2] = B[0][2] / detval;
01630
01631 B[1][0] = B[1][0] / detval;
01632 B[1][1] = B[1][1] / detval;
01633 B[1][2] = B[1][2] / detval;
01634
01635 B[2][0] = B[2][0] / detval;
01636 B[2][1] = B[2][1] / detval;
01637 B[2][2] = B[2][2] / detval;
01638 }
01639 }
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01654
01655
01656
01657
01658
01660 }
01661
01662
01663
01664
01665 #endif
01666