ICRS Eurobot 2013

Dependencies:   mbed mbed-rtos Servo QEI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MatrixFunctions.h Source File

MatrixFunctions.h

00001 /*
00002  * Tiny Vector Matrix Library
00003  * Dense Vector Matrix Libary of Tiny size using Expression Templates
00004  *
00005  * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * $Id: MatrixFunctions.h,v 1.65 2007-06-23 15:58:58 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_MATRIX_FUNCTIONS_H
00025 #define TVMET_MATRIX_FUNCTIONS_H
00026 
00027 #include <tvmet/Extremum.h>
00028 
00029 namespace tvmet {
00030 
00031 /* forwards */
00032 template<class T, std::size_t Sz> class Vector;
00033 template<class T, std::size_t Sz> class VectorConstReference;
00034 
00035 
00036 /*********************************************************
00037  * PART I: DECLARATION
00038  *********************************************************/
00039 
00040 
00041 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00042  * Vector arithmetic functions add, sub, mul and div
00043  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00044 
00045 
00046 /*
00047  * function(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00048  * function(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
00049  * function(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
00050  */
00051 #define TVMET_DECLARE_MACRO(NAME)                    \
00052 template<class T1, class T2, std::size_t Rows, std::size_t Cols>    \
00053 XprMatrix<                                \
00054   XprBinOp<                                \
00055     Fcnl_##NAME<T1, T2>,                        \
00056     MatrixConstReference<T1, Rows, Cols>,                \
00057     MatrixConstReference<T2, Rows, Cols>                \
00058   >,                                    \
00059   Rows, Cols                                \
00060 >                                    \
00061 NAME (const Matrix<T1, Rows, Cols>& lhs,                \
00062       const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;    \
00063                                     \
00064 template<class E, class T, std::size_t Rows, std::size_t Cols>        \
00065 XprMatrix<                                \
00066   XprBinOp<                                \
00067     Fcnl_##NAME<typename E::value_type, T>,                \
00068     XprMatrix<E, Rows, Cols>,                        \
00069     MatrixConstReference<T, Rows, Cols>                    \
00070   >,                                    \
00071   Rows, Cols                                \
00072 >                                    \
00073 NAME (const XprMatrix<E, Rows, Cols>& lhs,                \
00074       const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;    \
00075                                     \
00076 template<class T, class E, std::size_t Rows, std::size_t Cols>        \
00077 XprMatrix<                                \
00078   XprBinOp<                                \
00079     Fcnl_##NAME<typename E::value_type, T>,                \
00080     MatrixConstReference<T, Rows, Cols>,                \
00081     XprMatrix<E, Rows, Cols>                        \
00082   >,                                    \
00083   Rows, Cols                                \
00084 >                                    \
00085 NAME (const Matrix<T, Rows, Cols>& lhs,                    \
00086       const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00087 
00088 TVMET_DECLARE_MACRO(add)            // per se element wise
00089 TVMET_DECLARE_MACRO(sub)            // per se element wise
00090 namespace element_wise {
00091   TVMET_DECLARE_MACRO(mul)            // not defined for matrizes
00092   TVMET_DECLARE_MACRO(div)            // not defined for matrizes
00093 }
00094 
00095 #undef TVMET_DECLARE_MACRO
00096 
00097 
00098 /*
00099  * function(Matrix<T, Rows, Cols>, POD)
00100  * function(POD, Matrix<T, Rows, Cols>)
00101  * Note: - operations +,-,*,/ are per se element wise
00102  */
00103 #define TVMET_DECLARE_MACRO(NAME, POD)                    \
00104 template<class T, std::size_t Rows, std::size_t Cols>            \
00105 XprMatrix<                                \
00106   XprBinOp<                                \
00107     Fcnl_##NAME<T, POD >,                        \
00108     MatrixConstReference<T, Rows, Cols>,                \
00109     XprLiteral<POD >                            \
00110   >,                                    \
00111   Rows, Cols                                \
00112 >                                    \
00113 NAME (const Matrix<T, Rows, Cols>& lhs,                 \
00114       POD rhs) TVMET_CXX_ALWAYS_INLINE;                    \
00115                                     \
00116 template<class T, std::size_t Rows, std::size_t Cols>            \
00117 XprMatrix<                                \
00118   XprBinOp<                                \
00119     Fcnl_##NAME< POD, T>,                        \
00120     XprLiteral< POD >,                            \
00121     MatrixConstReference<T, Rows, Cols>                    \
00122   >,                                    \
00123   Rows, Cols                                \
00124 >                                    \
00125 NAME (POD lhs,                                 \
00126       const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00127 
00128 TVMET_DECLARE_MACRO(add, int)
00129 TVMET_DECLARE_MACRO(sub, int)
00130 TVMET_DECLARE_MACRO(mul, int)
00131 TVMET_DECLARE_MACRO(div, int)
00132 
00133 #if defined(TVMET_HAVE_LONG_LONG)
00134 TVMET_DECLARE_MACRO(add, long long int)
00135 TVMET_DECLARE_MACRO(sub, long long int)
00136 TVMET_DECLARE_MACRO(mul, long long int)
00137 TVMET_DECLARE_MACRO(div, long long int)
00138 #endif
00139 
00140 TVMET_DECLARE_MACRO(add, float)
00141 TVMET_DECLARE_MACRO(sub, float)
00142 TVMET_DECLARE_MACRO(mul, float)
00143 TVMET_DECLARE_MACRO(div, float)
00144 
00145 TVMET_DECLARE_MACRO(add, double)
00146 TVMET_DECLARE_MACRO(sub, double)
00147 TVMET_DECLARE_MACRO(mul, double)
00148 TVMET_DECLARE_MACRO(div, double)
00149 
00150 #if defined(TVMET_HAVE_LONG_DOUBLE)
00151 TVMET_DECLARE_MACRO(add, long double)
00152 TVMET_DECLARE_MACRO(sub, long double)
00153 TVMET_DECLARE_MACRO(mul, long double)
00154 TVMET_DECLARE_MACRO(div, long double)
00155 #endif
00156 
00157 #undef TVMET_DECLARE_MACRO
00158 
00159 
00160 #if defined(TVMET_HAVE_COMPLEX)
00161 /*
00162  * function(Matrix<T, Rows, Cols>, complex<T>)
00163  * function(complex<T>, Matrix<T, Rows, Cols>)
00164  * Note: - operations +,-,*,/ are per se element wise
00165  * \todo type promotion
00166  */
00167 #define TVMET_DECLARE_MACRO(NAME)                        \
00168 template<class T, std::size_t Rows, std::size_t Cols>                \
00169 XprMatrix<                                    \
00170   XprBinOp<                                    \
00171     Fcnl_##NAME< std::complex<T>, std::complex<T> >,                \
00172     MatrixConstReference< std::complex<T>, Rows, Cols>,                \
00173     XprLiteral<std::complex<T> >                        \
00174   >,                                        \
00175   Rows, Cols                                    \
00176 >                                        \
00177 NAME (const Matrix< std::complex<T>, Rows, Cols>& lhs,                \
00178       const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;            \
00179                                         \
00180 template<class T, std::size_t Rows, std::size_t Cols>                \
00181 XprMatrix<                                    \
00182   XprBinOp<                                    \
00183     Fcnl_##NAME< std::complex<T>, std::complex<T> >,                \
00184     XprLiteral< std::complex<T> >,                        \
00185     MatrixConstReference< std::complex<T>, Rows, Cols>                \
00186   >,                                        \
00187   Rows, Cols                                    \
00188 >                                        \
00189 NAME (const std::complex<T>& lhs,                        \
00190       const Matrix< std::complex<T>, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00191 
00192 TVMET_DECLARE_MACRO(add)
00193 TVMET_DECLARE_MACRO(sub)
00194 TVMET_DECLARE_MACRO(mul)
00195 TVMET_DECLARE_MACRO(div)
00196 
00197 #undef TVMET_DECLARE_MACRO
00198 
00199 #endif // defined(TVMET_HAVE_COMPLEX)
00200 
00201 
00202 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00203  * matrix specific prod( ... ) functions
00204  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00205 
00206 
00207 template<class T1, std::size_t Rows1, std::size_t Cols1,
00208      class T2, std::size_t Cols2>
00209 XprMatrix<
00210   XprMMProduct<
00211     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00212     MatrixConstReference<T2, Cols1, Cols2>, Cols2         // M2(Cols1, Cols2)
00213   >,
00214   Rows1, Cols2                            // return Dim
00215 >
00216 prod(const Matrix<T1, Rows1, Cols1>& lhs,
00217      const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00218 
00219 
00220 template<class E1, std::size_t Rows1, std::size_t Cols1,
00221      class T2, std::size_t Cols2>
00222 XprMatrix<
00223   XprMMProduct<
00224     XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,            // M1(Rows1, Cols1)
00225     MatrixConstReference<T2, Cols1, Cols2>, Cols2        // M2(Cols1, Cols2)
00226   >,
00227   Rows1, Cols2                            // return Dim
00228 >
00229 prod(const XprMatrix<E1, Rows1, Cols1>& lhs,
00230      const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00231 
00232 
00233 template<class T1, std::size_t Rows1, std::size_t Cols1,
00234      class E2, std::size_t Cols2>
00235 XprMatrix<
00236   XprMMProduct<
00237     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00238     XprMatrix<E2, Cols1, Cols2>, Cols2                // M2(Cols1, Cols2)
00239   >,
00240   Rows1, Cols2                            // return Dim
00241 >
00242 prod(const Matrix<T1, Rows1, Cols1>& lhs,
00243      const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00244 
00245 
00246 template<class T1, std::size_t Rows1, std::size_t Cols1,
00247      class T2, std::size_t Cols2>
00248 XprMatrix<
00249   XprMMProductTransposed<
00250     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00251     MatrixConstReference<T2, Cols1, Cols2>, Cols2        // M2(Cols1, Cols2)
00252   >,
00253   Cols2, Rows1                            // return Dim
00254 >
00255 trans_prod(const Matrix<T1, Rows1, Cols1>& lhs,
00256        const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00257 
00258 
00259 template<class T1, std::size_t Rows1, std::size_t Cols1,
00260      class T2, std::size_t Cols2>    // Rows2 = Rows1
00261 XprMatrix<
00262   XprMtMProduct<
00263     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00264     MatrixConstReference<T2, Rows1, Cols2>, Cols2        // M2(Rows1, Cols2)
00265   >,
00266   Cols1, Cols2                            // return Dim
00267 >
00268 MtM_prod(const Matrix<T1, Rows1, Cols1>& lhs,
00269      const Matrix<T2, Rows1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00270 
00271 
00272 template<class T1, std::size_t Rows1, std::size_t Cols1,
00273      class T2, std::size_t Rows2>
00274 XprMatrix<
00275   XprMMtProduct<
00276     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00277     MatrixConstReference<T2, Rows2, Cols1>, Cols1         // M2(Rows2, Cols1)
00278   >,
00279   Rows1, Rows2                            // return Dim
00280 >
00281 MMt_prod(const Matrix<T1, Rows1, Cols1>& lhs,
00282      const Matrix<T2, Rows2, Cols1>& rhs) TVMET_CXX_ALWAYS_INLINE;
00283 
00284 
00285 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00286  * matrix-vector specific prod( ... ) functions
00287  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00288 
00289 
00290 template<class T1, class T2, std::size_t Rows, std::size_t Cols>
00291 XprVector<
00292   XprMVProduct<
00293     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,    // M(Rows, Cols)
00294     VectorConstReference<T2, Cols>             // V
00295   >,
00296   Rows
00297 >
00298 prod(const Matrix<T1, Rows, Cols>& lhs,
00299      const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00300 
00301 
00302 template<class T1, class E2, std::size_t Rows, std::size_t Cols>
00303 XprVector<
00304   XprMVProduct<
00305     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00306     XprVector<E2, Cols>
00307   >,
00308   Rows
00309 >
00310 prod(const Matrix<T1, Rows, Cols>& lhs,
00311      const XprVector<E2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00312 
00313 
00314 template<class E1, class T2, std::size_t Rows, std::size_t Cols>
00315 XprVector<
00316   XprMVProduct<
00317     XprMatrix<E1, Rows, Cols>, Rows, Cols,        // M(Rows, Cols)
00318     VectorConstReference<T2, Cols>             // V
00319   >,
00320   Rows
00321 >
00322 prod(const XprMatrix<E1, Rows, Cols>& lhs,
00323      const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00324 
00325 
00326 template<class T1, class T2, std::size_t Rows, std::size_t Cols>
00327 XprVector<
00328   XprMtVProduct<
00329     MatrixConstReference<T1, Rows, Cols>, Rows,    Cols,   // M(Rows, Cols)
00330     VectorConstReference<T2, Rows>             // V
00331   >,
00332   Cols
00333 >
00334 Mtx_prod(const Matrix<T1, Rows, Cols>& lhs,
00335      const Vector<T2, Rows>& rhs) TVMET_CXX_ALWAYS_INLINE;
00336 
00337 
00338 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00339  * matrix specific functions
00340  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00341 
00342 
00343 template<class T, std::size_t Rows, std::size_t Cols>
00344 XprMatrix<
00345   XprMatrixTranspose<
00346     MatrixConstReference<T, Rows, Cols>
00347   >,
00348   Cols, Rows
00349 >
00350 trans(const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00351 
00352 
00353 template<class T, std::size_t Sz>
00354 typename NumericTraits<T>::sum_type
00355 trace(const Matrix<T, Sz, Sz>& m) TVMET_CXX_ALWAYS_INLINE;
00356 
00357 
00358 template<class T, std::size_t Rows, std::size_t Cols>
00359 XprVector<
00360   XprMatrixRow<
00361     MatrixConstReference<T, Rows, Cols>,
00362     Rows, Cols
00363   >,
00364   Cols
00365 >
00366 row(const Matrix<T, Rows, Cols>& m,
00367     std::size_t no) TVMET_CXX_ALWAYS_INLINE;
00368 
00369 
00370 template<class T, std::size_t Rows, std::size_t Cols>
00371 XprVector<
00372   XprMatrixCol<
00373     MatrixConstReference<T, Rows, Cols>,
00374     Rows, Cols
00375   >,
00376   Rows
00377 >
00378 col(const Matrix<T, Rows, Cols>& m,
00379     std::size_t no) TVMET_CXX_ALWAYS_INLINE;
00380 
00381 
00382 template<class T, std::size_t Sz>
00383 XprVector<
00384   XprMatrixDiag<
00385     MatrixConstReference<T, Sz, Sz>,
00386     Sz
00387   >,
00388   Sz
00389 >
00390 diag(const Matrix<T, Sz, Sz>& m) TVMET_CXX_ALWAYS_INLINE;
00391 
00392 
00393 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00394  * min/max unary functions
00395  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00396 
00397 
00398 template<class E, std::size_t Rows, std::size_t Cols>
00399 Extremum<typename E::value_type, std::size_t, matrix_tag>
00400 maximum(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00401 
00402 
00403 template<class T, std::size_t Rows, std::size_t Cols>
00404 Extremum<T, std::size_t, matrix_tag>
00405 maximum(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
00406 
00407 
00408 template<class E, std::size_t Rows, std::size_t Cols>
00409 Extremum<typename E::value_type, std::size_t, matrix_tag>
00410 minimum(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00411 
00412 
00413 template<class T, std::size_t Rows, std::size_t Cols>
00414 Extremum<T, std::size_t, matrix_tag>
00415 minimum(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
00416 
00417 
00418 template<class E, std::size_t Rows, std::size_t Cols>
00419 typename E::value_type
00420 max(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00421 
00422 
00423 template<class T, std::size_t Rows, std::size_t Cols>
00424 T max(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
00425 
00426 
00427 template<class E, std::size_t Rows, std::size_t Cols>
00428 typename E::value_type
00429 min(const XprMatrix<E, Rows, Cols>& e); // NOT TVMET_CXX_ALWAYS_INLINE;
00430 
00431 
00432 template<class T, std::size_t Rows, std::size_t Cols>
00433 T min(const Matrix<T, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
00434 
00435 
00436 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00437  * other unary functions
00438  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00439 
00440 
00441 template<class T, std::size_t Rows, std::size_t Cols>
00442 XprMatrix<
00443   XprIdentity<T, Rows, Cols>,
00444   Rows, Cols
00445 >
00446 identity() TVMET_CXX_ALWAYS_INLINE;
00447 
00448 
00449 template<class M>
00450 XprMatrix<
00451   XprIdentity<
00452     typename M::value_type,
00453     M::Rows, M::Cols>,
00454   M::Rows, M::Cols
00455 >
00456 identity() TVMET_CXX_ALWAYS_INLINE;
00457 
00458 
00459 template<class T, std::size_t Rows, std::size_t Cols>
00460 XprMatrix<
00461   MatrixConstReference<T, Rows, Cols>,
00462   Rows, Cols
00463 >
00464 cmatrix_ref(const T* mem) TVMET_CXX_ALWAYS_INLINE;
00465 
00466 
00467 /*********************************************************
00468  * PART II: IMPLEMENTATION
00469  *********************************************************/
00470 
00471 
00472 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00473  * Vector arithmetic functions add, sub, mul and div
00474  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00475 
00476 
00477 /*
00478  * function(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00479  * function(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
00480  * function(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
00481  */
00482 #define TVMET_IMPLEMENT_MACRO(NAME)                        \
00483 template<class T1, class T2, std::size_t Rows, std::size_t Cols>        \
00484 inline                                        \
00485 XprMatrix<                                    \
00486   XprBinOp<                                    \
00487     Fcnl_##NAME<T1, T2>,                            \
00488     MatrixConstReference<T1, Rows, Cols>,                    \
00489     MatrixConstReference<T2, Rows, Cols>                    \
00490   >,                                        \
00491   Rows, Cols                                    \
00492 >                                        \
00493 NAME (const Matrix<T1, Rows, Cols>& lhs, const Matrix<T2, Rows, Cols>& rhs) {    \
00494   typedef XprBinOp <                                \
00495     Fcnl_##NAME<T1, T2>,                            \
00496     MatrixConstReference<T1, Rows, Cols>,                    \
00497     MatrixConstReference<T2, Rows, Cols>                    \
00498   >                            expr_type;        \
00499   return XprMatrix<expr_type, Rows, Cols>(                    \
00500     expr_type(lhs.const_ref(), rhs.const_ref()));                \
00501 }                                        \
00502                                         \
00503 template<class E, class T, std::size_t Rows, std::size_t Cols>            \
00504 inline                                        \
00505 XprMatrix<                                    \
00506   XprBinOp<                                    \
00507     Fcnl_##NAME<typename E::value_type, T>,                    \
00508     XprMatrix<E, Rows, Cols>,                            \
00509     MatrixConstReference<T, Rows, Cols>                        \
00510   >,                                        \
00511   Rows, Cols                                    \
00512 >                                        \
00513 NAME (const XprMatrix<E, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs) {    \
00514   typedef XprBinOp<                                \
00515     Fcnl_##NAME<typename E::value_type, T>,                    \
00516     XprMatrix<E, Rows, Cols>,                            \
00517     MatrixConstReference<T, Rows, Cols>                        \
00518   >                              expr_type;        \
00519   return XprMatrix<expr_type, Rows, Cols>(                    \
00520     expr_type(lhs, rhs.const_ref()));                        \
00521 }                                        \
00522                                         \
00523 template<class T, class E, std::size_t Rows, std::size_t Cols>            \
00524 inline                                        \
00525 XprMatrix<                                    \
00526   XprBinOp<                                    \
00527     Fcnl_##NAME<typename E::value_type, T>,                    \
00528     MatrixConstReference<T, Rows, Cols>,                    \
00529     XprMatrix<E, Rows, Cols>                            \
00530   >,                                        \
00531   Rows, Cols                                    \
00532 >                                        \
00533 NAME (const Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) {    \
00534   typedef XprBinOp<                                \
00535     Fcnl_##NAME<T, typename E::value_type>,                    \
00536     MatrixConstReference<T, Rows, Cols>,                    \
00537     XprMatrix<E, Rows, Cols>                            \
00538   >                              expr_type;        \
00539   return XprMatrix<expr_type, Rows, Cols>(                    \
00540     expr_type(lhs.const_ref(), rhs));                        \
00541 }
00542 
00543 TVMET_IMPLEMENT_MACRO(add)            // per se element wise
00544 TVMET_IMPLEMENT_MACRO(sub)            // per se element wise
00545 namespace element_wise {
00546   TVMET_IMPLEMENT_MACRO(mul)            // not defined for matrizes
00547   TVMET_IMPLEMENT_MACRO(div)            // not defined for matrizes
00548 }
00549 
00550 #undef TVMET_IMPLEMENT_MACRO
00551 
00552 
00553 /*
00554  * function(Matrix<T, Rows, Cols>, POD)
00555  * function(POD, Matrix<T, Rows, Cols>)
00556  * Note: - operations +,-,*,/ are per se element wise
00557  */
00558 #define TVMET_IMPLEMENT_MACRO(NAME, POD)                \
00559 template<class T, std::size_t Rows, std::size_t Cols>            \
00560 inline                                    \
00561 XprMatrix<                                \
00562   XprBinOp<                                \
00563     Fcnl_##NAME<T, POD >,                        \
00564     MatrixConstReference<T, Rows, Cols>,                \
00565     XprLiteral<POD >                            \
00566   >,                                    \
00567   Rows, Cols                                \
00568 >                                    \
00569 NAME (const Matrix<T, Rows, Cols>& lhs, POD rhs) {            \
00570   typedef XprBinOp<                            \
00571     Fcnl_##NAME<T, POD >,                        \
00572     MatrixConstReference<T, Rows, Cols>,                \
00573     XprLiteral< POD >                            \
00574   >                            expr_type;    \
00575   return XprMatrix<expr_type, Rows, Cols>(                \
00576     expr_type(lhs.const_ref(), XprLiteral< POD >(rhs)));        \
00577 }                                    \
00578                                     \
00579 template<class T, std::size_t Rows, std::size_t Cols>            \
00580 inline                                    \
00581 XprMatrix<                                \
00582   XprBinOp<                                \
00583     Fcnl_##NAME< POD, T>,                        \
00584     XprLiteral< POD >,                            \
00585     MatrixConstReference<T, Rows, Cols>                    \
00586   >,                                    \
00587   Rows, Cols                                \
00588 >                                    \
00589 NAME (POD lhs, const Matrix<T, Rows, Cols>& rhs) {            \
00590   typedef XprBinOp<                            \
00591     Fcnl_##NAME< POD, T>,                        \
00592     XprLiteral< POD >,                            \
00593     MatrixConstReference<T, Rows, Cols>                    \
00594   >                            expr_type;    \
00595   return XprMatrix<expr_type, Rows, Cols>(                \
00596     expr_type(XprLiteral< POD >(lhs), rhs.const_ref()));        \
00597 }
00598 
00599 TVMET_IMPLEMENT_MACRO(add, int)
00600 TVMET_IMPLEMENT_MACRO(sub, int)
00601 TVMET_IMPLEMENT_MACRO(mul, int)
00602 TVMET_IMPLEMENT_MACRO(div, int)
00603 
00604 #if defined(TVMET_HAVE_LONG_LONG)
00605 TVMET_IMPLEMENT_MACRO(add, long long int)
00606 TVMET_IMPLEMENT_MACRO(sub, long long int)
00607 TVMET_IMPLEMENT_MACRO(mul, long long int)
00608 TVMET_IMPLEMENT_MACRO(div, long long int)
00609 #endif
00610 
00611 TVMET_IMPLEMENT_MACRO(add, float)
00612 TVMET_IMPLEMENT_MACRO(sub, float)
00613 TVMET_IMPLEMENT_MACRO(mul, float)
00614 TVMET_IMPLEMENT_MACRO(div, float)
00615 
00616 TVMET_IMPLEMENT_MACRO(add, double)
00617 TVMET_IMPLEMENT_MACRO(sub, double)
00618 TVMET_IMPLEMENT_MACRO(mul, double)
00619 TVMET_IMPLEMENT_MACRO(div, double)
00620 
00621 #if defined(TVMET_HAVE_LONG_DOUBLE)
00622 TVMET_IMPLEMENT_MACRO(add, long double)
00623 TVMET_IMPLEMENT_MACRO(sub, long double)
00624 TVMET_IMPLEMENT_MACRO(mul, long double)
00625 TVMET_IMPLEMENT_MACRO(div, long double)
00626 #endif
00627 
00628 #undef TVMET_IMPLEMENT_MACRO
00629 
00630 
00631 #if defined(TVMET_HAVE_COMPLEX)
00632 /*
00633  * function(Matrix<T, Rows, Cols>, complex<T>)
00634  * function(complex<T>, Matrix<T, Rows, Cols>)
00635  * Note: - operations +,-,*,/ are per se element wise
00636  * \todo type promotion
00637  */
00638 #define TVMET_IMPLEMENT_MACRO(NAME)                    \
00639 template<class T, std::size_t Rows, std::size_t Cols>            \
00640 inline                                    \
00641 XprMatrix<                                \
00642   XprBinOp<                                \
00643     Fcnl_##NAME< std::complex<T>, std::complex<T> >,            \
00644     MatrixConstReference< std::complex<T>, Rows, Cols>,            \
00645     XprLiteral<std::complex<T> >                    \
00646   >,                                    \
00647   Rows, Cols                                \
00648 >                                    \
00649 NAME (const Matrix< std::complex<T>, Rows, Cols>& lhs,            \
00650       const std::complex<T>& rhs) {                    \
00651   typedef XprBinOp<                            \
00652     Fcnl_##NAME< std::complex<T>, std::complex<T> >,            \
00653     MatrixConstReference< std::complex<T>, Rows, Cols>,            \
00654     XprLiteral< std::complex<T> >                    \
00655   >                            expr_type;    \
00656   return XprMatrix<expr_type, Rows, Cols>(                \
00657     expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs)));    \
00658 }                                    \
00659                                     \
00660 template<class T, std::size_t Rows, std::size_t Cols>            \
00661 inline                                    \
00662 XprMatrix<                                \
00663   XprBinOp<                                \
00664     Fcnl_##NAME< std::complex<T>, std::complex<T> >,            \
00665     XprLiteral< std::complex<T> >,                    \
00666     MatrixConstReference< std::complex<T>, Rows, Cols>            \
00667   >,                                    \
00668   Rows, Cols                                \
00669 >                                    \
00670 NAME (const std::complex<T>& lhs,                    \
00671       const Matrix< std::complex<T>, Rows, Cols>& rhs) {        \
00672   typedef XprBinOp<                            \
00673     Fcnl_##NAME< std::complex<T>, std::complex<T> >,            \
00674     XprLiteral< std::complex<T> >,                    \
00675     MatrixConstReference<std::complex<T>, Rows, Cols>            \
00676   >                            expr_type;    \
00677   return XprMatrix<expr_type, Rows, Cols>(                \
00678     expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref()));    \
00679 }
00680 
00681 TVMET_IMPLEMENT_MACRO(add)
00682 TVMET_IMPLEMENT_MACRO(sub)
00683 TVMET_IMPLEMENT_MACRO(mul)
00684 TVMET_IMPLEMENT_MACRO(div)
00685 
00686 #undef TVMET_IMPLEMENT_MACRO
00687 
00688 #endif // defined(TVMET_HAVE_COMPLEX)
00689 
00690 
00691 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00692  * matrix specific prod( ... ) functions
00693  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00694 
00695 
00696 /**
00697  * \fn prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
00698  * \brief Function for the matrix-matrix-product.
00699  * \ingroup _binary_function
00700  * \note The rows2 has to be equal to cols1.
00701  */
00702 template<class T1, std::size_t Rows1, std::size_t Cols1,
00703      class T2, std::size_t Cols2>
00704 inline
00705 XprMatrix<
00706   XprMMProduct<
00707     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00708     MatrixConstReference<T2, Cols1, Cols2>, Cols2         // M2(Cols1, Cols2)
00709   >,
00710   Rows1, Cols2                            // return Dim
00711 >
00712 prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
00713   typedef XprMMProduct<
00714     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00715     MatrixConstReference<T2, Cols1, Cols2>, Cols2
00716   >                            expr_type;
00717   return XprMatrix<expr_type, Rows1, Cols2>(
00718     expr_type(lhs.const_ref(), rhs.const_ref()));
00719 }
00720 
00721 
00722 /**
00723  * \fn prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
00724  * \brief Evaluate the product of XprMatrix and Matrix.
00725  * \ingroup _binary_function
00726  */
00727 template<class E1, std::size_t Rows1, std::size_t Cols1,
00728      class T2, std::size_t Cols2>
00729 inline
00730 XprMatrix<
00731   XprMMProduct<
00732     XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,            // M1(Rows1, Cols1)
00733     MatrixConstReference<T2, Cols1, Cols2>, Cols2        // M2(Cols1, Cols2)
00734   >,
00735   Rows1, Cols2                            // return Dim
00736 >
00737 prod(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
00738   typedef XprMMProduct<
00739     XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
00740     MatrixConstReference<T2, Cols1, Cols2>, Cols2
00741   >                            expr_type;
00742   return XprMatrix<expr_type, Rows1, Cols2>(
00743     expr_type(lhs, rhs.const_ref()));
00744 }
00745 
00746 
00747 /**
00748  * \fn prod(const Matrix<T1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs)
00749  * \brief Evaluate the product of Matrix and XprMatrix.
00750  * \ingroup _binary_function
00751  */
00752 template<class T1, std::size_t Rows1, std::size_t Cols1,
00753      class E2, std::size_t Cols2>
00754 inline
00755 XprMatrix<
00756   XprMMProduct<
00757     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00758     XprMatrix<E2, Cols1, Cols2>, Cols2                // M2(Cols1, Cols2)
00759   >,
00760   Rows1, Cols2                            // return Dim
00761 >
00762 prod(const Matrix<T1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
00763   typedef XprMMProduct<
00764     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00765     XprMatrix<E2, Cols1, Cols2>, Cols2
00766   >                            expr_type;
00767   return XprMatrix<expr_type, Rows1, Cols2>(
00768     expr_type(lhs.const_ref(), rhs));
00769 }
00770 
00771 
00772 /**
00773  * \fn trans_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs)
00774  * \brief Function for the trans(matrix-matrix-product)
00775  * \ingroup _binary_function
00776  * Perform on given Matrix M1 and M2:
00777  * \f[
00778  * (M_1\,M_2)^T
00779  * \f]
00780  */
00781 template<class T1, std::size_t Rows1, std::size_t Cols1,
00782      class T2, std::size_t Cols2>
00783 inline
00784 XprMatrix<
00785   XprMMProductTransposed<
00786     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00787     MatrixConstReference<T2, Cols1, Cols2>, Cols2        // M2(Cols1, Cols2)
00788   >,
00789   Cols2, Rows1                            // return Dim
00790 >
00791 trans_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
00792   typedef XprMMProductTransposed<
00793     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00794     MatrixConstReference<T2, Cols1, Cols2>, Cols2
00795   >                            expr_type;
00796   return XprMatrix<expr_type, Cols2, Rows1>(
00797     expr_type(lhs.const_ref(), rhs.const_ref()));
00798 }
00799 
00800 
00801 /**
00802  * \fn MtM_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows1, Cols2>& rhs)
00803  * \brief Function for the trans(matrix)-matrix-product.
00804  * \ingroup _binary_function
00805  *        using formula
00806  *        \f[
00807  *        M_1^{T}\,M_2
00808  *        \f]
00809  * \note The number of cols of matrix 2 have to be equal to number of rows of
00810  *       matrix 1, since matrix 1 is trans - the result is a (Cols1 x Cols2)
00811  *       matrix.
00812  */
00813 template<class T1, std::size_t Rows1, std::size_t Cols1,
00814      class T2, std::size_t Cols2>    // Rows2 = Rows1
00815 inline
00816 XprMatrix<
00817   XprMtMProduct<
00818     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00819     MatrixConstReference<T2, Rows1, Cols2>, Cols2        // M2(Rows1, Cols2)
00820   >,
00821   Cols1, Cols2                            // return Dim
00822 >
00823 MtM_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows1, Cols2>& rhs) {
00824   typedef XprMtMProduct<
00825     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00826     MatrixConstReference<T2, Rows1, Cols2>, Cols2
00827   >                            expr_type;
00828   return XprMatrix<expr_type, Cols1, Cols2>(
00829     expr_type(lhs.const_ref(), rhs.const_ref()));
00830 }
00831 
00832 
00833 /**
00834  * \fn MMt_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows2, Cols1>& rhs)
00835  * \brief Function for the matrix-trans(matrix)-product.
00836  * \ingroup _binary_function
00837  * \note The Cols2 has to be equal to Cols1.
00838  */
00839 template<class T1, std::size_t Rows1, std::size_t Cols1,
00840      class T2, std::size_t Rows2>
00841 inline
00842 XprMatrix<
00843   XprMMtProduct<
00844     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,    // M1(Rows1, Cols1)
00845     MatrixConstReference<T2, Rows2, Cols1>, Cols1         // M2(Rows2, Cols1)
00846   >,
00847   Rows1, Rows2                            // return Dim
00848 >
00849 MMt_prod(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Rows2, Cols1>& rhs) {
00850   typedef XprMMtProduct<
00851     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00852     MatrixConstReference<T2, Rows2, Cols1>, Cols1
00853   >                            expr_type;
00854   return XprMatrix<expr_type, Rows1, Rows2>(
00855     expr_type(lhs.const_ref(), rhs.const_ref()));
00856 }
00857 
00858 
00859 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00860  * matrix-vector specific prod( ... ) functions
00861  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00862 
00863 
00864 /**
00865  * \fn prod(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs)
00866  * \brief Function for the matrix-vector-product
00867  * \ingroup _binary_function
00868  */
00869 template<class T1, class T2, std::size_t Rows, std::size_t Cols>
00870 inline
00871 XprVector<
00872   XprMVProduct<
00873     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,    // M(Rows, Cols)
00874     VectorConstReference<T2, Cols>             // V
00875   >,
00876   Rows
00877 >
00878 prod(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
00879   typedef XprMVProduct<
00880     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00881     VectorConstReference<T2, Cols>
00882   >                             expr_type;
00883   return XprVector<expr_type, Rows>(
00884     expr_type(lhs.const_ref(), rhs.const_ref()));
00885 }
00886 
00887 
00888 /**
00889  * \fn prod(const Matrix<T1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs)
00890  * \brief Function for the matrix-vector-product
00891  * \ingroup _binary_function
00892  */
00893 template<class T1, class E2, std::size_t Rows, std::size_t Cols>
00894 inline
00895 XprVector<
00896   XprMVProduct<
00897     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00898     XprVector<E2, Cols>
00899   >,
00900   Rows
00901 >
00902 prod(const Matrix<T1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs) {
00903   typedef XprMVProduct<
00904     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00905     XprVector<E2, Cols>
00906   >                             expr_type;
00907   return XprVector<expr_type, Rows>(
00908     expr_type(lhs.const_ref(), rhs));
00909 }
00910 
00911 
00912 /*
00913  * \fn prod(const XprMatrix<E, Rows, Cols>& lhs, const Vector<T, Cols>& rhs)
00914  * \brief Compute the product of an XprMatrix with a Vector.
00915  * \ingroup _binary_function
00916  */
00917 template<class E1, class T2, std::size_t Rows, std::size_t Cols>
00918 inline
00919 XprVector<
00920   XprMVProduct<
00921     XprMatrix<E1, Rows, Cols>, Rows, Cols,        // M(Rows, Cols)
00922     VectorConstReference<T2, Cols>             // V
00923   >,
00924   Rows
00925 >
00926 prod(const XprMatrix<E1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
00927   typedef XprMVProduct<
00928     XprMatrix<E1, Rows, Cols>, Rows, Cols,
00929     VectorConstReference<T2, Cols>
00930   >                             expr_type;
00931   return XprVector<expr_type, Rows>(
00932     expr_type(lhs, rhs.const_ref()));
00933 }
00934 
00935 
00936 /**
00937  * \fn Mtx_prod(const Matrix<T1, Rows, Cols>& matrix, const Vector<T2, Rows>& vector)
00938  * \brief Function for the trans(matrix)-vector-product
00939  * \ingroup _binary_function
00940  * Perform on given Matrix M and vector x:
00941  * \f[
00942  * M^T\, x
00943  * \f]
00944  */
00945 template<class T1, class T2, std::size_t Rows, std::size_t Cols>
00946 inline
00947 XprVector<
00948   XprMtVProduct<
00949     MatrixConstReference<T1, Rows, Cols>, Rows,    Cols,   // M(Rows, Cols)
00950     VectorConstReference<T2, Rows>             // V
00951   >,
00952   Cols
00953 >
00954 Mtx_prod(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Rows>& rhs) {
00955   typedef XprMtVProduct<
00956     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00957     VectorConstReference<T2, Rows>
00958   >                             expr_type;
00959   return XprVector<expr_type, Cols>(
00960     expr_type(lhs.const_ref(), rhs.const_ref()));
00961 }
00962 
00963 
00964 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00965  * matrix specific functions
00966  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00967 
00968 
00969 /**
00970  * \fn trans(const Matrix<T, Rows, Cols>& rhs)
00971  * \brief Transpose the matrix
00972  * \ingroup _unary_function
00973  */
00974 template<class T, std::size_t Rows, std::size_t Cols>
00975 inline
00976 XprMatrix<
00977   XprMatrixTranspose<
00978     MatrixConstReference<T, Rows, Cols>
00979   >,
00980   Cols, Rows
00981 >
00982 trans(const Matrix<T, Rows, Cols>& rhs) {
00983   typedef XprMatrixTranspose<
00984     MatrixConstReference<T, Rows, Cols>
00985   >                            expr_type;
00986   return XprMatrix<expr_type, Cols, Rows>(
00987     expr_type(rhs.const_ref()));
00988 }
00989 
00990 
00991 /*
00992  * \fn trace(const Matrix<T, Sz, Sz>& m)
00993  * \brief Compute the trace of a square matrix.
00994  * \ingroup _unary_function
00995  *
00996  * Simply compute the trace of the given matrix as:
00997  * \f[
00998  *  \sum_{k = 0}^{Sz-1} m(k, k)
00999  * \f]
01000  */
01001 template<class T, std::size_t Sz>
01002 inline
01003 typename NumericTraits<T>::sum_type
01004 trace(const Matrix<T, Sz, Sz>& m) {
01005   return meta::Matrix<Sz, Sz, 0, 0>::trace(m);
01006 }
01007 
01008 
01009 /**
01010  * \fn row(const Matrix<T, Rows, Cols>& m, std::size_t no)
01011  * \brief Returns a row vector of the given matrix.
01012  * \ingroup _binary_function
01013  */
01014 template<class T, std::size_t Rows, std::size_t Cols>
01015 inline
01016 XprVector<
01017   XprMatrixRow<
01018     MatrixConstReference<T, Rows, Cols>,
01019     Rows, Cols
01020   >,
01021   Cols
01022 >
01023 row(const Matrix<T, Rows, Cols>& m, std::size_t no) {
01024   typedef XprMatrixRow<
01025     MatrixConstReference<T, Rows, Cols>,
01026     Rows, Cols
01027   >                            expr_type;
01028   return XprVector<expr_type, Cols>(expr_type(m.const_ref(), no));
01029 }
01030 
01031 
01032 /**
01033  * \fn col(const Matrix<T, Rows, Cols>& m, std::size_t no)
01034  * \brief Returns a column vector of the given matrix.
01035  * \ingroup _binary_function
01036  */
01037 template<class T, std::size_t Rows, std::size_t Cols>
01038 inline
01039 XprVector<
01040   XprMatrixCol<
01041     MatrixConstReference<T, Rows, Cols>,
01042     Rows, Cols
01043   >,
01044   Rows
01045 >
01046 col(const Matrix<T, Rows, Cols>& m, std::size_t no) {
01047   typedef XprMatrixCol<
01048     MatrixConstReference<T, Rows, Cols>,
01049     Rows, Cols
01050   >                            expr_type;
01051   return XprVector<expr_type, Rows>(expr_type(m.const_ref(), no));
01052 }
01053 
01054 
01055 /**
01056  * \fn diag(const Matrix<T, Sz, Sz>& m)
01057  * \brief Returns the diagonal vector of the given square matrix.
01058  * \ingroup _unary_function
01059  */
01060 template<class T, std::size_t Sz>
01061 inline
01062 XprVector<
01063   XprMatrixDiag<
01064     MatrixConstReference<T, Sz, Sz>,
01065     Sz
01066   >,
01067   Sz
01068 >
01069 diag(const Matrix<T, Sz, Sz>& m) {
01070   typedef XprMatrixDiag<
01071     MatrixConstReference<T, Sz, Sz>,
01072     Sz
01073   >                            expr_type;
01074   return XprVector<expr_type, Sz>(expr_type(m.const_ref()));
01075 }
01076 
01077 
01078 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01079  * min/max unary functions
01080  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
01081 
01082 
01083 /**
01084  * \fn maximum(const XprMatrix<E, Rows, Cols>& e)
01085  * \brief Find the maximum of a matrix expression
01086  * \ingroup _unary_function
01087  */
01088 template<class E, std::size_t Rows, std::size_t Cols>
01089 inline
01090 Extremum<typename E::value_type, std::size_t, matrix_tag>
01091 maximum(const XprMatrix<E, Rows, Cols>& e) {
01092   typedef typename E::value_type             value_type;
01093 
01094   value_type                         temp(e(0, 0));
01095   std::size_t                         row_no(0), col_no(0);
01096 
01097   for(std::size_t i = 0; i != Rows; ++i) {
01098     for(std::size_t j = 0; j != Cols; ++j) {
01099       if(e(i, j) > temp) {
01100     temp = e(i, j);
01101     row_no = i;
01102     col_no = j;
01103       }
01104     }
01105   }
01106 
01107   return Extremum<value_type, std::size_t, matrix_tag>(temp, row_no, col_no);
01108 }
01109 
01110 
01111 /**
01112  * \fn maximum(const Matrix<T, Rows, Cols>& m)
01113  * \brief Find the maximum of a matrix
01114  * \ingroup _unary_function
01115  */
01116 template<class T, std::size_t Rows, std::size_t Cols>
01117 inline
01118 Extremum<T, std::size_t, matrix_tag>
01119 maximum(const Matrix<T, Rows, Cols>& m) { return maximum(m.as_expr()); }
01120 
01121 
01122 /**
01123  * \fn minimum(const XprMatrix<E, Rows, Cols>& e)
01124  * \brief Find the minimum of a matrix expression
01125  * \ingroup _unary_function
01126  */
01127 template<class E, std::size_t Rows, std::size_t Cols>
01128 inline
01129 Extremum<typename E::value_type, std::size_t, matrix_tag>
01130 minimum(const XprMatrix<E, Rows, Cols>& e) {
01131   typedef typename E::value_type             value_type;
01132 
01133   value_type                         temp(e(0, 0));
01134   std::size_t                         row_no(0), col_no(0);
01135 
01136   for(std::size_t i = 0; i != Rows; ++i) {
01137     for(std::size_t j = 0; j != Cols; ++j) {
01138       if(e(i, j) < temp) {
01139     temp = e(i, j);
01140     row_no = i;
01141     col_no = j;
01142       }
01143     }
01144   }
01145 
01146   return Extremum<value_type, std::size_t, matrix_tag>(temp, row_no, col_no);
01147 }
01148 
01149 
01150 /**
01151  * \fn minimum(const Matrix<T, Rows, Cols>& m)
01152  * \brief Find the minimum of a matrix
01153  * \ingroup _unary_function
01154  */
01155 template<class T, std::size_t Rows, std::size_t Cols>
01156 inline
01157 Extremum<T, std::size_t, matrix_tag>
01158 minimum(const Matrix<T, Rows, Cols>& m) { return minimum(m.as_expr()); }
01159 
01160 
01161 /**
01162  * \fn max(const XprMatrix<E, Rows, Cols>& e)
01163  * \brief Find the maximum of a matrix expression
01164  * \ingroup _unary_function
01165  */
01166 template<class E, std::size_t Rows, std::size_t Cols>
01167 inline
01168 typename E::value_type
01169 max(const XprMatrix<E, Rows, Cols>& e) {
01170   typedef typename E::value_type             value_type;
01171 
01172   value_type                         temp(e(0, 0));
01173 
01174   for(std::size_t i = 0; i != Rows; ++i)
01175     for(std::size_t j = 0; j != Cols; ++j)
01176       if(e(i, j) > temp)
01177     temp = e(i, j);
01178 
01179   return temp;
01180 }
01181 
01182 
01183 /**
01184  * \fn max(const Matrix<T, Rows, Cols>& m)
01185  * \brief Find the maximum of a matrix
01186  * \ingroup _unary_function
01187  */
01188 template<class T, std::size_t Rows, std::size_t Cols>
01189 inline
01190 T max(const Matrix<T, Rows, Cols>& m) {
01191   typedef T                         value_type;
01192   typedef typename Matrix<
01193    T, Rows, Cols
01194   >::const_iterator                    const_iterator;
01195 
01196   const_iterator                    iter(m.begin());
01197   const_iterator                    last(m.end());
01198   value_type                         temp(*iter);
01199 
01200   for( ; iter != last; ++iter)
01201     if(*iter > temp)
01202       temp = *iter;
01203 
01204   return temp;
01205 }
01206 
01207 
01208 /**
01209  * \fn min(const XprMatrix<E, Rows, Cols>& e)
01210  * \brief Find the minimum of a matrix expression
01211  * \ingroup _unary_function
01212  */
01213 template<class E, std::size_t Rows, std::size_t Cols>
01214 inline
01215 typename E::value_type
01216 min(const XprMatrix<E, Rows, Cols>& e) {
01217   typedef typename E::value_type            value_type;
01218 
01219   value_type                         temp(e(0, 0));
01220 
01221   for(std::size_t i = 0; i != Rows; ++i)
01222     for(std::size_t j = 0; j != Cols; ++j)
01223       if(e(i, j) < temp)
01224     temp = e(i, j);
01225 
01226   return temp;
01227 }
01228 
01229 
01230 /**
01231  * \fn min(const Matrix<T, Rows, Cols>& m)
01232  * \brief Find the minimum of a matrix
01233  * \ingroup _unary_function
01234  */
01235 template<class T, std::size_t Rows, std::size_t Cols>
01236 inline
01237 T min(const Matrix<T, Rows, Cols>& m) {
01238   typedef T                         value_type;
01239   typedef typename Matrix<
01240    T, Rows, Cols
01241   >::const_iterator                    const_iterator;
01242 
01243   const_iterator                    iter(m.begin());
01244   const_iterator                    last(m.end());
01245   value_type                         temp(*iter);
01246 
01247   for( ; iter != last; ++iter)
01248     if(*iter < temp)
01249       temp = *iter;
01250 
01251   return temp;
01252 }
01253 
01254 
01255 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01256  * other unary functions
01257  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
01258 
01259 
01260 /**
01261  * \fn XprMatrix<XprIdentity<typename M::value_type, M::Rows, M::Cols>, M::Rows, M::Cols>identity()
01262  * \brief Fill a matrix to an identity matrix.
01263  * \ingroup _unary_function
01264  *
01265  * \note The matrix doesn't need to be square. Only the elements
01266  *       where the current number of rows are equal to columns
01267  *       will be set to 1, else to 0.
01268  *
01269  * \par Usage:
01270  * \code
01271  * typedef Matrix<double,3,3>        matrix_type;
01272  * ...
01273  * matrix_type E( identity<double, 3, 3>() );
01274  * \endcode
01275  *
01276  * Note, we have to specify the type, number of rows and columns
01277  * since ADL can't work here.
01278  *
01279  *
01280  *
01281  * \since release 1.6.0
01282  */
01283 template<class T, std::size_t Rows, std::size_t Cols>
01284 inline
01285 XprMatrix<
01286   XprIdentity<T, Rows, Cols>,
01287   Rows, Cols
01288 >
01289 identity() {
01290   typedef XprIdentity<T, Rows, Cols>        expr_type;
01291 
01292   return XprMatrix<expr_type, Rows, Cols>(expr_type());
01293 }
01294 
01295 /**
01296  * \fn XprMatrix<XprIdentity<typename M::value_type, M::Rows, M::Cols>, M::Rows, M::Cols>identity()
01297  * \brief Fill a matrix to an identity matrix (convenience wrapper
01298  *        for matrix typedefs).
01299  * \ingroup _unary_function
01300  *
01301  * \note The matrix doesn't need to be square. Only the elements
01302  *       where the current number of rows are equal to columns
01303  *       will be set to 1, else to 0.
01304  *
01305  * \par Usage:
01306  * \code
01307  * typedef Matrix<double,3,3>        matrix_type;
01308  * ...
01309  * matrix_type E( identity<matrix_type>() );
01310  * \endcode
01311  *
01312  * Note, we have to specify the matrix type, since ADL can't work here.
01313  *
01314  * \since release 1.6.0
01315  */
01316 template<class M>
01317 inline
01318 XprMatrix<
01319   XprIdentity<
01320     typename M::value_type,
01321     M::Rows, M::Cols>,
01322   M::Rows, M::Cols
01323 >
01324 identity() {
01325   return identity<typename M::value_type, M::Rows, M::Cols>();
01326 }
01327 
01328 
01329 /**
01330  * \fn cmatrix_ref(const T* mem)
01331  * \brief Creates an expression wrapper for a C like matrices.
01332  * \ingroup _unary_function
01333  *
01334  * This is like creating a matrix of external data, as described
01335  * at \ref construct. With this function you wrap an expression
01336  * around a C style matrix and you can operate directly with it
01337  * as usual.
01338  *
01339  * \par Example:
01340  * \code
01341  * static float lhs[3][3] = {
01342  *   {-1,  0,  1}, { 1,  0,  1}, {-1,  0, -1}
01343  * };
01344  * static float rhs[3][3] = {
01345  *   { 0,  1,  1}, { 0,  1, -1}, { 0, -1,  1}
01346  * };
01347  * ...
01348  *
01349  * typedef Matrix<float, 3, 3>            matrix_type;
01350  *
01351  * matrix_type M( cmatrix_ref<float, 3, 3>(&lhs[0][0])
01352  *                *  cmatrix_ref<float, 3, 3>(&rhs[0][0]) );
01353  * \endcode
01354  *
01355  * \since release 1.6.0
01356  */
01357 template<class T, std::size_t Rows, std::size_t Cols>
01358 inline
01359 XprMatrix<
01360   MatrixConstReference<T, Rows, Cols>,
01361   Rows, Cols
01362 >
01363 cmatrix_ref(const T* mem) {
01364   typedef MatrixConstReference<T, Rows, Cols>    expr_type;
01365 
01366   return XprMatrix<expr_type, Rows, Cols>(expr_type(mem));
01367 }
01368 
01369 
01370 } // namespace tvmet
01371 
01372 #endif // TVMET_MATRIX_FUNCTIONS_H
01373 
01374 // Local Variables:
01375 // mode:C++
01376 // tab-width:8
01377 // End: