Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

matrix.h

Go to the documentation of this file.
00001 
00008 #ifndef _MATRIX_H_
00009 #define _MATRIX_H_
00010 
00011 /*
00012   Choose at least one matrix package; currently MTL and TNT are
00013   supported.
00014 
00015   Enabling more than one package is legal and can be useful if you
00016   want to support more than one matrix implementation, e.g. for
00017   different source files.  Note that the type generator (by design)
00018   and the MSEQ definitions (due to MTL's broken iterator concept) only
00019   use a single implementation regardless.
00020 */
00021 #define USE_TNT_MATRIX
00022 //#define USE_MTL_MATRIX
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 #endif
00058 
00059 
00060 #ifdef USE_TNT_MATRIX
00061 
00062 #define SubMatrixType const_Region
00063 
00064 #define Index(i) (i+1)
00065 
00066 #define UpperBound(i) (i)
00067 
00068 #else
00069 
00070 #define SubMatrixType submatrix_type
00071 
00072 #define Index(i) (i)
00073 
00074 #define UpperBound(i) (i)
00075 #endif
00076 
00077 
00078 
00079 #ifndef  MSEQ
00080 
00081 #define  MSEQ(container) (container).begin(),(container).end()
00082 
00083 #define CMSEQ(container) (container).begin(),(container).end()
00084 #endif
00085 
00086 
00087 
00088 /******************************************************************************/
00089 /* Type generator                                                             */
00090 /******************************************************************************/
00124 template<class T=double>
00125 struct MatrixType {
00126 
00127 
00128   
00129 #ifdef USE_MTL_MATRIX
00130   /* Use MTL if available */
00132   typedef typename mtl::matrix< T, mtl::rectangle<>, mtl::dense<>      >::type rectangular;
00134   typedef typename mtl::matrix< T, mtl::rectangle<>, mtl::dense<>      >::type circular;
00136   typedef typename mtl::matrix< T, mtl::rectangle<>, mtl::compressed<> >::type sparse;
00137 
00138 #else
00139   /* Default to TNT */
00141   typedef TNT::Matrix<T> rectangular;
00143   typedef TNT::Matrix<T> circular;  
00145   typedef TNT::Matrix<T> sparse;  
00146 #endif
00147 
00148 };
00149 
00150 
00151 
00152 /******************************************************************************/
00153 /* Additional routines for namespace mtl                                      */
00154 /******************************************************************************/
00155 
00160 namespace mtl {
00161 
00173 template <class Matrix> inline
00174 Matrix& operator*=(Matrix &A, const typename Matrix::value_type B)
00175 {  mtl::scale(A,B);  return A;  }
00176 
00177  
00178 
00179 template <class Matrix> inline
00180 Matrix& operator+=(Matrix &A, const typename Matrix::value_type B)
00181 {
00182   typedef typename Matrix::size_type Subscript;
00183 
00184   for (Subscript i=0; i<A.nrows(); i++)
00185     for (Subscript j=0; j<A.ncols(); j++)
00186       A[i][j] += B;
00187 
00188   return A;
00189 }
00190 
00191 
00192 template <class Matrix> inline
00193 Matrix& operator-=(Matrix &A, const typename Matrix::value_type B)
00194 {  return A += -1*B;  }
00195 
00196 
00198 } /* namespace mtl */
00199 
00200 
00201 
00202 /******************************************************************************/
00203 /* Additional routines for namespace TNT                                      */
00204 /******************************************************************************/
00205 
00206 #ifdef USE_TNT_MATRIX
00207 
00211 namespace TNT {
00212   
00219 template <class T>
00220 inline Matrix<T>& operator+=(Matrix<T>  &A, const T B)
00221 {
00222   for (Subscript i=0; i<A.nrows(); i++)
00223     for (Subscript j=0; j<A.ncols(); j++)
00224       A[i][j] += B;
00225 
00226   return A;
00227 }
00228 
00229 template <class T>
00230 inline Matrix<T>& operator-=(Matrix<T>  &A, const T B)
00231 {
00232   for (Subscript i=0; i<A.nrows(); i++)
00233     for (Subscript j=0; j<A.ncols(); j++)
00234       A[i][j] -= B;
00235 
00236   return A;
00237 }
00238 
00239 template <class T>
00240 inline Matrix<T>& operator*=(Matrix<T>  &A, const T B)
00241 {
00242   for (Subscript i=0; i<A.nrows(); i++)
00243     for (Subscript j=0; j<A.ncols(); j++)
00244       A[i][j] *= B;
00245 
00246   return A;
00247 }
00248 
00249 template <class T>
00250 inline Matrix<T> operator*(const Matrix<T>  &A, const T B)
00251 {
00252   Subscript M = A.nrows();
00253   Subscript N = A.ncols();
00254   
00255   Matrix<T> tmp(M,N);
00256   
00257   for (Subscript i=0; i<M; i++)
00258     for (Subscript j=0; j<N; j++)
00259       tmp[i][j] = A[i][j]*B; 
00260   
00261   return tmp;
00262 }
00263 
00264 template <class T> inline T sum(const Matrix<T>& A)
00265 {  return accumulate(A.begin(),A.end(),T(0));  }
00266  
00267 template <class T> inline T sum(const Vector<T>& A)
00268 {  return accumulate(A.begin(),A.end(),T(0));  }
00269  
00270 template <class T> inline T sum(const_Region2D< Matrix<T> >& A)
00271 {
00272   Subscript start = A.lbound();
00273   Subscript Mend  = A.lbound() + A.nrows() - 1;
00274   Subscript Nend  = A.lbound() + A.ncols() - 1;
00275   T partialsum = T(0);
00276   
00277   for (Subscript i=start; i<=Mend; i++)
00278     for (Subscript j=start; j<=Nend; j++)
00279         partialsum += A(i,j);
00280   
00281   return partialsum;
00282 }
00283 
00285 } /* namespace TNT */
00286 #endif
00287 
00288 
00289 
00290 
00291 /******************************************************************************/
00292 /* Routines for namespace mat                                                 */
00293 /******************************************************************************/
00301 namespace mat {
00302 
00303   
00306 template <class Matrix> inline
00307 typename Matrix::value_type
00308 sum(const Matrix& A)
00309 {  return std::accumulate(CMSEQ(A), typename Matrix::value_type(0) );  }
00310 
00311 
00312 
00314 template <class Matrix> inline
00315 typename Matrix::size_type
00316 size(const Matrix& A)
00317 {  return (A.nrows()*A.ncols());  }
00318 
00319 
00320 
00322 template <class Matrix> inline
00323 Matrix& set(Matrix &A, const typename Matrix::value_type B)
00324 {
00325   typedef typename Matrix::size_type Subscript;
00326 
00327   for (Subscript i=0; i<A.nrows(); i++)
00328     for (Subscript j=0; j<A.ncols(); j++)
00329       A[i][j] = B;
00330 
00331   return A;
00332 }
00333 
00334 
00335 
00337 template <class Matrix> inline
00338 typename Matrix::value_type elem(const Matrix &A, typename Matrix::size_type i, typename Matrix::size_type j)
00339 {
00340   return A(Index(i),Index(j));
00341 }
00342 
00343 
00344 
00352 template <class Matrix> inline
00353 const typename Matrix::SubMatrixType
00354 submatrix(const Matrix &A,
00355           typename Matrix::size_type i1, typename Matrix::size_type i2,
00356           typename Matrix::size_type j1, typename Matrix::size_type j2)
00357 {
00358 #ifdef USE_TNT_MATRIX
00359   TNT::Index1D I(Index(i1),UpperBound(i2));
00360   TNT::Index1D J(Index(j1),UpperBound(j2));  
00361   return A(I,J);
00362 #else
00363   return A.sub_matrix(Index(i1),UpperBound(i2),Index(j1),UpperBound(j2));
00364 #endif
00365 }
00366 
00367 
00368 
00370 #ifdef USE_TNT_MATRIX
00371 template <class T> inline
00372 TNT::Subscript
00373 size(TNT::const_Region2D< TNT::Matrix<T> >& A)
00374 {  return (A.lbound() + A.nrows() - 1)*(A.lbound() + A.ncols() - 1);  }
00375 #endif
00376  
00377 
00378 
00384 template <class Matrix>
00385 typename Matrix::value_type
00386 edge_average(Matrix& mat)
00387 {
00388   typedef typename Matrix::value_type T;
00389   typedef typename Matrix::size_type  Subscript;
00390   
00391   Subscript X=mat.nrows();
00392   Subscript Y=mat.ncols();
00393 
00394   /* Return zero in case of empty matrix to avoid divide by zero */
00395   if (X<1 || Y<1) return T(0);
00396   
00397   typename Matrix::submatrix_type left   = mat.sub_matrix(0,   1,   0,   Y-1);
00398   typename Matrix::submatrix_type top    = mat.sub_matrix(1,   X,   0,   1  );
00399   typename Matrix::submatrix_type right  = mat.sub_matrix(X-1, X,   1,   Y  );
00400   typename Matrix::submatrix_type bottom = mat.sub_matrix(0,   X-1, Y-1, Y  );
00401 
00402   const T         total =  mat::sum(left)+  mat::sum(top)+  mat::sum(right)+  mat::sum(bottom);
00403   const Subscript count = mat::size(left)+ mat::size(top)+ mat::size(right)+ mat::size(bottom);
00404 
00405   return total/count;
00406 }
00407 
00408 
00413 #ifdef USE_TNT_MATRIX
00414 template <class T>
00415 T edge_average(TNT::Matrix<T>& mat)
00416 {
00417   using namespace TNT;
00418   
00419   Subscript X=mat.nrows();
00420   Subscript Y=mat.ncols();
00421 
00422   /* Image must be at least 2x2 to have an edge */
00423   if (X<2 || Y<2) return T(0);
00424   
00425   const_Region2D< Matrix<double> > left(   mat, 1, 1,   1, Y-1);
00426   const_Region2D< Matrix<double> > top(    mat, 2, X,   1, 1  );
00427   const_Region2D< Matrix<double> > right(  mat, X, X,   2, Y  );
00428   const_Region2D< Matrix<double> > bottom( mat, 1, X-1, Y, Y  );
00429 
00430   const T         total =  TNT::sum(left)+  TNT::sum(top)+  TNT::sum(right)+  TNT::sum(bottom);  
00431   const Subscript count = mat::size(left)+ mat::size(top)+ mat::size(right)+ mat::size(bottom);
00432 
00433   return total/count;
00434 }
00435 #endif
00436 
00437 
00438 /* Returns the maximum num_rows of any element in the given matrix or region.
00439    
00440   There may be a way to code this using a generic mem_fun() call, but
00441   it wasn't obvious how to specify that call since we don't know the
00442   actual Matrix::value_type, i.e. the type of an element.
00443 */
00444 template <class Matrix> inline
00445 typename Matrix::size_type max_nrows(Matrix &A)
00446 {
00447   typedef typename Matrix::size_type Subscript;
00448   Subscript val=0;
00449   
00450   for (Subscript i=0; i<A.nrows(); i++)
00451     for (Subscript j=0; j<A.ncols(); j++)
00452       if (mat::elem(A,i,j).nrows()>val)
00453         val = mat::elem(A,i,j).nrows();
00454 
00455   return val;
00456 }
00457 
00458 
00459 
00460 /* Returns the maximum num_cols of any element in the given matrix or region.
00461    
00462   As for max_nrows, this routine *should* be unnecessary.
00463 */
00464 template <class Matrix> inline
00465 typename Matrix::size_type max_ncols(Matrix &A)
00466 {
00467   typedef typename Matrix::size_type Subscript;
00468   Subscript val=0;
00469   
00470   for (Subscript i=0; i<A.nrows(); i++)
00471     for (Subscript j=0; j<A.ncols(); j++)
00472       if (mat::elem(A,i,j).ncols()>val)
00473         val = mat::elem(A,i,j).ncols();
00474 
00475   return val;
00476 }
00477 
00478 
00479 /* Avoid namespace pollution */
00480 #undef Index
00481 #undef UpperBound
00482 
00483 } /* namespace mat */
00484 #endif

Generated at Mon Aug 21 00:30:54 2000 for RF-LISSOM by doxygen1.2.1 written by Dimitri van Heesch, © 1997-2000