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 #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
00090
00124 template<class T=double>
00125 struct MatrixType {
00126
00127
00128
00129 #ifdef USE_MTL_MATRIX
00130
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
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
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 }
00199
00200
00201
00202
00203
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 }
00286 #endif
00287
00288
00289
00290
00291
00292
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
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
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 00439 00440 00441 00442 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 00461 00462 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
00480 #undef Index
00481 #undef UpperBound
00482
00483 }
00484 #endif