SourceForge Logo Tiny Vector Matrix library using Expression Templates Sourceforge Project Page

include/tvmet/xpr/MatrixOperators.h

Go to the documentation of this file.
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: MatrixOperators.h,v 1.23 2007-06-23 15:59:00 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_XPR_MATRIX_OPERATORS_H
00025 #define TVMET_XPR_MATRIX_OPERATORS_H
00026 
00027 namespace tvmet {
00028 
00029 
00030 /*********************************************************
00031  * PART I: DECLARATION
00032  *********************************************************/
00033 
00034 
00035 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00036  * Matrix arithmetic operators implemented by functions
00037  * add, sub, mul and div
00038  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00039 
00040 
00041 /*
00042  * operator(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1,Cols2>& rhs)
00043  *
00044  * Note: operations +,-,*,/ are per se element wise. Further more,
00045  * element wise operations make sense only for matrices of the same
00046  * size [varg].
00047  */
00048 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00049 template<class E1, std::size_t Rows1, std::size_t Cols1,      \
00050          class E2>                \
00051 XprMatrix<                  \
00052   XprBinOp<                 \
00053     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,    \
00054     XprMatrix<E1, Rows1, Cols1>,            \
00055     XprMatrix<E2, Rows1, Cols1>             \
00056   >,                    \
00057   Rows1, Cols1                  \
00058 >                   \
00059 operator OP (const XprMatrix<E1, Rows1, Cols1>& lhs,        \
00060        const XprMatrix<E2, Rows1, Cols1>& rhs) TVMET_CXX_ALWAYS_INLINE;
00061 
00062 TVMET_DECLARE_MACRO(add, +)   // per se element wise
00063 TVMET_DECLARE_MACRO(sub, -)   // per se element wise
00064 namespace element_wise {
00065   TVMET_DECLARE_MACRO(mul, *)   // see as prod()
00066   TVMET_DECLARE_MACRO(div, /)   // not defined for matrizes, must be element_wise
00067 }
00068 #undef TVMET_DECLARE_MACRO
00069 
00070 
00071 /*
00072  * operator(XprMatrix<E, Rows, Cols>,  POD)
00073  * operator(POD, XprMatrix<E, Rows, Cols>)
00074  * Note: operations +,-,*,/ are per se element wise
00075  */
00076 #define TVMET_DECLARE_MACRO(NAME, OP, POD)          \
00077 template<class E, std::size_t Rows, std::size_t Cols>       \
00078 XprMatrix<                  \
00079   XprBinOp<                 \
00080     Fcnl_##NAME<typename E::value_type, POD >,          \
00081     XprMatrix<E, Rows, Cols>,             \
00082     XprLiteral< POD >               \
00083   >,                    \
00084   Rows, Cols                  \
00085 >                   \
00086 operator OP (const XprMatrix<E, Rows, Cols>& lhs,         \
00087        POD rhs) TVMET_CXX_ALWAYS_INLINE;          \
00088                     \
00089 template<class E,std::size_t Rows, std::size_t Cols>        \
00090 XprMatrix<                  \
00091   XprBinOp<                 \
00092     Fcnl_##NAME<POD, typename E::value_type>,         \
00093     XprLiteral< POD >,                \
00094     XprMatrix<E, Rows, Cols>              \
00095   >,                    \
00096   Rows, Cols                  \
00097 >                   \
00098 operator OP (POD lhs,                 \
00099        const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00100 
00101 TVMET_DECLARE_MACRO(add, +, int)
00102 TVMET_DECLARE_MACRO(sub, -, int)
00103 TVMET_DECLARE_MACRO(mul, *, int)
00104 TVMET_DECLARE_MACRO(div, /, int)
00105 
00106 #if defined(TVMET_HAVE_LONG_LONG)
00107 TVMET_DECLARE_MACRO(add, +, long long int)
00108 TVMET_DECLARE_MACRO(sub, -, long long int)
00109 TVMET_DECLARE_MACRO(mul, *, long long int)
00110 TVMET_DECLARE_MACRO(div, /, long long int)
00111 #endif // defined(TVMET_HAVE_LONG_LONG)
00112 
00113 TVMET_DECLARE_MACRO(add, +, float)
00114 TVMET_DECLARE_MACRO(sub, -, float)
00115 TVMET_DECLARE_MACRO(mul, *, float)
00116 TVMET_DECLARE_MACRO(div, /, float)
00117 
00118 TVMET_DECLARE_MACRO(add, +, double)
00119 TVMET_DECLARE_MACRO(sub, -, double)
00120 TVMET_DECLARE_MACRO(mul, *, double)
00121 TVMET_DECLARE_MACRO(div, /, double)
00122 
00123 #if defined(TVMET_HAVE_LONG_DOUBLE)
00124 TVMET_DECLARE_MACRO(add, +, long double)
00125 TVMET_DECLARE_MACRO(sub, -, long double)
00126 TVMET_DECLARE_MACRO(mul, *, long double)
00127 TVMET_DECLARE_MACRO(div, /, long double)
00128 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00129 
00130 #undef TVMET_DECLARE_MACRO
00131 
00132 
00133 #if defined(TVMET_HAVE_COMPLEX)
00134 /*
00135  * operator(XprMatrix<E, Rows, Cols>, complex<>)
00136  * operator(complex<>, XprMatrix<E, Rows, Cols>)
00137  * Note: operations +,-,*,/ are per se element wise
00138  * \todo type promotion
00139  */
00140 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00141 template<class E, std::size_t Rows, std::size_t Cols, class T>      \
00142 XprMatrix<                  \
00143   XprBinOp<                 \
00144     Fcnl_##NAME<typename E::value_type, std::complex<T> >,      \
00145     XprMatrix<E, Rows, Cols>,             \
00146     XprLiteral< std::complex<T> >           \
00147   >,                    \
00148   Rows, Cols                  \
00149 >                   \
00150 operator OP (const XprMatrix<E, Rows, Cols>& lhs,       \
00151        const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;   \
00152                     \
00153 template<class E, std::size_t Rows, std::size_t Cols, class T>      \
00154 XprMatrix<                  \
00155   XprBinOp<                 \
00156     Fcnl_##NAME<std::complex<T>, typename E::value_type>,     \
00157     XprLiteral< std::complex<T> >,            \
00158     XprMatrix<E, Rows, Cols>              \
00159   >,                    \
00160   Rows, Cols                  \
00161 >                   \
00162 operator OP (const std::complex<T>& lhs,          \
00163        const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00164 
00165 TVMET_DECLARE_MACRO(add, +)
00166 TVMET_DECLARE_MACRO(sub, -)
00167 TVMET_DECLARE_MACRO(mul, *)
00168 TVMET_DECLARE_MACRO(div, /)
00169 
00170 #undef TVMET_DECLARE_MACRO
00171 
00172 #endif // defined(TVMET_HAVE_COMPLEX)
00173 
00174 
00175 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00176  * matrix specific operator*() = prod() operations
00177  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00178 
00179 
00186 template<class E1, std::size_t Rows1, std::size_t Cols1,
00187    class E2, std::size_t Cols2>
00188 XprMatrix<
00189   XprMMProduct<
00190     XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,  // M1(Rows1, Cols1)
00191     XprMatrix<E2, Cols1, Cols2>, Cols2    // M2(Cols1, Cols2)
00192   >,
00193   Rows1, Cols2
00194 >
00195 operator*(const XprMatrix<E1, Rows1, Cols1>& lhs,
00196     const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00197 
00198 
00199 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00200  * matrix-vector specific prod( ... ) operators
00201  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00202 
00203 
00210 template<class E1, std::size_t Rows, std::size_t Cols,
00211    class E2>
00212 XprVector<
00213   XprMVProduct<
00214     XprMatrix<E1, Rows, Cols>, Rows, Cols,
00215     XprVector<E2, Cols>
00216   >,
00217   Rows
00218 >
00219 operator*(const XprMatrix<E1, Rows, Cols>& lhs,
00220     const XprVector<E2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00221 
00222 
00223 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00224  * Matrix integer and compare operators
00225  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00226 
00227 
00228 /*
00229  * operator(XprMatrix<>, XprMatrix<>)
00230  * Note: operations are per se element wise
00231  */
00232 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00233 template<class E1, std::size_t Rows, std::size_t Cols,        \
00234          class E2>                \
00235 XprMatrix<                  \
00236   XprBinOp<                 \
00237     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,    \
00238     XprMatrix<E1, Rows, Cols>,              \
00239     XprMatrix<E2, Rows, Cols>             \
00240   >,                    \
00241   Rows, Cols                  \
00242 >                   \
00243 operator OP (const XprMatrix<E1, Rows, Cols>& lhs,        \
00244        const XprMatrix<E2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00245 
00246 // integer operators only, e.g used on double you will get an error
00247 namespace element_wise {
00248   TVMET_DECLARE_MACRO(mod, %)
00249   TVMET_DECLARE_MACRO(bitxor, ^)
00250   TVMET_DECLARE_MACRO(bitand, &)
00251   TVMET_DECLARE_MACRO(bitor, |)
00252   TVMET_DECLARE_MACRO(shl, <<)
00253   TVMET_DECLARE_MACRO(shr, >>)
00254 }
00255 
00256 // necessary operators for eval functions
00257 TVMET_DECLARE_MACRO(greater, >)
00258 TVMET_DECLARE_MACRO(less, <)
00259 TVMET_DECLARE_MACRO(greater_eq, >=)
00260 TVMET_DECLARE_MACRO(less_eq, <=)
00261 TVMET_DECLARE_MACRO(eq, ==)
00262 TVMET_DECLARE_MACRO(not_eq, !=)
00263 TVMET_DECLARE_MACRO(and, &&)
00264 TVMET_DECLARE_MACRO(or, ||)
00265 
00266 #undef TVMET_DECLARE_MACRO
00267 
00268 
00269 #if defined(TVMET_HAVE_COMPLEX)
00270 /*
00271  * operator(XprMatrix<E, Rows, Cols>, std::complex<>)
00272  * operator(std::complex<>, XprMatrix<E, Rows, Cols>)
00273  * Note: - per se element wise
00274  *       - bit ops on complex<int> doesn't make sense, stay away
00275  * \todo type promotion
00276  */
00277 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00278 template<class E, std::size_t Rows, std::size_t Cols, class T>      \
00279 XprMatrix<                  \
00280   XprBinOp<                 \
00281     Fcnl_##NAME<typename E::value_type, std::complex<T> >,      \
00282     XprMatrix<E, Rows, Cols>,             \
00283     XprLiteral< std::complex<T> >           \
00284   >,                    \
00285   Rows, Cols                  \
00286 >                   \
00287 operator OP (const XprMatrix<E, Rows, Cols>& lhs,         \
00288        const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;   \
00289                     \
00290 template<class E, std::size_t Rows, std::size_t Cols, class T>      \
00291 XprMatrix<                  \
00292   XprBinOp<                 \
00293     Fcnl_##NAME<std::complex<T>, typename E::value_type>,     \
00294     XprLiteral< std::complex<T> >,            \
00295     XprMatrix<E, Rows, Cols>              \
00296   >,                    \
00297   Rows, Cols                  \
00298 >                   \
00299 operator OP (const std::complex<T>& lhs,          \
00300        const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00301 
00302 // necessary operators for eval functions
00303 TVMET_DECLARE_MACRO(greater, >)
00304 TVMET_DECLARE_MACRO(less, <)
00305 TVMET_DECLARE_MACRO(greater_eq, >=)
00306 TVMET_DECLARE_MACRO(less_eq, <=)
00307 TVMET_DECLARE_MACRO(eq, ==)
00308 TVMET_DECLARE_MACRO(not_eq, !=)
00309 TVMET_DECLARE_MACRO(and, &&)
00310 TVMET_DECLARE_MACRO(or, ||)
00311 
00312 #undef TVMET_DECLARE_MACRO
00313 
00314 #endif // defined(TVMET_HAVE_COMPLEX)
00315 
00316 
00317 /*
00318  * operator(XprMatrix<E, Rows, Cols>, POD)
00319  * operator(POD, XprMatrix<E, Rows, Cols>)
00320  * Note: operations are per se element wise
00321  */
00322 #define TVMET_DECLARE_MACRO(NAME, OP, TP)         \
00323 template<class E, std::size_t Rows, std::size_t Cols>       \
00324 XprMatrix<                  \
00325   XprBinOp<                 \
00326     Fcnl_##NAME<typename E::value_type, TP >,         \
00327     XprMatrix<E, Rows, Cols>,             \
00328     XprLiteral< TP >                \
00329   >,                    \
00330   Rows, Cols                  \
00331 >                   \
00332 operator OP (const XprMatrix<E, Rows, Cols>& lhs,         \
00333        TP rhs) TVMET_CXX_ALWAYS_INLINE;         \
00334                     \
00335 template<class E, std::size_t Rows, std::size_t Cols>       \
00336 XprMatrix<                  \
00337   XprBinOp<                 \
00338     Fcnl_##NAME<TP, typename E::value_type>,          \
00339     XprLiteral< TP >,               \
00340     XprMatrix<E, Rows, Cols>              \
00341   >,                    \
00342   Rows, Cols                  \
00343 >                   \
00344 operator OP (TP lhs,                \
00345        const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00346 
00347 // integer operators only, e.g used on double you will get an error
00348 namespace element_wise {
00349   TVMET_DECLARE_MACRO(mod, %, int)
00350   TVMET_DECLARE_MACRO(bitxor, ^, int)
00351   TVMET_DECLARE_MACRO(bitand, &, int)
00352   TVMET_DECLARE_MACRO(bitor, |, int)
00353   TVMET_DECLARE_MACRO(shl, <<, int)
00354   TVMET_DECLARE_MACRO(shr, >>, int)
00355 }
00356 
00357 // necessary operators for eval functions
00358 TVMET_DECLARE_MACRO(greater, >, int)
00359 TVMET_DECLARE_MACRO(less, <, int)
00360 TVMET_DECLARE_MACRO(greater_eq, >=, int)
00361 TVMET_DECLARE_MACRO(less_eq, <=, int)
00362 TVMET_DECLARE_MACRO(eq, ==, int)
00363 TVMET_DECLARE_MACRO(not_eq, !=, int)
00364 TVMET_DECLARE_MACRO(and, &&, int)
00365 TVMET_DECLARE_MACRO(or, ||, int)
00366 
00367 #if defined(TVMET_HAVE_LONG_LONG)
00368 // integer operators only
00369 namespace element_wise {
00370   TVMET_DECLARE_MACRO(mod, %, long long int)
00371   TVMET_DECLARE_MACRO(bitxor, ^, long long int)
00372   TVMET_DECLARE_MACRO(bitand, &, long long int)
00373   TVMET_DECLARE_MACRO(bitor, |, long long int)
00374   TVMET_DECLARE_MACRO(shl, <<, long long int)
00375   TVMET_DECLARE_MACRO(shr, >>, long long int)
00376 }
00377 
00378 // necessary operators for eval functions
00379 TVMET_DECLARE_MACRO(greater, >, long long int)
00380 TVMET_DECLARE_MACRO(less, <, long long int)
00381 TVMET_DECLARE_MACRO(greater_eq, >=, long long int)
00382 TVMET_DECLARE_MACRO(less_eq, <=, long long int)
00383 TVMET_DECLARE_MACRO(eq, ==, long long int)
00384 TVMET_DECLARE_MACRO(not_eq, !=, long long int)
00385 TVMET_DECLARE_MACRO(and, &&, long long int)
00386 TVMET_DECLARE_MACRO(or, ||, long long int)
00387 #endif // defined(TVMET_HAVE_LONG_LONG)
00388 
00389 // necessary operators for eval functions
00390 TVMET_DECLARE_MACRO(greater, >, float)
00391 TVMET_DECLARE_MACRO(less, <, float)
00392 TVMET_DECLARE_MACRO(greater_eq, >=, float)
00393 TVMET_DECLARE_MACRO(less_eq, <=, float)
00394 TVMET_DECLARE_MACRO(eq, ==, float)
00395 TVMET_DECLARE_MACRO(not_eq, !=, float)
00396 TVMET_DECLARE_MACRO(and, &&, float)
00397 TVMET_DECLARE_MACRO(or, ||, float)
00398 
00399 // necessary operators for eval functions
00400 TVMET_DECLARE_MACRO(greater, >, double)
00401 TVMET_DECLARE_MACRO(less, <, double)
00402 TVMET_DECLARE_MACRO(greater_eq, >=, double)
00403 TVMET_DECLARE_MACRO(less_eq, <=, double)
00404 TVMET_DECLARE_MACRO(eq, ==, double)
00405 TVMET_DECLARE_MACRO(not_eq, !=, double)
00406 TVMET_DECLARE_MACRO(and, &&, double)
00407 TVMET_DECLARE_MACRO(or, ||, double)
00408 
00409 #if defined(TVMET_HAVE_LONG_DOUBLE)
00410 // necessary operators for eval functions
00411 TVMET_DECLARE_MACRO(greater, >, long double)
00412 TVMET_DECLARE_MACRO(less, <, long double)
00413 TVMET_DECLARE_MACRO(greater_eq, >=, long double)
00414 TVMET_DECLARE_MACRO(less_eq, <=, long double)
00415 TVMET_DECLARE_MACRO(eq, ==, long double)
00416 TVMET_DECLARE_MACRO(not_eq, !=, long double)
00417 TVMET_DECLARE_MACRO(and, &&, long double)
00418 TVMET_DECLARE_MACRO(or, ||, long double)
00419 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00420 
00421 #undef TVMET_DECLARE_MACRO
00422 
00423 
00424 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00425  * global unary operators
00426  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00427 
00428 
00429 /*
00430  * unary_operator(const XprMatrix<E, Rows, Cols>& m)
00431  * Note: per se element wise
00432  */
00433 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00434 template <class E, std::size_t Rows, std::size_t Cols>        \
00435 XprMatrix<                  \
00436   XprUnOp<                  \
00437     Fcnl_##NAME<typename E::value_type>,          \
00438     XprMatrix<E, Rows, Cols>              \
00439   >,                    \
00440   Rows, Cols                  \
00441 >                   \
00442 operator OP (const XprMatrix<E, Rows, Cols>& m) TVMET_CXX_ALWAYS_INLINE;
00443 
00444 TVMET_DECLARE_MACRO(not, !)
00445 TVMET_DECLARE_MACRO(compl, ~)
00446 TVMET_DECLARE_MACRO(neg, -)
00447 
00448 #undef TVMET_DECLARE_MACRO
00449 
00450 
00451 /*********************************************************
00452  * PART II: IMPLEMENTATION
00453  *********************************************************/
00454 
00455 
00456 
00457 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00458  * Matrix arithmetic operators implemented by functions
00459  * add, sub, mul and div
00460  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00461 
00462 
00463 /*
00464  * operator(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1,Cols2>& rhs)
00465  *
00466  * Note: operations +,-,*,/ are per se element wise. Further more,
00467  * element wise operations make sense only for matrices of the same
00468  * size [varg].
00469  */
00470 #define TVMET_IMPLEMENT_MACRO(NAME, OP)         \
00471 template<class E1, std::size_t Rows1, std::size_t Cols1,    \
00472          class E2>              \
00473 inline                  \
00474 XprMatrix<                \
00475   XprBinOp<               \
00476     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,  \
00477     XprMatrix<E1, Rows1, Cols1>,          \
00478     XprMatrix<E2, Rows1, Cols1>           \
00479   >,                  \
00480   Rows1, Cols1                \
00481 >                 \
00482 operator OP (const XprMatrix<E1, Rows1, Cols1>& lhs,      \
00483        const XprMatrix<E2, Rows1, Cols1>& rhs) {      \
00484   return NAME (lhs, rhs);           \
00485 }
00486 
00487 TVMET_IMPLEMENT_MACRO(add, +)   // per se element wise
00488 TVMET_IMPLEMENT_MACRO(sub, -)   // per se element wise
00489 namespace element_wise {
00490   TVMET_IMPLEMENT_MACRO(mul, *)   // see as prod()
00491   TVMET_IMPLEMENT_MACRO(div, /)   // not defined for matrizes, must be element_wise
00492 }
00493 #undef TVMET_IMPLEMENT_MACRO
00494 
00495 
00496 /*
00497  * operator(XprMatrix<E, Rows, Cols>,  POD)
00498  * operator(POD, XprMatrix<E, Rows, Cols>)
00499  * Note: operations +,-,*,/ are per se element wise
00500  */
00501 #define TVMET_IMPLEMENT_MACRO(NAME, OP, POD)      \
00502 template<class E, std::size_t Rows, std::size_t Cols>   \
00503 inline                \
00504 XprMatrix<              \
00505   XprBinOp<             \
00506     Fcnl_##NAME<typename E::value_type, POD >,      \
00507     XprMatrix<E, Rows, Cols>,         \
00508     XprLiteral< POD >           \
00509   >,                \
00510   Rows, Cols              \
00511 >               \
00512 operator OP (const XprMatrix<E, Rows, Cols>& lhs, POD rhs) {  \
00513   return NAME (lhs, rhs);         \
00514 }               \
00515                 \
00516 template<class E,std::size_t Rows, std::size_t Cols>    \
00517 inline                \
00518 XprMatrix<              \
00519   XprBinOp<             \
00520     Fcnl_##NAME<POD, typename E::value_type>,     \
00521     XprLiteral< POD >,            \
00522     XprMatrix<E, Rows, Cols>          \
00523   >,                \
00524   Rows, Cols              \
00525 >               \
00526 operator OP (POD lhs, const XprMatrix<E, Rows, Cols>& rhs) {  \
00527   return NAME (lhs, rhs);         \
00528 }
00529 
00530 TVMET_IMPLEMENT_MACRO(add, +, int)
00531 TVMET_IMPLEMENT_MACRO(sub, -, int)
00532 TVMET_IMPLEMENT_MACRO(mul, *, int)
00533 TVMET_IMPLEMENT_MACRO(div, /, int)
00534 
00535 #if defined(TVMET_HAVE_LONG_LONG)
00536 TVMET_IMPLEMENT_MACRO(add, +, long long int)
00537 TVMET_IMPLEMENT_MACRO(sub, -, long long int)
00538 TVMET_IMPLEMENT_MACRO(mul, *, long long int)
00539 TVMET_IMPLEMENT_MACRO(div, /, long long int)
00540 #endif // defined(TVMET_HAVE_LONG_LONG)
00541 
00542 TVMET_IMPLEMENT_MACRO(add, +, float)
00543 TVMET_IMPLEMENT_MACRO(sub, -, float)
00544 TVMET_IMPLEMENT_MACRO(mul, *, float)
00545 TVMET_IMPLEMENT_MACRO(div, /, float)
00546 
00547 TVMET_IMPLEMENT_MACRO(add, +, double)
00548 TVMET_IMPLEMENT_MACRO(sub, -, double)
00549 TVMET_IMPLEMENT_MACRO(mul, *, double)
00550 TVMET_IMPLEMENT_MACRO(div, /, double)
00551 
00552 #if defined(TVMET_HAVE_LONG_DOUBLE)
00553 TVMET_IMPLEMENT_MACRO(add, +, long double)
00554 TVMET_IMPLEMENT_MACRO(sub, -, long double)
00555 TVMET_IMPLEMENT_MACRO(mul, *, long double)
00556 TVMET_IMPLEMENT_MACRO(div, /, long double)
00557 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00558 
00559 #undef TVMET_IMPLEMENT_MACRO
00560 
00561 
00562 #if defined(TVMET_HAVE_COMPLEX)
00563 /*
00564  * operator(XprMatrix<E, Rows, Cols>, complex<>)
00565  * operator(complex<>, XprMatrix<E, Rows, Cols>)
00566  * Note: operations +,-,*,/ are per se element wise
00567  * \todo type promotion
00568  */
00569 #define TVMET_IMPLEMENT_MACRO(NAME, OP)       \
00570 template<class E, std::size_t Rows, std::size_t Cols, class T>  \
00571 inline                \
00572 XprMatrix<              \
00573   XprBinOp<             \
00574     Fcnl_##NAME<typename E::value_type, std::complex<T> >,  \
00575     XprMatrix<E, Rows, Cols>,         \
00576     XprLiteral< std::complex<T> >       \
00577   >,                \
00578   Rows, Cols              \
00579 >               \
00580 operator OP (const XprMatrix<E, Rows, Cols>& lhs,   \
00581        const std::complex<T>& rhs) {      \
00582   return NAME (lhs, rhs);         \
00583 }               \
00584                 \
00585 template<class E, std::size_t Rows, std::size_t Cols, class T>  \
00586 inline                \
00587 XprMatrix<              \
00588   XprBinOp<             \
00589     Fcnl_##NAME<std::complex<T>, typename E::value_type>, \
00590     XprLiteral< std::complex<T> >,        \
00591     XprMatrix<E, Rows, Cols>          \
00592   >,                \
00593   Rows, Cols              \
00594 >               \
00595 operator OP (const std::complex<T>& lhs,      \
00596        const XprMatrix<E, Rows, Cols>& rhs) {   \
00597   return NAME (lhs, rhs);         \
00598 }
00599 
00600 TVMET_IMPLEMENT_MACRO(add, +)
00601 TVMET_IMPLEMENT_MACRO(sub, -)
00602 TVMET_IMPLEMENT_MACRO(mul, *)
00603 TVMET_IMPLEMENT_MACRO(div, /)
00604 
00605 #undef TVMET_IMPLEMENT_MACRO
00606 
00607 #endif // defined(TVMET_HAVE_COMPLEX)
00608 
00609 
00610 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00611  * matrix specific operator*() = prod() operations
00612  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00613 
00614 
00621 template<class E1, std::size_t Rows1, std::size_t Cols1,
00622    class E2, std::size_t Cols2>
00623 inline
00624 XprMatrix<
00625   XprMMProduct<
00626     XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,  // M1(Rows1, Cols1)
00627     XprMatrix<E2, Cols1, Cols2>, Cols2    // M2(Cols1, Cols2)
00628   >,
00629   Rows1, Cols2
00630 >
00631 operator*(const XprMatrix<E1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
00632   return prod(lhs, rhs);
00633 }
00634 
00635 
00636 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00637  * matrix-vector specific prod( ... ) operators
00638  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00639 
00640 
00647 template<class E1, std::size_t Rows, std::size_t Cols,
00648    class E2>
00649 inline
00650 XprVector<
00651   XprMVProduct<
00652     XprMatrix<E1, Rows, Cols>, Rows, Cols,
00653     XprVector<E2, Cols>
00654   >,
00655   Rows
00656 >
00657 operator*(const XprMatrix<E1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs) {
00658   return prod(lhs, rhs);
00659 }
00660 
00661 
00662 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00663  * Matrix integer and compare operators
00664  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00665 
00666 
00667 /*
00668  * operator(XprMatrix<>, XprMatrix<>)
00669  * Note: operations are per se element wise
00670  */
00671 #define TVMET_IMPLEMENT_MACRO(NAME, OP)         \
00672 template<class E1, std::size_t Rows, std::size_t Cols,      \
00673          class E2>              \
00674 inline                  \
00675 XprMatrix<                \
00676   XprBinOp<               \
00677     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,  \
00678     XprMatrix<E1, Rows, Cols>,            \
00679     XprMatrix<E2, Rows, Cols>           \
00680   >,                  \
00681   Rows, Cols                \
00682 >                 \
00683 operator OP (const XprMatrix<E1, Rows, Cols>& lhs,      \
00684        const XprMatrix<E2, Rows, Cols>& rhs) {      \
00685   typedef XprBinOp<             \
00686     Fcnl_##NAME<typename E1::value_type, typename E2::value_type>,  \
00687     XprMatrix<E1, Rows, Cols>,            \
00688     XprMatrix<E2, Rows, Cols>           \
00689   >                 expr_type;  \
00690   return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs, rhs));   \
00691 }
00692 
00693 // integer operators only, e.g used on double you will get an error
00694 namespace element_wise {
00695   TVMET_IMPLEMENT_MACRO(mod, %)
00696   TVMET_IMPLEMENT_MACRO(bitxor, ^)
00697   TVMET_IMPLEMENT_MACRO(bitand, &)
00698   TVMET_IMPLEMENT_MACRO(bitor, |)
00699   TVMET_IMPLEMENT_MACRO(shl, <<)
00700   TVMET_IMPLEMENT_MACRO(shr, >>)
00701 }
00702 
00703 // necessary operators for eval functions
00704 TVMET_IMPLEMENT_MACRO(greater, >)
00705 TVMET_IMPLEMENT_MACRO(less, <)
00706 TVMET_IMPLEMENT_MACRO(greater_eq, >=)
00707 TVMET_IMPLEMENT_MACRO(less_eq, <=)
00708 TVMET_IMPLEMENT_MACRO(eq, ==)
00709 TVMET_IMPLEMENT_MACRO(not_eq, !=)
00710 TVMET_IMPLEMENT_MACRO(and, &&)
00711 TVMET_IMPLEMENT_MACRO(or, ||)
00712 
00713 #undef TVMET_IMPLEMENT_MACRO
00714 
00715 
00716 #if defined(TVMET_HAVE_COMPLEX)
00717 /*
00718  * operator(XprMatrix<E, Rows, Cols>, std::complex<>)
00719  * operator(std::complex<>, XprMatrix<E, Rows, Cols>)
00720  * Note: - per se element wise
00721  *       - bit ops on complex<int> doesn't make sense, stay away
00722  * \todo type promotion
00723  */
00724 #define TVMET_IMPLEMENT_MACRO(NAME, OP)         \
00725 template<class E, std::size_t Rows, std::size_t Cols, class T>    \
00726 inline                  \
00727 XprMatrix<                \
00728   XprBinOp<               \
00729     Fcnl_##NAME<typename E::value_type, std::complex<T> >,    \
00730     XprMatrix<E, Rows, Cols>,           \
00731     XprLiteral< std::complex<T> >         \
00732   >,                  \
00733   Rows, Cols                \
00734 >                 \
00735 operator OP (const XprMatrix<E, Rows, Cols>& lhs,       \
00736        const std::complex<T>& rhs) {        \
00737   typedef XprBinOp<             \
00738     Fcnl_##NAME<typename E::value_type, std::complex<T> >,    \
00739     XprMatrix<E, Rows, Cols>,           \
00740     XprLiteral< std::complex<T> >         \
00741   >             expr_type;  \
00742   return XprMatrix<expr_type, Rows, Cols>(        \
00743     expr_type(lhs, XprLiteral< std::complex<T> >(rhs)));    \
00744 }                 \
00745                   \
00746 template<class E, std::size_t Rows, std::size_t Cols, class T>    \
00747 inline                  \
00748 XprMatrix<                \
00749   XprBinOp<               \
00750     Fcnl_##NAME<std::complex<T>, typename E::value_type>,   \
00751     XprLiteral< std::complex<T> >,          \
00752     XprMatrix<E, Rows, Cols>            \
00753   >,                  \
00754   Rows, Cols                \
00755 >                 \
00756 operator OP (const std::complex<T>& lhs,        \
00757        const XprMatrix<E, Rows, Cols>& rhs) {     \
00758   typedef XprBinOp<             \
00759     Fcnl_##NAME< std::complex<T>, typename E::value_type>,    \
00760     XprLiteral< std::complex<T> >,          \
00761     XprMatrix<E, Rows, Cols>            \
00762   >             expr_type;  \
00763   return XprMatrix<expr_type, Rows, Cols>(        \
00764     expr_type(XprLiteral< std::complex<T> >(lhs), rhs));    \
00765 }
00766 
00767 // necessary operators for eval functions
00768 TVMET_IMPLEMENT_MACRO(greater, >)
00769 TVMET_IMPLEMENT_MACRO(less, <)
00770 TVMET_IMPLEMENT_MACRO(greater_eq, >=)
00771 TVMET_IMPLEMENT_MACRO(less_eq, <=)
00772 TVMET_IMPLEMENT_MACRO(eq, ==)
00773 TVMET_IMPLEMENT_MACRO(not_eq, !=)
00774 TVMET_IMPLEMENT_MACRO(and, &&)
00775 TVMET_IMPLEMENT_MACRO(or, ||)
00776 
00777 #undef TVMET_IMPLEMENT_MACRO
00778 
00779 #endif // defined(TVMET_HAVE_COMPLEX)
00780 
00781 
00782 /*
00783  * operator(XprMatrix<E, Rows, Cols>, POD)
00784  * operator(POD, XprMatrix<E, Rows, Cols>)
00785  * Note: operations are per se element wise
00786  */
00787 #define TVMET_IMPLEMENT_MACRO(NAME, OP, TP)       \
00788 template<class E, std::size_t Rows, std::size_t Cols>     \
00789 inline                  \
00790 XprMatrix<                \
00791   XprBinOp<               \
00792     Fcnl_##NAME<typename E::value_type, TP >,       \
00793     XprMatrix<E, Rows, Cols>,           \
00794     XprLiteral< TP >              \
00795   >,                  \
00796   Rows, Cols                \
00797 >                 \
00798 operator OP (const XprMatrix<E, Rows, Cols>& lhs, TP rhs) {   \
00799   typedef XprBinOp<             \
00800     Fcnl_##NAME<typename E::value_type, TP >,       \
00801     XprMatrix<E, Rows, Cols>,           \
00802     XprLiteral< TP >              \
00803   >             expr_type;  \
00804   return XprMatrix<expr_type, Rows, Cols>(        \
00805     expr_type(lhs, XprLiteral< TP >(rhs)));       \
00806 }                 \
00807                   \
00808 template<class E, std::size_t Rows, std::size_t Cols>     \
00809 inline                  \
00810 XprMatrix<                \
00811   XprBinOp<               \
00812     Fcnl_##NAME<TP, typename E::value_type>,        \
00813     XprLiteral< TP >,             \
00814     XprMatrix<E, Rows, Cols>            \
00815   >,                  \
00816   Rows, Cols                \
00817 >                 \
00818 operator OP (TP lhs, const XprMatrix<E, Rows, Cols>& rhs) {   \
00819   typedef XprBinOp<             \
00820     Fcnl_##NAME< TP, typename E::value_type>,       \
00821     XprLiteral< TP >,             \
00822     XprMatrix<E, Rows, Cols>            \
00823   >             expr_type;  \
00824   return XprMatrix<expr_type, Rows, Cols>(        \
00825     expr_type(XprLiteral< TP >(lhs), rhs));       \
00826 }
00827 
00828 
00829 // integer operators only, e.g used on double you will get an error
00830 namespace element_wise {
00831   TVMET_IMPLEMENT_MACRO(mod, %, int)
00832   TVMET_IMPLEMENT_MACRO(bitxor, ^, int)
00833   TVMET_IMPLEMENT_MACRO(bitand, &, int)
00834   TVMET_IMPLEMENT_MACRO(bitor, |, int)
00835   TVMET_IMPLEMENT_MACRO(shl, <<, int)
00836   TVMET_IMPLEMENT_MACRO(shr, >>, int)
00837 }
00838 
00839 // necessary operators for eval functions
00840 TVMET_IMPLEMENT_MACRO(greater, >, int)
00841 TVMET_IMPLEMENT_MACRO(less, <, int)
00842 TVMET_IMPLEMENT_MACRO(greater_eq, >=, int)
00843 TVMET_IMPLEMENT_MACRO(less_eq, <=, int)
00844 TVMET_IMPLEMENT_MACRO(eq, ==, int)
00845 TVMET_IMPLEMENT_MACRO(not_eq, !=, int)
00846 TVMET_IMPLEMENT_MACRO(and, &&, int)
00847 TVMET_IMPLEMENT_MACRO(or, ||, int)
00848 
00849 #if defined(TVMET_HAVE_LONG_LONG)
00850 // integer operators only
00851 namespace element_wise {
00852   TVMET_IMPLEMENT_MACRO(mod, %, long long int)
00853   TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int)
00854   TVMET_IMPLEMENT_MACRO(bitand, &, long long int)
00855   TVMET_IMPLEMENT_MACRO(bitor, |, long long int)
00856   TVMET_IMPLEMENT_MACRO(shl, <<, long long int)
00857   TVMET_IMPLEMENT_MACRO(shr, >>, long long int)
00858 }
00859 
00860 // necessary operators for eval functions
00861 TVMET_IMPLEMENT_MACRO(greater, >, long long int)
00862 TVMET_IMPLEMENT_MACRO(less, <, long long int)
00863 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int)
00864 TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int)
00865 TVMET_IMPLEMENT_MACRO(eq, ==, long long int)
00866 TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int)
00867 TVMET_IMPLEMENT_MACRO(and, &&, long long int)
00868 TVMET_IMPLEMENT_MACRO(or, ||, long long int)
00869 #endif // defined(TVMET_HAVE_LONG_LONG)
00870 
00871 // necessary operators for eval functions
00872 TVMET_IMPLEMENT_MACRO(greater, >, float)
00873 TVMET_IMPLEMENT_MACRO(less, <, float)
00874 TVMET_IMPLEMENT_MACRO(greater_eq, >=, float)
00875 TVMET_IMPLEMENT_MACRO(less_eq, <=, float)
00876 TVMET_IMPLEMENT_MACRO(eq, ==, float)
00877 TVMET_IMPLEMENT_MACRO(not_eq, !=, float)
00878 TVMET_IMPLEMENT_MACRO(and, &&, float)
00879 TVMET_IMPLEMENT_MACRO(or, ||, float)
00880 
00881 // necessary operators for eval functions
00882 TVMET_IMPLEMENT_MACRO(greater, >, double)
00883 TVMET_IMPLEMENT_MACRO(less, <, double)
00884 TVMET_IMPLEMENT_MACRO(greater_eq, >=, double)
00885 TVMET_IMPLEMENT_MACRO(less_eq, <=, double)
00886 TVMET_IMPLEMENT_MACRO(eq, ==, double)
00887 TVMET_IMPLEMENT_MACRO(not_eq, !=, double)
00888 TVMET_IMPLEMENT_MACRO(and, &&, double)
00889 TVMET_IMPLEMENT_MACRO(or, ||, double)
00890 
00891 #if defined(TVMET_HAVE_LONG_DOUBLE)
00892 // necessary operators for eval functions
00893 TVMET_IMPLEMENT_MACRO(greater, >, long double)
00894 TVMET_IMPLEMENT_MACRO(less, <, long double)
00895 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double)
00896 TVMET_IMPLEMENT_MACRO(less_eq, <=, long double)
00897 TVMET_IMPLEMENT_MACRO(eq, ==, long double)
00898 TVMET_IMPLEMENT_MACRO(not_eq, !=, long double)
00899 TVMET_IMPLEMENT_MACRO(and, &&, long double)
00900 TVMET_IMPLEMENT_MACRO(or, ||, long double)
00901 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00902 
00903 #undef TVMET_IMPLEMENT_MACRO
00904 
00905 
00906 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00907  * global unary operators
00908  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00909 
00910 
00911 /*
00912  * unary_operator(const XprMatrix<E, Rows, Cols>& m)
00913  * Note: per se element wise
00914  */
00915 #define TVMET_IMPLEMENT_MACRO(NAME, OP)         \
00916 template <class E, std::size_t Rows, std::size_t Cols>      \
00917 inline                  \
00918 XprMatrix<                \
00919   XprUnOp<                \
00920     Fcnl_##NAME<typename E::value_type>,        \
00921     XprMatrix<E, Rows, Cols>            \
00922   >,                  \
00923   Rows, Cols                \
00924 >                 \
00925 operator OP (const XprMatrix<E, Rows, Cols>& m) {     \
00926   typedef XprUnOp<              \
00927     Fcnl_##NAME<typename E::value_type>,        \
00928     XprMatrix<E, Rows, Cols>            \
00929   >                expr_type; \
00930   return XprMatrix<expr_type, Rows, Cols>(expr_type(m));    \
00931 }
00932 
00933 TVMET_IMPLEMENT_MACRO(not, !)
00934 TVMET_IMPLEMENT_MACRO(compl, ~)
00935 TVMET_IMPLEMENT_MACRO(neg, -)
00936 
00937 #undef TVMET_IMPLEMENT_MACRO
00938 
00939 
00940 } // namespace tvmet
00941 
00942 #endif // TVMET_XPR_MATRIX_OPERATORS_H
00943 
00944 // Local Variables:
00945 // mode:C++
00946 // tab-width:8
00947 // End:

Author: