00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef TOON_INCLUDE_HELPERS_H
00033 #define TOON_INCLUDE_HELPERS_H
00034
00035 #include <TooN/TooN.h>
00036 #include <cmath>
00037 #include <functional>
00038 #include <utility>
00039
00040 #ifndef M_PI
00041 #define M_PI 3.14159265358979323846
00042 #endif
00043
00044 #ifndef M_SQRT1_2
00045 #define M_SQRT1_2 0.707106781186547524401
00046 #endif
00047
00048 namespace TooN {
00049
00052 template<int Size, class Precision, class Base> TOON_DEPRECATED void Fill(Vector<Size, Precision, Base>& v, const Precision& p)
00053 {
00054 for(int i=0; i < v.size(); i++)
00055 v[i]= p;
00056 }
00057
00060 template<int Rows, int Cols, class Precision, class Base> TOON_DEPRECATED void Fill(Matrix<Rows, Cols, Precision, Base>& m, const Precision& p)
00061 {
00062 for(int i=0; i < m.num_rows(); i++)
00063 for(int j=0; j < m.num_cols(); j++)
00064 m[i][j] = p;
00065 }
00066
00070 template<int Size, class Precision, class Base> inline Precision norm(const Vector<Size, Precision, Base>& v)
00071 {
00072 using std::sqrt;
00073 return sqrt(v*v);
00074 }
00075
00079 template<int Size, class Precision, class Base> inline Precision norm_sq(const Vector<Size, Precision, Base>& v)
00080 {
00081 return v*v;
00082 }
00083
00087 template<int Size, class Precision, class Base> inline Precision norm_1(const Vector<Size, Precision, Base>& v)
00088 {
00089 using std::abs;
00090 Precision n = 0;
00091 for(int i=0; i < v.size(); i++)
00092 n += abs(v[i]);
00093 return n;
00094 }
00095
00099 template<int Size, class Precision, class Base> inline Precision norm_inf(const Vector<Size, Precision, Base>& v)
00100 {
00101 using std::abs;
00102 using std::max;
00103 Precision n = 0;
00104 n = abs(v[0]);
00105
00106 for(int i=1; i < v.size(); i++)
00107 n = max(n, abs(v[i]));
00108 return n;
00109 }
00110
00115 template<int Size, class Precision, class Base> inline Precision norm_2(const Vector<Size, Precision, Base>& v)
00116 {
00117 return norm(v);
00118 }
00119
00120
00121
00122
00126 template<int Size, class Precision, class Base> inline Vector<Size, Precision> unit(const Vector<Size, Precision, Base> & v)
00127 {
00128 using std::sqrt;
00129 return v * (1/sqrt(v*v));
00130 }
00131
00132
00133
00134
00138 template<int Size, class Precision, class Base> inline void normalize(Vector<Size, Precision, Base> v)
00139 {
00140 using std::sqrt;
00141 v /= sqrt(v*v);
00142 }
00143
00144
00148 template<int Size, class Precision> inline void normalize(Vector<Size, Precision> & v)
00149 {
00150 normalize(v.as_slice());
00151 }
00152
00153
00157 template<int Size, typename Precision, typename Base> inline Vector<(Size==Dynamic?Dynamic:Size-1), Precision> project( const Vector<Size, Precision, Base> & v){
00158 static const int Len = (Size==Dynamic?Dynamic:Size-1);
00159 return v.template slice<0, Len>(0, v.size()-1) / v[v.size() - 1];
00160 }
00161
00162
00166 template<int Size, typename Precision, typename Base> inline Vector<(Size==Dynamic?Dynamic:Size+1), Precision> unproject( const Vector<Size, Precision, Base> & v){
00167 Vector<(Size==Dynamic?Dynamic:Size+1), Precision> result(v.size()+1);
00168 static const int Len = (Size==Dynamic?Dynamic:Size);
00169 result.template slice<0, Len>(0, v.size()) = v;
00170 result[v.size()] = 1;
00171 return result;
00172 }
00173
00177 template<int R, int C, typename Precision, typename Base> inline Matrix<R-1, C, Precision> project( const Matrix<R,C, Precision, Base> & m){
00178 Matrix<R-1, C, Precision> result = m.template slice(0,0,R-1,m.num_cols());
00179 for( int c = 0; c < m.num_cols(); ++c ) {
00180 result.slice(0,c,R-1,1) /= m[R-1][c];
00181 }
00182 return result;
00183 }
00184
00185 template<int C, typename Precision, typename Base> inline Matrix<-1, C, Precision> project( const Matrix<-1,C, Precision, Base> & m){
00186 Matrix<-1, C, Precision> result = m.template slice(0,0,m.num_rows()-1,m.num_cols());
00187 for( int c = 0; c < m.num_cols(); ++c ) {
00188 result.slice(0,c,m.num_rows()-1,1) /= m[m.num_rows()-1][c];
00189 }
00190 return result;
00191 }
00192
00196 template<int R, int C, typename Precision, typename Base> inline Matrix<R+1, C, Precision> unproject( const Matrix<R, C, Precision, Base> & m){
00197 Matrix<R+1, C, Precision> result;
00198 result.template slice<0,0,R,C>() = m;
00199 result[R] = Ones;
00200 return result;
00201 }
00202
00203 template<int C, typename Precision, typename Base> inline Matrix<-1, C, Precision> unproject( const Matrix<-1, C, Precision, Base> & m){
00204 Matrix<-1, C, Precision> result( m.num_rows()+1, m.num_cols() );
00205 result.template slice(0,0,m.num_rows(),m.num_cols()) = m;
00206 result[m.num_rows()] = Ones;
00207 return result;
00208 }
00209
00213 template <int R, int C, typename P, typename B>
00214 P inline norm_fro( const Matrix<R,C,P,B> & m ){
00215 using std::sqrt;
00216 P n = 0;
00217 for(int r = 0; r < m.num_rows(); ++r)
00218 for(int c = 0; c < m.num_cols(); ++c)
00219 n += m[r][c] * m[r][c];
00220
00221 return sqrt(n);
00222 }
00223
00227 template <int R, int C, typename P, typename B>
00228 P inline norm_inf( const Matrix<R,C,P,B> & m ){
00229 using std::abs;
00230 using std::max;
00231 P n = 0;
00232 for(int r = 0; r < m.num_rows(); ++r){
00233 P s = 0;
00234 for(int c = 0; c < m.num_cols(); ++c)
00235 s += abs(m(r,c));
00236 n = max(n,s);
00237 }
00238 return n;
00239 }
00240
00244 template <int R, int C, typename P, typename B>
00245 P inline norm_1( const Matrix<R,C,P,B> & m ){
00246 using std::abs;
00247 using std::max;
00248 P n = 0;
00249 for(int c = 0; c < m.num_cols(); ++c){
00250 P s = 0;
00251 for(int r = 0; r < m.num_rows(); ++r)
00252 s += abs(m(r,c));
00253 n = max(n,s);
00254 }
00255 return n;
00256 }
00257
00258 namespace Internal {
00262 template <int R, int C, typename P, typename B>
00263 inline Matrix<R, C, P> exp_taylor( const Matrix<R,C,P,B> & m ){
00264 TooN::SizeMismatch<R, C>::test(m.num_rows(), m.num_cols());
00265 Matrix<R,C,P> result = TooN::Zeros(m.num_rows(), m.num_cols());
00266 Matrix<R,C,P> f = TooN::Identity(m.num_rows());
00267 P k = 1;
00268 while(norm_inf((result+f)-result) > 0){
00269 result += f;
00270 f = (m * f) / k;
00271 k += 1;
00272 }
00273 return result;
00274 }
00275 };
00276
00283 template <int R, int C, typename P, typename B>
00284 inline Matrix<R, C, P> exp( const Matrix<R,C,P,B> & m ){
00285 using std::max;
00286 SizeMismatch<R, C>::test(m.num_rows(), m.num_cols());
00287 const P l = log2(norm_inf(m));
00288 const int s = max(0,(int)ceil(l));
00289 Matrix<R,C,P> result = Internal::exp_taylor(m/(1<<s));
00290 for(int i = 0; i < s; ++i)
00291 result = result * result;
00292 return result;
00293 }
00294
00297 template<int S, class P, class B> bool isfinite(const Vector<S, P, B>& v)
00298 {
00299 using std::isfinite;
00300 for(int i=0; i < v.size(); i++)
00301 if(!isfinite(v[i]))
00302 return 0;
00303 return 1;
00304 }
00305
00308 template<int S, class P, class B> bool isnan(const Vector<S, P, B>& v)
00309 {
00310 using std::isnan;
00311 for(int i=0; i < v.size(); i++)
00312 if(isnan(v[i]))
00313 return 1;
00314 return 0;
00315 }
00316
00321 template<int Rows, int Cols, typename Precision, typename Base>
00322 void Symmetrize(Matrix<Rows,Cols,Precision,Base>& m){
00323 SizeMismatch<Rows,Cols>::test(m.num_rows(), m.num_cols());
00324 for(int r=0; r<m.num_rows()-1; r++){
00325 for(int c=r+1; c<m.num_cols(); c++){
00326 const Precision temp=(m(r,c)+m(c,r))/2;
00327 m(r,c)=temp;
00328 m(c,r)=temp;
00329 }
00330 }
00331 }
00332
00335 template<int Rows, int Cols, typename Precision, typename Base>
00336 Precision trace(const Matrix<Rows, Cols, Precision, Base> & m ){
00337 SizeMismatch<Rows,Cols>::test(m.num_rows(), m.num_cols());
00338 Precision tr = 0;
00339 for(int i = 0; i < m.num_rows(); ++i)
00340 tr += m(i,i);
00341 return tr;
00342 }
00343
00348 template<int Size, class P, class B> inline TooN::Matrix<3, 3, P> cross_product_matrix(const Vector<Size, P, B>& vec)
00349 {
00350 SizeMismatch<Size,3>::test(vec.size(), 3);
00351
00352 TooN::Matrix<3> result;
00353
00354 result(0,0) = 0;
00355 result(0,1) = -vec[2];
00356 result(0,2) = vec[1];
00357 result(1,0) = vec[2];
00358 result(1,1) = 0;
00359 result(1,2) = -vec[0];
00360 result(2,0) = -vec[1];
00361 result(2,1) = vec[0];
00362 result(2,2) = 0;
00363
00364 return result;
00365 }
00366
00367 namespace Internal {
00368 template<int Size, typename Precision, typename Base, typename Func, typename Ret> inline Ret accumulate( const Vector<Size, Precision, Base> & v ) {
00369 Func func;
00370 if( v.size() == 0 ) {
00371 return func.null();
00372 }
00373 func.initialise( v[0], 0 );
00374 for( int ii = 1; ii < v.size(); ii++ ) {
00375 func( v[ii], ii );
00376 }
00377 return func.ret();
00378 }
00379
00380 template<int R, int C, typename Precision, typename Base, typename Func, typename Ret> inline Ret accumulate( const Matrix<R, C, Precision, Base> & m ) {
00381 Func func;
00382 if( m.num_rows() == 0 || m.num_cols() == 0) {
00383 return func.null();
00384 }
00385 func.initialise( m[0][0], 0, 0 );
00386 for(int r=0; r<m.num_rows(); r++){
00387 for(int c=0; c<m.num_cols(); c++){
00388 func( m[r][c], r, c );
00389 }
00390 }
00391 return func.ret();
00392 }
00393 template<int R, int C, typename Precision, typename Base, typename Func, typename Ret> inline Ret accumulate_horizontal( const Matrix<R, C, Precision, Base> & m ) {
00394 Func func( m.num_rows() );
00395 if( m.num_cols() == 0 || m.num_rows() == 0 ) {
00396 func.null();
00397 }
00398 for(int r=0; r<m.num_rows(); r++){
00399 func.initialise( m[r][0], r, 0 );
00400 for(int c=1; c<m.num_cols(); c++){
00401 func( m[r][c], r, c );
00402 }
00403 }
00404 return func.ret();
00405 }
00406 template<int R, int C, typename Precision, typename Base, typename Func, typename Ret> inline Ret accumulate_vertical( const Matrix<R, C, Precision, Base> & m ) {
00407 Func func( m.num_cols() );
00408 if( m.num_cols() == 0 || m.num_rows() == 0 ) {
00409 func.null();
00410 }
00411 for(int c=0; c<m.num_cols(); c++){
00412 func.initialise( m[0][c], 0, c );
00413 for(int r=1; r<m.num_rows(); r++){
00414 func( m[r][c], r, c );
00415 }
00416 }
00417 return func.ret();
00418 }
00419
00420 template<typename Precision, typename ComparisonFunctor>
00421 class accumulate_functor_vector {
00422 Precision bestVal;
00423 public:
00424 Precision null() {
00425 return 0;
00426 }
00427 void initialise( Precision initialVal, int ) {
00428 bestVal = initialVal;
00429 }
00430 void operator()( Precision curVal, int ) {
00431 if( ComparisonFunctor()( curVal, bestVal ) ) {
00432 bestVal = curVal;
00433 }
00434 }
00435 Precision ret() { return bestVal; }
00436 };
00437 template<typename Precision, typename ComparisonFunctor>
00438 class accumulate_element_functor_vector {
00439 Precision bestVal;
00440 int nBestIndex;
00441 public:
00442 std::pair<Precision,int> null() {
00443 return std::pair<Precision,int>( 0, 0 );
00444 }
00445 void initialise( Precision initialVal, int nIndex ) {
00446 bestVal = initialVal;
00447 nBestIndex = nIndex;
00448 }
00449 void operator()( Precision curVal, int nIndex ) {
00450 if( ComparisonFunctor()( curVal, bestVal ) ) {
00451 bestVal = curVal;
00452 nBestIndex = nIndex;
00453 }
00454 }
00455 std::pair<Precision,int> ret() {
00456 return std::pair<Precision,int>( bestVal, nBestIndex );
00457 }
00458 };
00459 template<typename Precision, typename ComparisonFunctor>
00460 class accumulate_functor_matrix {
00461 Precision bestVal;
00462 public:
00463 Precision null() {
00464 return 0;
00465 }
00466 void initialise( Precision initialVal, int, int ) {
00467 bestVal = initialVal;
00468 }
00469 void operator()( Precision curVal, int, int ) {
00470 if( ComparisonFunctor()( curVal, bestVal ) ) {
00471 bestVal = curVal;
00472 }
00473 }
00474 Precision ret() { return bestVal; }
00475 };
00476 template<typename Precision, typename ComparisonFunctor>
00477 class accumulate_element_functor_matrix {
00478 Precision bestVal;
00479 int nBestRow;
00480 int nBestCol;
00481 public:
00482 std::pair<Precision,std::pair<int,int> > null() {
00483 return std::pair<Precision,std::pair<int,int> >( 0, std::pair<int,int>( 0, 0 ) );
00484 }
00485 void initialise( Precision initialVal, int nRow, int nCol ) {
00486 bestVal = initialVal;
00487 nBestRow = nRow;
00488 nBestCol = nCol;
00489 }
00490 void operator()( Precision curVal, int nRow, int nCol ) {
00491 if( ComparisonFunctor()( curVal, bestVal ) ) {
00492 bestVal = curVal;
00493 nBestRow = nRow;
00494 nBestCol = nCol;
00495 }
00496 }
00497 std::pair<Precision,std::pair<int,int> > ret() {
00498 return std::pair<Precision,std::pair<int,int> >( bestVal,
00499 std::pair<int,int>( nBestRow, nBestCol ) );
00500 }
00501 };
00502 template<typename Precision, typename ComparisonFunctor>
00503 class accumulate_vertical_functor {
00504 Vector<Dynamic,Precision>* bestVal;
00505 public:
00506 accumulate_vertical_functor() {
00507 bestVal = NULL;
00508 }
00509 accumulate_vertical_functor( int nNumCols ) {
00510 bestVal = new Vector<Dynamic,Precision>( nNumCols );
00511 }
00512 Vector<Dynamic,Precision> null() {
00513 return Vector<Dynamic,Precision>( 0 );
00514 }
00515 void initialise( Precision initialVal, int, int nCol ) {
00516 (*bestVal)[nCol] = initialVal;
00517 }
00518 void operator()( Precision curVal, int, int nCol ) {
00519 if( ComparisonFunctor()( curVal, (*bestVal)[nCol] ) ) {
00520 (*bestVal)[nCol] = curVal;
00521 }
00522 }
00523 Vector<Dynamic,Precision> ret() {
00524 if( bestVal == NULL ) {
00525 return null();
00526 }
00527 Vector<Dynamic,Precision> vRet = *bestVal;
00528 delete bestVal;
00529 return vRet;
00530 }
00531 };
00532 template<typename Precision, typename ComparisonFunctor>
00533 class accumulate_element_vertical_functor {
00534 Vector<Dynamic,Precision>* bestVal;
00535 Vector<Dynamic,Precision>* bestIndices;
00536 public:
00537 accumulate_element_vertical_functor() {
00538 bestVal = NULL;
00539 bestIndices = NULL;
00540 }
00541 accumulate_element_vertical_functor( int nNumCols ) {
00542 bestVal = new Vector<Dynamic,Precision>( nNumCols );
00543 bestIndices = new Vector<Dynamic,Precision>( nNumCols );
00544 }
00545 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > null() {
00546 Vector<Dynamic,Precision> vEmpty( 0 );
00547 return std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> >( vEmpty, vEmpty );
00548 }
00549 void initialise( Precision initialVal, int nRow, int nCol ) {
00550 (*bestVal)[nCol] = initialVal;
00551 (*bestIndices)[nCol] = nRow;
00552 }
00553 void operator()( Precision curVal, int nRow, int nCol ) {
00554 if( ComparisonFunctor()( curVal, (*bestVal)[nCol] ) ) {
00555 (*bestVal)[nCol] = curVal;
00556 (*bestIndices)[nCol] = nRow;
00557 }
00558 }
00559 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > ret() {
00560 if( bestVal == NULL ) {
00561 return null();
00562 }
00563 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > vRet =
00564 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > (*bestVal, *bestIndices );
00565 delete bestVal; bestVal = NULL;
00566 delete bestIndices; bestIndices = NULL;
00567 return vRet;
00568 }
00569 };
00570 template<typename Precision, typename ComparisonFunctor>
00571 class accumulate_horizontal_functor {
00572 Vector<Dynamic,Precision>* bestVal;
00573 public:
00574 accumulate_horizontal_functor() {
00575 bestVal = NULL;
00576 }
00577 accumulate_horizontal_functor( int nNumRows ) {
00578 bestVal = new Vector<Dynamic,Precision>( nNumRows );
00579 }
00580 Vector<Dynamic,Precision> null() {
00581 return Vector<Dynamic,Precision>( 0 );
00582 }
00583 void initialise( Precision initialVal, int nRow, int ) {
00584 (*bestVal)[nRow] = initialVal;
00585 }
00586 void operator()( Precision curVal, int nRow, int ) {
00587 if( ComparisonFunctor()( curVal, (*bestVal)[nRow] ) ) {
00588 (*bestVal)[nRow] = curVal;
00589 }
00590 }
00591 Vector<Dynamic,Precision> ret() {
00592 if( bestVal == NULL ) {
00593 return null();
00594 }
00595 Vector<Dynamic,Precision> vRet = *bestVal;
00596 delete bestVal; bestVal = NULL;
00597 return vRet;
00598 }
00599 };
00600 template<typename Precision, typename ComparisonFunctor>
00601 class accumulate_element_horizontal_functor {
00602 Vector<Dynamic,Precision>* bestVal;
00603 Vector<Dynamic,Precision>* bestIndices;
00604 public:
00605 accumulate_element_horizontal_functor() {
00606 bestVal = NULL;
00607 bestIndices = NULL;
00608 }
00609 accumulate_element_horizontal_functor( int nNumRows ) {
00610 bestVal = new Vector<Dynamic,Precision>( nNumRows );
00611 bestIndices = new Vector<Dynamic,Precision>( nNumRows );
00612 }
00613 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > null() {
00614 Vector<Dynamic,Precision> vEmpty( 0 );
00615 return std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> >( vEmpty, vEmpty );
00616 }
00617 void initialise( Precision initialVal, int nRow, int nCol ) {
00618 (*bestVal)[nRow] = initialVal;
00619 (*bestIndices)[nRow] = nCol;
00620 }
00621 void operator()( Precision curVal, int nRow, int nCol ) {
00622 if( ComparisonFunctor()( curVal, (*bestVal)[nRow] ) ) {
00623 (*bestVal)[nRow] = curVal;
00624 (*bestIndices)[nRow] = nCol;
00625 }
00626 }
00627 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > ret() {
00628 if( bestVal == NULL ) {
00629 return null();
00630 }
00631 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > vRet =
00632 std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> >( *bestVal, *bestIndices );
00633 delete bestVal; bestVal = NULL;
00634 delete bestIndices; bestIndices = NULL;
00635 return vRet;
00636 }
00637 };
00638 }
00639
00640
00644 template<int Size, typename Precision, typename Base> inline Precision min_value( const Vector<Size, Precision, Base>& v) {
00645 typedef Internal::accumulate_functor_vector<Precision, std::less<Precision> > vector_accumulate_functor;
00646 return Internal::accumulate<Size,Precision,Base,
00647 vector_accumulate_functor, Precision >( v );
00648 }
00652 template<int Size, typename Precision, typename Base> inline Precision max_value( const Vector<Size, Precision, Base>& v) {
00653 typedef Internal::accumulate_functor_vector<Precision, std::greater<Precision> > vector_accumulate_functor;
00654 return Internal::accumulate<Size,Precision,Base,
00655 vector_accumulate_functor, Precision >( v );
00656 }
00657
00661 template<int R, int C, typename Precision, typename Base> inline Precision min_value( const Matrix<R, C, Precision, Base> & m) {
00662 typedef Internal::accumulate_functor_matrix<Precision, std::less<Precision> > matrix_accumulate_functor;
00663 return Internal::accumulate<R,C,Precision,Base,
00664 matrix_accumulate_functor, Precision>( m );
00665 }
00669 template<int R, int C, typename Precision, typename Base> inline Precision max_value( const Matrix<R, C, Precision, Base> & m) {
00670 typedef Internal::accumulate_functor_matrix<Precision, std::greater<Precision> > matrix_accumulate_functor;
00671 return Internal::accumulate<R,C,Precision,Base,
00672 matrix_accumulate_functor, Precision>( m );
00673 }
00677 template<int R, int C, typename Precision, typename Base> inline Vector<Dynamic,Precision> min_value_vertical( const Matrix<R, C, Precision, Base> & m) {
00678 typedef Internal::accumulate_vertical_functor<Precision,std::less<Precision> > matrix_accumulate_vertical_functor;
00679 return Internal::accumulate_vertical<R,C,Precision,Base,
00680 matrix_accumulate_vertical_functor, Vector<Dynamic,Precision> >( m );
00681 }
00685 template<int R, int C, typename Precision, typename Base> inline Vector<Dynamic,Precision> max_value_vertical( const Matrix<R, C, Precision, Base> & m) {
00686 typedef Internal::accumulate_vertical_functor<Precision,std::greater<Precision> > matrix_accumulate_vertical_functor;
00687 return Internal::accumulate_vertical<R,C,Precision,Base,
00688 matrix_accumulate_vertical_functor, Vector<Dynamic,Precision> >( m );
00689 }
00693 template<int R, int C, typename Precision, typename Base> inline Vector<Dynamic,Precision> min_value_horizontal( const Matrix<R, C, Precision, Base> & m) {
00694 typedef Internal::accumulate_horizontal_functor<Precision,std::less<Precision> > matrix_accumulate_horizontal_functor;
00695 return Internal::accumulate_horizontal<R,C,Precision,Base,
00696 matrix_accumulate_horizontal_functor, Vector<Dynamic,Precision> >( m );
00697 }
00701 template<int R, int C, typename Precision, typename Base> inline Vector<Dynamic,Precision> max_value_horizontal( const Matrix<R, C, Precision, Base> & m) {
00702 typedef Internal::accumulate_horizontal_functor<Precision,std::greater<Precision> > matrix_accumulate_horizontal_functor;
00703 return Internal::accumulate_horizontal<R,C,Precision,Base,
00704 matrix_accumulate_horizontal_functor, Vector<Dynamic,Precision> >( m );
00705 }
00709 template<int Size, typename Precision, typename Base> inline std::pair<Precision,int> min_element( const Vector<Size, Precision, Base>& v) {
00710 typedef Internal::accumulate_element_functor_vector<Precision, std::less<Precision> > vector_accumulate_functor;
00711 return Internal::accumulate<Size,Precision,Base,
00712 vector_accumulate_functor, std::pair<Precision,int> >( v );
00713 }
00717 template<int Size, typename Precision, typename Base> inline std::pair<Precision,int> max_element( const Vector<Size, Precision, Base>& v) {
00718 typedef Internal::accumulate_element_functor_vector<Precision, std::greater<Precision> > vector_accumulate_functor;
00719 return Internal::accumulate<Size,Precision,Base,
00720 vector_accumulate_functor, std::pair<Precision,int> >( v );
00721 }
00726 template<int R, int C, typename Precision, typename Base> inline std::pair<Precision,std::pair<int,int> > min_element( const Matrix<R, C, Precision, Base> & m) {
00727 typedef Internal::accumulate_element_functor_matrix<Precision, std::less<Precision> > matrix_accumulate_functor;
00728 typedef std::pair<Precision,std::pair<int,int> > Ret;
00729 return Internal::accumulate<R,C,Precision,Base,
00730 matrix_accumulate_functor, Ret>( m );
00731 }
00736 template<int R, int C, typename Precision, typename Base> inline std::pair<Precision,std::pair<int,int> > max_element( const Matrix<R, C, Precision, Base> & m) {
00737 typedef Internal::accumulate_element_functor_matrix<Precision, std::greater<Precision> > matrix_accumulate_functor;
00738 typedef std::pair<Precision,std::pair<int,int> > Ret;
00739 return Internal::accumulate<R,C,Precision,Base,
00740 matrix_accumulate_functor, Ret>( m );
00741 }
00747 template<int R, int C, typename Precision, typename Base> inline std::pair<Vector<Dynamic,Precision>,Vector<Dynamic,Precision> > min_element_vertical( const Matrix<R, C, Precision, Base> & m) {
00748 typedef Internal::accumulate_element_vertical_functor<Precision,std::less<Precision> > matrix_accumulate_vertical_functor;
00749 typedef std::pair<Vector< Dynamic, Precision >,Vector< Dynamic, Precision > > Ret;
00750 return Internal::accumulate_vertical<R,C,Precision,Base,
00751 matrix_accumulate_vertical_functor, Ret >( m );
00752 }
00758 template<int R, int C, typename Precision, typename Base> inline std::pair<Vector< Dynamic, Precision >,Vector< Dynamic, Precision > > max_element_vertical( const Matrix<R, C, Precision, Base> & m) {
00759 typedef Internal::accumulate_element_vertical_functor<Precision,std::greater<Precision> > matrix_accumulate_vertical_functor;
00760 typedef std::pair<Vector< Dynamic, Precision >,Vector< Dynamic, Precision > > Ret;
00761 return Internal::accumulate_vertical<R,C,Precision,Base,
00762 matrix_accumulate_vertical_functor, Ret >( m );
00763 }
00769 template<int R, int C, typename Precision, typename Base> inline std::pair<Vector< Dynamic, Precision >,Vector< Dynamic, Precision > > min_element_horizontal( const Matrix<R, C, Precision, Base> & m) {
00770 typedef Internal::accumulate_element_horizontal_functor<Precision,std::less<Precision> > matrix_accumulate_vertical_functor;
00771 typedef std::pair<Vector< Dynamic, Precision >,Vector< Dynamic, Precision > > Ret;
00772 return Internal::accumulate_horizontal<R,C,Precision,Base,
00773 matrix_accumulate_vertical_functor, Ret >( m );
00774 }
00780 template<int R, int C, typename Precision, typename Base> inline std::pair<Vector< Dynamic, Precision >,Vector< Dynamic, Precision > > max_element_horizontal( const Matrix<R, C, Precision, Base> & m) {
00781 typedef Internal::accumulate_element_horizontal_functor<Precision,std::greater<Precision> > matrix_accumulate_vertical_functor;
00782 typedef std::pair<Vector< Dynamic, Precision >,Vector< Dynamic, Precision > > Ret;
00783 return Internal::accumulate_horizontal<R,C,Precision,Base,
00784 matrix_accumulate_vertical_functor, Ret >( m );
00785 }
00786 }
00787 #endif