00001 
00008 #ifndef _MATRIX_H_
00009 #define _MATRIX_H_
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #define USE_TNT_MATRIX
00022 
00023 
00024 
00025 
00026 #include <numeric>
00027 
00028 
00029 #ifdef USE_TNT_MATRIX
00030 
00031 #define num_cols ncols
00032 #define num_rows nrows
00033 #include "tnt/tnt.h"
00034 #include "tnt/cmat.h"
00035 #include "tnt/vec.h"
00036 #include "tnt/region1d.h"
00037 #include "tnt/region2d.h"
00038 #undef  num_cols
00039 #undef  num_rows
00040 #endif
00041 
00042 
00043 #ifdef USE_MTL_MATRIX
00044 #include "mtl/mtl.h"
00045 #include "mtl/scaled2D.h"
00046 #include "mtl/matrix.h"
00047 #include "mtl/flatten_iterator.h"
00048 #include "mtl/flatten_iterator.h"
00050 #define MSEQ(container)      mtl::flatten_begin(container),mtl::flatten_end(container)
00051 
00052 #define CMSEQ(container)     mtl::const_flatten_begin(container),mtl::const_flatten_end(container)
00053 
00054 #define MTL_MSEQ(container)  mtl::flatten_begin(container),mtl::flatten_end(container)
00055 
00056 #define MTL_CMSEQ(container) mtl:::const_flatten_begin(container),mtl:::const_flatten_end(container)
00057 
00058 #define MBEGIN(container)    mtl::flatten_begin(container)
00059 
00060 #define CMBEGIN(container)   mtl::const_flatten_begin(container)
00061 #endif
00062 
00063 
00064 #ifdef USE_TNT_MATRIX
00065 
00066 #define SubMatrixType const_Region
00067 
00068 #define MatIndex(i) (i+1)
00069 
00070 #define UpperBound(i) (i)
00071 
00072 #else
00073 
00074 #define SubMatrixType submatrix_type
00075 
00076 #define MatIndex(i) (i)
00077 
00078 #define UpperBound(i) (i)
00079 #endif
00080 
00081 
00082 
00083 #ifndef  MSEQ
00084 
00085 #define  MSEQ(container) (container).begin(),(container).end()
00086 
00087 #define CMSEQ(container) (container).begin(),(container).end()
00088 
00089 #define  MBEGIN(container)  (container).begin()
00090 
00091 #define  CMBEGIN(container) (container).begin()
00092 #endif
00093 
00094 
00095 
00096 
00097 
00131 template<class T=double>
00132 struct MatrixType {
00133 
00134 
00135   
00136 #ifdef USE_MTL_MATRIX
00137   
00139   typedef typename mtl::matrix< T, mtl::rectangle<>, mtl::dense<>      >::type rectangular;
00141   typedef typename mtl::matrix< T, mtl::rectangle<>, mtl::dense<>      >::type circular;
00143   typedef typename mtl::matrix< T, mtl::rectangle<>, mtl::compressed<> >::type sparse;
00144 
00145 #else
00146   
00148   typedef TNT::Matrix<T> rectangular;
00150   typedef TNT::Matrix<T> circular;  
00152   typedef TNT::Matrix<T> sparse;  
00153 #endif
00154 
00155 };
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00167 namespace mtl {
00168 
00180 template <class Matrix> inline
00181 Matrix& operator*=(Matrix &A, const typename Matrix::value_type B)
00182 {  mtl::scale(A,B);  return A;  }
00183 
00184  
00185 
00186 template <class Matrix> inline
00187 Matrix& operator+=(Matrix &A, const typename Matrix::value_type B)
00188 {
00189   typedef typename Matrix::size_type Subscript;
00190 
00191   for (Subscript i=0; i<A.nrows(); i++)
00192     for (Subscript j=0; j<A.ncols(); j++)
00193       A[i][j] += B;
00194 
00195   return A;
00196 }
00197 
00198 
00199 template <class Matrix> inline
00200 Matrix& operator-=(Matrix &A, const typename Matrix::value_type B)
00201 {  return A += -1*B;  }
00202 
00203 
00205 } 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 #ifdef USE_TNT_MATRIX
00214 
00218 namespace TNT {
00219   
00226 template <class T>
00227 inline Matrix<T>& operator+=(Matrix<T>  &A, const T B)
00228 {
00229   for (Subscript i=0; i<A.nrows(); i++)
00230     for (Subscript j=0; j<A.ncols(); j++)
00231       A[i][j] += B;
00232 
00233   return A;
00234 }
00235 
00236 template <class T>
00237 inline Matrix<T>& operator-=(Matrix<T>  &A, const T B)
00238 {
00239   for (Subscript i=0; i<A.nrows(); i++)
00240     for (Subscript j=0; j<A.ncols(); j++)
00241       A[i][j] -= B;
00242 
00243   return A;
00244 }
00245 
00246 template <class T>
00247 inline Matrix<T>& operator*=(Matrix<T>  &A, const T B)
00248 {
00249   for (Subscript i=0; i<A.nrows(); i++)
00250     for (Subscript j=0; j<A.ncols(); j++)
00251       A[i][j] *= B;
00252 
00253   return A;
00254 }
00255 
00256 template <class T>
00257 inline Matrix<T> operator*(const Matrix<T>  &A, const T B)
00258 {
00259   Subscript M = A.nrows();
00260   Subscript N = A.ncols();
00261   
00262   Matrix<T> tmp(M,N);
00263   
00264   for (Subscript i=0; i<M; i++)
00265     for (Subscript j=0; j<N; j++)
00266       tmp[i][j] = A[i][j]*B; 
00267   
00268   return tmp;
00269 }
00270 
00271 template <class T> inline T sum(const Matrix<T>& A)
00272 {  return std::accumulate(A.begin(),A.end(),T(0));  }
00273  
00274 template <class T> inline T sum(const Vector<T>& A)
00275 {  return std::accumulate(A.begin(),A.end(),T(0));  }
00276  
00277 template <class T> inline T sum(const_Region2D< Matrix<T> >& A)
00278 {
00279   Subscript start = A.lbound();
00280   Subscript Mend  = A.lbound() + A.nrows() - 1;
00281   Subscript Nend  = A.lbound() + A.ncols() - 1;
00282   T partialsum = T(0);
00283   
00284   for (Subscript i=start; i<=Mend; i++)
00285     for (Subscript j=start; j<=Nend; j++)
00286         partialsum += A(i,j);
00287   
00288   return partialsum;
00289 }
00290 
00292 } 
00293 #endif
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00308 namespace mat {
00309 
00310   
00322 template <class Matrix, class InnerC, class OuterC> inline
00323 Matrix matrix_from_nested_containers(const OuterC& n, bool column_major=false)
00324 {
00325   typedef typename Matrix::size_type Subscript;
00326 
00327   
00328   Subscript max_minor = 0;
00329   for (typename OuterC::const_iterator i=n.begin(); i!=n.end(); i++) {
00330     const Subscript new_size =  (*i ? ((*i)->size()) : 0);
00331     if (new_size > max_minor) max_minor=new_size;
00332   }
00333 
00334   
00335   Matrix m((column_major? max_minor  : n.size()  ),
00336            (column_major? n.size()   : max_minor));
00337   int major=0;
00338   for (    typename OuterC::const_iterator i=n.begin();         i!=n.end(); i++,major++) {
00339     int minor=0;
00340     if (*i)
00341       for (typename InnerC::const_iterator j=(*i)->begin(); j!=(*i)->end(); j++,minor++) {
00342         if (column_major) 
00343           m[minor][major] = *j;
00344         else
00345           m[major][minor] = *j;
00346       }
00347   }
00348     
00349   return m;
00350 }
00351 
00352 
00353 
00356 template <class Matrix> inline
00357 typename Matrix::value_type
00358 sum(const Matrix& A)
00359 {  return std::accumulate(CMSEQ(A), typename Matrix::value_type(0) );  }
00360 
00361 
00362 
00364 template <class Matrix> inline
00365 typename Matrix::size_type
00366 size(const Matrix& A)
00367 {  return (A.nrows()*A.ncols());  }
00368 
00369 
00370 
00372 template <class Matrix> inline
00373 Matrix& set(Matrix &A, const typename Matrix::value_type B)
00374 {
00375   typedef typename Matrix::size_type Subscript;
00376 
00377   for (Subscript i=0; i<A.nrows(); i++)
00378     for (Subscript j=0; j<A.ncols(); j++)
00379       A[i][j] = B;
00380 
00381   return A;
00382 }
00383 
00384 
00385 
00387 template <class Matrix> inline
00388 typename Matrix::value_type elem(const Matrix &A, typename Matrix::size_type i, typename Matrix::size_type j)
00389 {
00390   return A(MatIndex(i),MatIndex(j));
00391 }
00392 
00393 
00394 
00402 template <class Matrix> inline
00403 const typename Matrix::SubMatrixType
00404 submatrix(const Matrix &A,
00405           typename Matrix::size_type i1, typename Matrix::size_type i2,
00406           typename Matrix::size_type j1, typename Matrix::size_type j2)
00407 {
00408 #ifdef USE_TNT_MATRIX
00409   TNT::Index1D I(MatIndex(i1),UpperBound(i2));
00410   TNT::Index1D J(MatIndex(j1),UpperBound(j2));  
00411   return A(I,J);
00412 #else
00413   return A.sub_matrix(MatIndex(i1),UpperBound(i2),MatIndex(j1),UpperBound(j2));
00414 #endif
00415 }
00416 
00417 
00418 
00420 #ifdef USE_TNT_MATRIX
00421 template <class T> inline
00422 TNT::Subscript
00423 size(TNT::const_Region2D< TNT::Matrix<T> >& A)
00424 {  return (A.lbound() + A.nrows() - 1)*(A.lbound() + A.ncols() - 1);  }
00425 #endif
00426  
00427 
00428 
00434 template <class Matrix>
00435 typename Matrix::value_type
00436 edge_average(const Matrix& mat)
00437 {
00438   typedef typename Matrix::value_type T;
00439   typedef typename Matrix::size_type  Subscript;
00440   
00441   Subscript X=mat.nrows();
00442   Subscript Y=mat.ncols();
00443 
00444   
00445   if (X<1 || Y<1) return T(0);
00446   
00447   typename Matrix::submatrix_type left   = mat.sub_matrix(0,   1,   0,   Y-1);
00448   typename Matrix::submatrix_type top    = mat.sub_matrix(1,   X,   0,   1  );
00449   typename Matrix::submatrix_type right  = mat.sub_matrix(X-1, X,   1,   Y  );
00450   typename Matrix::submatrix_type bottom = mat.sub_matrix(0,   X-1, Y-1, Y  );
00451 
00452   const T         total =  mat::sum(left)+  mat::sum(top)+  mat::sum(right)+  mat::sum(bottom);
00453   const Subscript count = mat::size(left)+ mat::size(top)+ mat::size(right)+ mat::size(bottom);
00454 
00455   return total/count;
00456 }
00457 
00458 
00463 #ifdef USE_TNT_MATRIX
00464 template <class T>
00465 T edge_average(const TNT::Matrix<T>& mat)
00466 {
00467   using namespace TNT;
00468   
00469   Subscript X=mat.nrows();
00470   Subscript Y=mat.ncols();
00471 
00472   
00473   if (X<2 || Y<2) return T(0);
00474   
00475   const_Region2D< Matrix<double> > left(   mat, 1, 1,   1, Y-1);
00476   const_Region2D< Matrix<double> > top(    mat, 2, X,   1, 1  );
00477   const_Region2D< Matrix<double> > right(  mat, X, X,   2, Y  );
00478   const_Region2D< Matrix<double> > bottom( mat, 1, X-1, Y, Y  );
00479 
00480   const T         total =  TNT::sum(left)+  TNT::sum(top)+  TNT::sum(right)+  TNT::sum(bottom);  
00481   const Subscript count = mat::size(left)+ mat::size(top)+ mat::size(right)+ mat::size(bottom);
00482 
00483   return total/count;
00484 }
00485 #endif
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 template <class Matrix> inline
00500 typename Matrix::size_type max_nrows(const Matrix &A)
00501 {
00502   typedef typename Matrix::size_type Subscript;
00503   Subscript val=0;
00504   
00505   for (Subscript i=0; i<A.nrows(); i++)
00506     for (Subscript j=0; j<A.ncols(); j++)
00507       if (mat::elem(A,i,j).nrows()>val)
00508         val = mat::elem(A,i,j).nrows();
00509 
00510   return val;
00511 }
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 template <class Matrix> inline
00520 typename Matrix::size_type max_ncols(const Matrix &A)
00521 {
00522   typedef typename Matrix::size_type Subscript;
00523   Subscript val=0;
00524   
00525   for (Subscript i=0; i<A.nrows(); i++)
00526     for (Subscript j=0; j<A.ncols(); j++)
00527       if (mat::elem(A,i,j).ncols()>val)
00528         val = mat::elem(A,i,j).ncols();
00529 
00530   return val;
00531 }
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 template <class Matrix> inline
00542 typename Matrix::size_type max_pnrows(const Matrix &A)
00543 {
00544   typedef typename Matrix::size_type Subscript;
00545   Subscript val=0;
00546   
00547   for (Subscript i=0; i<A.nrows(); i++)
00548     for (Subscript j=0; j<A.ncols(); j++) {
00549       typename Matrix::value_type p=mat::elem(A,i,j);
00550       if (p && (p->nrows()>val))
00551         val = p->nrows();
00552     }
00553   
00554   return val;
00555 }
00556 
00557 
00558 
00559 
00560 
00561 
00562 
00563 
00564 template <class Matrix> inline
00565 typename Matrix::size_type max_pncols(const Matrix &A)
00566 {
00567   typedef typename Matrix::size_type Subscript;
00568   Subscript val=0;
00569   
00570   for (Subscript i=0; i<A.nrows(); i++)
00571     for (Subscript j=0; j<A.ncols(); j++) {
00572       typename Matrix::value_type p=mat::elem(A,i,j);
00573       if (p && (p->ncols()>val))
00574         val = p->ncols();
00575     }
00576 
00577   return val;
00578 }
00579 
00581 template<class Matrix>
00582 void delete_contents(Matrix& A)
00583 {
00584   typedef typename Matrix::size_type Subscript;
00585   for (Subscript i=0; i<A.nrows(); i++)
00586     for (Subscript j=0; j<A.ncols(); j++)
00587       delete A[i][j];
00588 }
00589 
00590 
00593 template<class Matrix, class OutputStream>
00594 OutputStream& stream_output(const Matrix& A, OutputStream& stream)
00595 {
00596   typedef typename Matrix::size_type Subscript;
00597   for (Subscript i=0; i<A.nrows(); i++) {
00598     for (Subscript j=0; j<A.ncols(); j++)
00599       stream << mat::elem(A,i,j) << " ";
00600     stream << std::endl;
00601   }
00602 
00603   return stream;
00604 }
00605 
00608 template<class Matrix, class InputStream>
00609 InputStream& stream_input(Matrix& A, InputStream& stream)
00610 {
00611   typedef typename Matrix::size_type Subscript;
00612   for (Subscript i=0; i<A.nrows(); i++) {
00613     for (Subscript j=0; j<A.ncols(); j++)
00614       stream >> A[i][j];
00615   }
00616 
00617   return stream;
00618 }
00619 
00620 
00621 
00622 
00623 #undef UpperBound
00624 
00625 } 
00626 #endif