Documentation


linear.h

Go to the documentation of this file.
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 //typename container_traits<Cont>::value_type v_norm( const Cont& v )
00096 typename value_type<Cont>::type v_norm( const Cont& v )
00097 {
00098     //cout << "v_norm, v_dot(v,v)= "<<v_dot(v,v)<<endl;
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);//*(Yi) = (*Xi)*a;
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);//*(yi) += (*xi) * a;
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 //typename container_traits<Cont>::value_type v_dot( const Cont& x, const Cont& y )
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 // vector-vector operations
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 //  container_traits<Cont>::iterator Mi = begin(M), Mend=end(M);
00421 //  for( ; Mi!=Mend; ++Mi )
00422 //      v_assign(*Mi,a);
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 //void m_teq ( Cont& M, const typename matrix_traits<Cont>::value_type& a )
00432 void m_teq ( Cont& M, const Val& a )
00433 {
00434 //  container_traits<Cont>::iterator Mi = begin(M), Mend=end(M);
00435 //  for( ; Mi!=Mend; ++Mi )
00436 //      v_teq(*Mi,a);
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     //std::cout<<"r,c: "<<nrows(M)<<","<<ncols(M)<<std::endl;
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     //std::cout<<"m_eq_A OK"<<std::endl;
00467 }
00468 
00470 template<class Cont1, class Cont2> inline
00471 //void m_eq_aA ( Cont1& M, typename container_traits<typename container_traits<Cont1>::value_type>::value_type a, const Cont2& A )
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 /*template<class Cont> inline
00520 typename matrix_traits<Cont>::value_type m_det_A ( const Cont& A, int dim = -1 )
00521 {   
00522 
00523 
00524 
00525     Cont sous_m;
00526     typename matrix_traits<Cont>::value_type det = 0;
00527     if( dim == -1 ) dim = nrows(A);
00528     if( dim == 1 )  return ( A[0][0] );
00529     for(int l=0,signe=1 ; l<dim ; ++l)
00530     {
00531         for( int i=0, ld=0 ; i<dim ; i++ )
00532         {
00533             if( i!=l ) // delete the current line
00534             {
00535                 for( int c=1 ; c<dim ; c++ ) // begin at 1 to delete the first line
00536                     sous_m[ld][c-1] = A[i][c];
00537                 ld++;
00538             }
00539         det += signe*A[l][0] * m_det_A(sous_m,dim-1);
00540             signe=-signe;
00541         }
00542    }
00543     return(det);
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 // matrix-vector operations
01129 //========================================================================
01133 
01134 // LU
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     //(*b)[i].resize(j, k);
01378   }
01379   return 0;
01380 }
01381 
01382 
01383 
01384 
01385 
01386 
01387 // cholesky
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     //typedef container_traits<container_traits<M1>::value_type>::value_type Real;
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     //typedef container_traits<container_traits<M1>::value_type>::value_type Real;
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         // determine diagonal element
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     // determine off-diagonal elements
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     //typedef container_traits<container_traits<M1>::value_type>::value_type Real;
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]);  // determiant
01608 
01609     if (detval==0)  cerr<<"Cannot inverse a Singular Matrix."<<endl;
01610     else
01611     {
01612     
01613         /* transpose of the cofactors gives adjoint */
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 // linear equation solution
01655 //===========================================================================
01656 
01657 
01658 
01660 }//animal
01661 
01662 
01663 
01664 
01665 #endif
01666 

Generated on Thu Dec 23 13:52:25 2004 by doxygen 1.3.6