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