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

include/tvmet/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.37 2007-06-23 15:58:58 opetzold Exp $
00022  */
00023 
00024 #ifndef TVMET_MATRIX_OPERATORS_H
00025 #define TVMET_MATRIX_OPERATORS_H
00026 
00027 namespace tvmet {
00028 
00029 
00030 /*********************************************************
00031  * PART I: DECLARATION
00032  *********************************************************/
00033 
00034 
00035 template<class T, std::size_t Rows, std::size_t Cols>
00036 std::ostream& operator<<(std::ostream& os,
00037        const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00038 
00039 
00040 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00041  * Member operators (arithmetic and bit ops)
00042  *++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00043 
00044 
00045 /*
00046  * update_operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00047  * update_operator(Matrix<T1, Rows, Cols>, XprMatrix<E, Rows, Cols> rhs)
00048  * Note: per se element wise
00049  * \todo: the operator*= can have element wise mul oder product, decide!
00050  */
00051 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00052 template<class T1, class T2, std::size_t Rows, std::size_t Cols>    \
00053 Matrix<T1, Rows, Cols>&               \
00054 operator OP (Matrix<T1, Rows, Cols>& lhs,           \
00055        const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;  \
00056                     \
00057 template<class T, class E, std::size_t Rows,  std::size_t Cols>     \
00058 Matrix<T, Rows, Cols>&                \
00059 operator OP (Matrix<T, Rows, Cols>& lhs,          \
00060        const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00061 
00062 TVMET_DECLARE_MACRO(add_eq, +=)   // per se element wise
00063 TVMET_DECLARE_MACRO(sub_eq, -=)   // per se element wise
00064 namespace element_wise {
00065   TVMET_DECLARE_MACRO(mul_eq, *=)   // see note
00066   TVMET_DECLARE_MACRO(div_eq, /=)   // not defined for vectors
00067 }
00068 
00069 // integer operators only, e.g used on double you wil get an error
00070 namespace element_wise {
00071   TVMET_DECLARE_MACRO(mod_eq, %=)
00072   TVMET_DECLARE_MACRO(xor_eq, ^=)
00073   TVMET_DECLARE_MACRO(and_eq, &=)
00074   TVMET_DECLARE_MACRO(or_eq, |=)
00075   TVMET_DECLARE_MACRO(shl_eq, <<=)
00076   TVMET_DECLARE_MACRO(shr_eq, >>=)
00077 }
00078 
00079 #undef TVMET_DECLARE_MACRO
00080 
00081 
00082 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00083  * Matrix arithmetic operators implemented by functions
00084  * add, sub, mul and div
00085  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00086 
00087 
00088 /*
00089  * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00090  * operator(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
00091  * operator(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
00092  * Note: per se element wise
00093  */
00094 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00095 template<class T1, class T2, std::size_t Rows, std::size_t Cols>    \
00096 XprMatrix<                  \
00097   XprBinOp<                 \
00098     Fcnl_##NAME<T1, T2>,              \
00099     MatrixConstReference<T1, Rows, Cols>,         \
00100     MatrixConstReference<T2, Rows, Cols>          \
00101   >,                    \
00102   Rows, Cols                  \
00103 >                   \
00104 operator OP (const Matrix<T1, Rows, Cols>& lhs,         \
00105        const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;  \
00106                     \
00107 template<class E, class T, std::size_t Rows, std::size_t Cols>      \
00108 XprMatrix<                  \
00109   XprBinOp<                 \
00110     Fcnl_##NAME<typename E::value_type, T>,         \
00111     XprMatrix<E, Rows, Cols>,             \
00112     MatrixConstReference<T, Rows, Cols>           \
00113   >,                    \
00114   Rows, Cols                  \
00115 >                   \
00116 operator OP (const XprMatrix<E, Rows, Cols>& lhs,         \
00117        const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;   \
00118                     \
00119 template<class T, class E, std::size_t Rows, std::size_t Cols>      \
00120 XprMatrix<                  \
00121   XprBinOp<                 \
00122     Fcnl_##NAME<typename E::value_type, T>,         \
00123     MatrixConstReference<T, Rows, Cols>,          \
00124     XprMatrix<E, Rows, Cols>              \
00125   >,                    \
00126   Rows, Cols                  \
00127 >                   \
00128 operator OP (const Matrix<T, Rows, Cols>& lhs,          \
00129        const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00130 
00131 TVMET_DECLARE_MACRO(add, +)     // per se element wise
00132 TVMET_DECLARE_MACRO(sub, -)     // per se element wise
00133 namespace element_wise {
00134   TVMET_DECLARE_MACRO(mul, *)     // see as prod()
00135   TVMET_DECLARE_MACRO(div, /)     // not defined for matrizes
00136 }
00137 #undef TVMET_DECLARE_MACRO
00138 
00139 
00140 /*
00141  * operator(Matrix<T, Rows, Cols>, POD)
00142  * operator(POD, Matrix<T, Rows, Cols>)
00143  * Note: operations +,-,*,/ are per se element wise
00144  */
00145 #define TVMET_DECLARE_MACRO(NAME, OP, POD)        \
00146 template<class T, std::size_t Rows, std::size_t Cols>     \
00147 XprMatrix<                \
00148   XprBinOp<               \
00149     Fcnl_##NAME<T, POD >,           \
00150     MatrixConstReference<T, Rows, Cols>,        \
00151     XprLiteral<POD >              \
00152   >,                  \
00153   Rows, Cols                \
00154 >                 \
00155 operator OP (const Matrix<T, Rows, Cols>& lhs,        \
00156        POD rhs) TVMET_CXX_ALWAYS_INLINE;        \
00157                   \
00158 template<class T, std::size_t Rows, std::size_t Cols>     \
00159 XprMatrix<                \
00160   XprBinOp<               \
00161     Fcnl_##NAME< POD, T>,           \
00162     XprLiteral< POD >,              \
00163     MatrixConstReference<T, Rows, Cols>         \
00164   >,                  \
00165   Rows, Cols                \
00166 >                 \
00167 operator OP (POD lhs,               \
00168        const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00169 
00170 TVMET_DECLARE_MACRO(add, +, int)
00171 TVMET_DECLARE_MACRO(sub, -, int)
00172 TVMET_DECLARE_MACRO(mul, *, int)
00173 TVMET_DECLARE_MACRO(div, /, int)
00174 
00175 #if defined(TVMET_HAVE_LONG_LONG)
00176 TVMET_DECLARE_MACRO(add, +, long long int)
00177 TVMET_DECLARE_MACRO(sub, -, long long int)
00178 TVMET_DECLARE_MACRO(mul, *, long long int)
00179 TVMET_DECLARE_MACRO(div, /, long long int)
00180 #endif // defined(TVMET_HAVE_LONG_LONG)
00181 
00182 TVMET_DECLARE_MACRO(add, +, float)
00183 TVMET_DECLARE_MACRO(sub, -, float)
00184 TVMET_DECLARE_MACRO(mul, *, float)
00185 TVMET_DECLARE_MACRO(div, /, float)
00186 
00187 TVMET_DECLARE_MACRO(add, +, double)
00188 TVMET_DECLARE_MACRO(sub, -, double)
00189 TVMET_DECLARE_MACRO(mul, *, double)
00190 TVMET_DECLARE_MACRO(div, /, double)
00191 
00192 #if defined(TVMET_HAVE_LONG_DOUBLE)
00193 TVMET_DECLARE_MACRO(add, +, long double)
00194 TVMET_DECLARE_MACRO(sub, -, long double)
00195 TVMET_DECLARE_MACRO(mul, *, long double)
00196 TVMET_DECLARE_MACRO(div, /, long double)
00197 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00198 
00199 #undef TVMET_DECLARE_MACRO
00200 
00201 
00202 #if defined(TVMET_HAVE_COMPLEX)
00203 /*
00204  * operator(Matrix<T, Rows, Cols>, complex<T>)
00205  * operator(complex<T>, Matrix<T, Rows, Cols>)
00206  * Note: operations +,-,*,/ are per se element wise
00207  * \todo type promotion
00208  */
00209 #define TVMET_DECLARE_MACRO(NAME, OP)             \
00210 template<class T, std::size_t Rows, std::size_t Cols>         \
00211 XprMatrix<                    \
00212   XprBinOp<                   \
00213     Fcnl_##NAME< std::complex<T>, std::complex<T> >,          \
00214     MatrixConstReference< std::complex<T>, Rows, Cols>,         \
00215     XprLiteral<std::complex<T> >              \
00216   >,                      \
00217   Rows, Cols                    \
00218 >                     \
00219 operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs,       \
00220        const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;     \
00221                       \
00222 template<class T, std::size_t Rows, std::size_t Cols>         \
00223 XprMatrix<                    \
00224   XprBinOp<                   \
00225     Fcnl_##NAME< std::complex<T>, std::complex<T> >,          \
00226     XprLiteral< std::complex<T> >,              \
00227     MatrixConstReference< std::complex<T>, Rows, Cols>          \
00228   >,                      \
00229   Rows, Cols                    \
00230 >                     \
00231 operator OP (const std::complex<T>& lhs,            \
00232        const Matrix< std::complex<T>, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00233 
00234 TVMET_DECLARE_MACRO(add, +)
00235 TVMET_DECLARE_MACRO(sub, -)
00236 TVMET_DECLARE_MACRO(mul, *)
00237 TVMET_DECLARE_MACRO(div, /)
00238 
00239 #undef TVMET_DECLARE_MACRO
00240 
00241 #endif // defined(TVMET_HAVE_COMPLEX)
00242 
00243 
00244 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00245  * matrix specific operator*() = prod() operations
00246  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00247 
00248 
00249 template<class T1, std::size_t Rows1, std::size_t Cols1,
00250    class T2, std::size_t Cols2>
00251 XprMatrix<
00252   XprMMProduct<
00253     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00254     MatrixConstReference<T2, Cols1, Cols2>, Cols2
00255   >,
00256   Rows1, Cols2
00257 >
00258 operator*(const Matrix<T1, Rows1, Cols1>& lhs,
00259     const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00260 
00261 
00262 template<class E1, std::size_t Rows1, std::size_t Cols1,
00263    class T2, std::size_t Cols2>
00264 XprMatrix<
00265   XprMMProduct<
00266     XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
00267     MatrixConstReference<T2, Cols1, Cols2>, Cols2
00268   >,
00269   Rows1, Cols2
00270 >
00271 operator*(const XprMatrix<E1, Rows1, Cols1>& lhs,
00272     const Matrix<T2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00273 
00274 
00275 template<class T1, std::size_t Rows1, std::size_t Cols1,
00276    class E2, std::size_t Cols2>
00277 XprMatrix<
00278   XprMMProduct<
00279     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00280     XprMatrix<E2, Cols1, Cols2>, Cols2
00281   >,
00282   Rows1, Cols2
00283 >
00284 operator*(const Matrix<T1, Rows1, Cols1>& lhs,
00285     const XprMatrix<E2, Cols1, Cols2>& rhs) TVMET_CXX_ALWAYS_INLINE;
00286 
00287 
00288 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00289  * matrix-vector specific prod( ... ) operators
00290  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00291 
00292 
00293 template<class T1, std::size_t Rows, std::size_t Cols, class T2>
00294 XprVector<
00295   XprMVProduct<
00296     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00297     VectorConstReference<T2, Cols>
00298   >,
00299   Rows
00300 >
00301 operator*(const Matrix<T1, Rows, Cols>& lhs,
00302     const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00303 
00304 
00305 template<class T1, class E2, std::size_t Rows, std::size_t Cols>
00306 XprVector<
00307   XprMVProduct<
00308     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00309     XprVector<E2, Cols>
00310   >,
00311   Rows
00312 >
00313 operator*(const Matrix<T1, Rows, Cols>& lhs,
00314     const XprVector<E2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00315 
00316 
00317 template<class E1, class T2, std::size_t Rows, std::size_t Cols>
00318 XprVector<
00319   XprMVProduct<
00320     XprMatrix<E1, Rows, Cols>, Rows, Cols,
00321     VectorConstReference<T2, Cols>
00322   >,
00323   Rows
00324 >
00325 operator*(const XprMatrix<E1, Rows, Cols>& lhs,
00326     const Vector<T2, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00327 
00328 
00329 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00330  * Matrix integer and compare operators
00331  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00332 
00333 
00334 /*
00335  * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00336  * operator(XprMatrix<E>, Matrix<T, Rows, Cols>)
00337  * operator(Matrix<T, Rows, Cols>, XprMatrix<E>)
00338  * Note: operations are per se element wise
00339  */
00340 #define TVMET_DECLARE_MACRO(NAME, OP)           \
00341 template<class T1, std::size_t Rows, std::size_t Cols,        \
00342    class T2>                \
00343 XprMatrix<                  \
00344   XprBinOp<                 \
00345     Fcnl_##NAME<T1, T2>,              \
00346     MatrixConstReference<T1, Rows, Cols>,         \
00347     MatrixConstReference<T2, Rows, Cols>          \
00348   >,                    \
00349   Rows, Cols                  \
00350 >                   \
00351 operator OP (const Matrix<T1, Rows, Cols>& lhs,         \
00352        const Matrix<T2, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;  \
00353                     \
00354 template<class E,               \
00355    class T, std::size_t Rows, std::size_t Cols>       \
00356 XprMatrix<                  \
00357   XprBinOp<                 \
00358     Fcnl_##NAME<typename E::value_type, T>,         \
00359     XprMatrix<E, Rows, Cols>,             \
00360     MatrixConstReference<T, Rows, Cols>           \
00361   >,                    \
00362   Rows, Cols                  \
00363 >                   \
00364 operator OP (const XprMatrix<E, Rows, Cols>& lhs,         \
00365        const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;   \
00366                     \
00367 template<class T, std::size_t Rows, std::size_t Cols,       \
00368    class E>               \
00369 XprMatrix<                  \
00370   XprBinOp<                 \
00371     Fcnl_##NAME<typename E::value_type, T>,         \
00372     MatrixConstReference<T, Rows, Cols>,          \
00373     XprMatrix<E, Rows, Cols>              \
00374   >,                    \
00375   Rows, Cols                  \
00376 >                   \
00377 operator OP (const Matrix<T, Rows, Cols>& lhs,          \
00378        const XprMatrix<E, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00379 
00380 // integer operators only, e.g used on double you wil get an error
00381 namespace element_wise {
00382   TVMET_DECLARE_MACRO(mod, %)
00383   TVMET_DECLARE_MACRO(bitxor, ^)
00384   TVMET_DECLARE_MACRO(bitand, &)
00385   TVMET_DECLARE_MACRO(bitor, |)
00386   TVMET_DECLARE_MACRO(shl, <<)
00387   TVMET_DECLARE_MACRO(shr, >>)
00388 }
00389 
00390 // necessary operators for eval functions
00391 TVMET_DECLARE_MACRO(greater, >)
00392 TVMET_DECLARE_MACRO(less, <)
00393 TVMET_DECLARE_MACRO(greater_eq, >=)
00394 TVMET_DECLARE_MACRO(less_eq, <=)
00395 TVMET_DECLARE_MACRO(eq, ==)
00396 TVMET_DECLARE_MACRO(not_eq, !=)
00397 TVMET_DECLARE_MACRO(and, &&)
00398 TVMET_DECLARE_MACRO(or, ||)
00399 
00400 #undef TVMET_DECLARE_MACRO
00401 
00402 
00403 #if defined(TVMET_HAVE_COMPLEX)
00404 /*
00405  * operator(Matrix<T, Rows, Cols>, complex<T>)
00406  * operator(complex<T>, Matrix<T, Rows, Cols>)
00407  * Note: - per se element wise
00408  *       - bit ops on complex<int> doesn't make sense, stay away
00409  * \todo type promotion
00410  */
00411 #define TVMET_DECLARE_MACRO(NAME, OP)             \
00412 template<class T, std::size_t Rows, std::size_t Cols>         \
00413 XprMatrix<                    \
00414   XprBinOp<                   \
00415     Fcnl_##NAME< std::complex<T>, std::complex<T> >,          \
00416     MatrixConstReference< std::complex<T>, Rows, Cols>,         \
00417     XprLiteral<std::complex<T> >              \
00418   >,                      \
00419   Rows, Cols                    \
00420 >                     \
00421 operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs,       \
00422        const std::complex<T>& rhs) TVMET_CXX_ALWAYS_INLINE;     \
00423                       \
00424 template<class T, std::size_t Rows, std::size_t Cols>         \
00425 XprMatrix<                    \
00426   XprBinOp<                   \
00427     Fcnl_##NAME< std::complex<T>, std::complex<T> >,          \
00428     XprLiteral< std::complex<T> >,              \
00429     MatrixConstReference< std::complex<T>, Rows, Cols>          \
00430   >,                      \
00431   Rows, Cols                    \
00432 >                     \
00433 operator OP (const std::complex<T>& lhs,            \
00434        const Matrix< std::complex<T>, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00435 
00436 // necessary operators for eval functions
00437 TVMET_DECLARE_MACRO(greater, >)
00438 TVMET_DECLARE_MACRO(less, <)
00439 TVMET_DECLARE_MACRO(greater_eq, >=)
00440 TVMET_DECLARE_MACRO(less_eq, <=)
00441 TVMET_DECLARE_MACRO(eq, ==)
00442 TVMET_DECLARE_MACRO(not_eq, !=)
00443 TVMET_DECLARE_MACRO(and, &&)
00444 TVMET_DECLARE_MACRO(or, ||)
00445 
00446 #undef TVMET_DECLARE_MACRO
00447 
00448 #endif // defined(TVMET_HAVE_COMPLEX)
00449 
00450 
00451 /*
00452  * operator(Matrix<T, Rows, Cols>, POD)
00453  * operator(POD, Matrix<T, Rows, Cols>)
00454  * Note: operations are per se element wise
00455  */
00456 #define TVMET_DECLARE_MACRO(NAME, OP, TP)         \
00457 template<class T, std::size_t Rows, std::size_t Cols>       \
00458 XprMatrix<                  \
00459   XprBinOp<                 \
00460     Fcnl_##NAME<T, TP >,              \
00461     MatrixConstReference<T, Rows, Cols>,          \
00462     XprLiteral<TP >               \
00463   >,                    \
00464   Rows, Cols                  \
00465 >                   \
00466 operator OP (const Matrix<T, Rows, Cols>& lhs, TP rhs) TVMET_CXX_ALWAYS_INLINE; \
00467                     \
00468 template<class T, std::size_t Rows, std::size_t Cols>       \
00469 XprMatrix<                  \
00470   XprBinOp<                 \
00471     Fcnl_##NAME< TP, T>,              \
00472     XprLiteral< TP >,               \
00473     MatrixConstReference<T, Rows, Cols>           \
00474   >,                    \
00475   Rows, Cols                  \
00476 >                   \
00477 operator OP (TP lhs, const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00478 
00479 // integer operators only, e.g used on double you wil get an error
00480 namespace element_wise {
00481   TVMET_DECLARE_MACRO(mod, %, int)
00482   TVMET_DECLARE_MACRO(bitxor, ^, int)
00483   TVMET_DECLARE_MACRO(bitand, &, int)
00484   TVMET_DECLARE_MACRO(bitor, |, int)
00485   TVMET_DECLARE_MACRO(shl, <<, int)
00486   TVMET_DECLARE_MACRO(shr, >>, int)
00487 }
00488 
00489 // necessary operators for eval functions
00490 TVMET_DECLARE_MACRO(greater, >, int)
00491 TVMET_DECLARE_MACRO(less, <, int)
00492 TVMET_DECLARE_MACRO(greater_eq, >=, int)
00493 TVMET_DECLARE_MACRO(less_eq, <=, int)
00494 TVMET_DECLARE_MACRO(eq, ==, int)
00495 TVMET_DECLARE_MACRO(not_eq, !=, int)
00496 TVMET_DECLARE_MACRO(and, &&, int)
00497 TVMET_DECLARE_MACRO(or, ||, int)
00498 
00499 #if defined(TVMET_HAVE_LONG_LONG)
00500 // integer operators only
00501 namespace element_wise {
00502   TVMET_DECLARE_MACRO(mod, %, long long int)
00503   TVMET_DECLARE_MACRO(bitxor, ^, long long int)
00504   TVMET_DECLARE_MACRO(bitand, &, long long int)
00505   TVMET_DECLARE_MACRO(bitor, |, long long int)
00506   TVMET_DECLARE_MACRO(shl, <<, long long int)
00507   TVMET_DECLARE_MACRO(shr, >>, long long int)
00508 }
00509 
00510 // necessary operators for eval functions
00511 TVMET_DECLARE_MACRO(greater, >, long long int)
00512 TVMET_DECLARE_MACRO(less, <, long long int)
00513 TVMET_DECLARE_MACRO(greater_eq, >=, long long int)
00514 TVMET_DECLARE_MACRO(less_eq, <=, long long int)
00515 TVMET_DECLARE_MACRO(eq, ==, long long int)
00516 TVMET_DECLARE_MACRO(not_eq, !=, long long int)
00517 TVMET_DECLARE_MACRO(and, &&, long long int)
00518 TVMET_DECLARE_MACRO(or, ||, long long int)
00519 #endif // defined(TVMET_HAVE_LONG_LONG)
00520 
00521 // necessary operators for eval functions
00522 TVMET_DECLARE_MACRO(greater, >, float)
00523 TVMET_DECLARE_MACRO(less, <, float)
00524 TVMET_DECLARE_MACRO(greater_eq, >=, float)
00525 TVMET_DECLARE_MACRO(less_eq, <=, float)
00526 TVMET_DECLARE_MACRO(eq, ==, float)
00527 TVMET_DECLARE_MACRO(not_eq, !=, float)
00528 TVMET_DECLARE_MACRO(and, &&, float)
00529 TVMET_DECLARE_MACRO(or, ||, float)
00530 
00531 // necessary operators for eval functions
00532 TVMET_DECLARE_MACRO(greater, >, double)
00533 TVMET_DECLARE_MACRO(less, <, double)
00534 TVMET_DECLARE_MACRO(greater_eq, >=, double)
00535 TVMET_DECLARE_MACRO(less_eq, <=, double)
00536 TVMET_DECLARE_MACRO(eq, ==, double)
00537 TVMET_DECLARE_MACRO(not_eq, !=, double)
00538 TVMET_DECLARE_MACRO(and, &&, double)
00539 TVMET_DECLARE_MACRO(or, ||, double)
00540 
00541 #if defined(TVMET_HAVE_LONG_DOUBLE)
00542 // necessary operators for eval functions
00543 TVMET_DECLARE_MACRO(greater, >, long double)
00544 TVMET_DECLARE_MACRO(less, <, long double)
00545 TVMET_DECLARE_MACRO(greater_eq, >=, long double)
00546 TVMET_DECLARE_MACRO(less_eq, <=, long double)
00547 TVMET_DECLARE_MACRO(eq, ==, long double)
00548 TVMET_DECLARE_MACRO(not_eq, !=, long double)
00549 TVMET_DECLARE_MACRO(and, &&, long double)
00550 TVMET_DECLARE_MACRO(or, ||, long double)
00551 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00552 
00553 #undef TVMET_DECLARE_MACRO
00554 
00555 
00556 
00557 
00558 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00559  * global unary operators
00560  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00561 
00562 
00563 /*
00564  * unary_operator(Matrix<T, Rows, Cols>)
00565  * Note: per se element wise
00566  */
00567 #define TVMET_DECLARE_MACRO(NAME, OP)         \
00568 template <class T, std::size_t Rows, std::size_t Cols>      \
00569 XprMatrix<                \
00570   XprUnOp<                \
00571     Fcnl_##NAME<T>,             \
00572     MatrixConstReference<T, Rows, Cols>         \
00573   >,                  \
00574   Rows, Cols                \
00575 >                 \
00576 operator OP (const Matrix<T, Rows, Cols>& rhs) TVMET_CXX_ALWAYS_INLINE;
00577 
00578 TVMET_DECLARE_MACRO(not, !)
00579 TVMET_DECLARE_MACRO(compl, ~)
00580 TVMET_DECLARE_MACRO(neg, -)
00581 #undef TVMET_DECLARE_MACRO
00582 
00583 
00584 /*********************************************************
00585  * PART II: IMPLEMENTATION
00586  *********************************************************/
00587 
00588 
00594 template<class T, std::size_t Rows, std::size_t Cols>
00595 inline
00596 std::ostream& operator<<(std::ostream& os, const Matrix<T, Rows, Cols>& rhs) {
00597   return rhs.print_on(os);
00598 }
00599 
00600 
00601 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00602  * Member operators (arithmetic and bit ops)
00603  *++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00604 
00605 
00606 /*
00607  * update_operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00608  * update_operator(Matrix<T1, Rows, Cols>, XprMatrix<E, Rows, Cols> rhs)
00609  * Note: per se element wise
00610  * \todo: the operator*= can have element wise mul oder product, decide!
00611  */
00612 #define TVMET_IMPLEMENT_MACRO(NAME, OP)           \
00613 template<class T1, class T2, std::size_t Rows, std::size_t Cols>    \
00614 inline                    \
00615 Matrix<T1, Rows, Cols>&               \
00616 operator OP (Matrix<T1, Rows, Cols>& lhs, const Matrix<T2, Rows, Cols>& rhs) {  \
00617   return lhs.M_##NAME(rhs);             \
00618 }                   \
00619                     \
00620 template<class T, class E, std::size_t Rows,  std::size_t Cols>     \
00621 inline                    \
00622 Matrix<T, Rows, Cols>&                \
00623 operator OP (Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) { \
00624   return lhs.M_##NAME(rhs);             \
00625 }
00626 
00627 TVMET_IMPLEMENT_MACRO(add_eq, +=)   // per se element wise
00628 TVMET_IMPLEMENT_MACRO(sub_eq, -=)   // per se element wise
00629 namespace element_wise {
00630   TVMET_IMPLEMENT_MACRO(mul_eq, *=)   // see note
00631   TVMET_IMPLEMENT_MACRO(div_eq, /=)   // not defined for vectors
00632 }
00633 
00634 // integer operators only, e.g used on double you wil get an error
00635 namespace element_wise {
00636   TVMET_IMPLEMENT_MACRO(mod_eq, %=)
00637   TVMET_IMPLEMENT_MACRO(xor_eq, ^=)
00638   TVMET_IMPLEMENT_MACRO(and_eq, &=)
00639   TVMET_IMPLEMENT_MACRO(or_eq, |=)
00640   TVMET_IMPLEMENT_MACRO(shl_eq, <<=)
00641   TVMET_IMPLEMENT_MACRO(shr_eq, >>=)
00642 }
00643 
00644 #undef TVMET_IMPLEMENT_MACRO
00645 
00646 
00647 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00648  * Matrix arithmetic operators implemented by functions
00649  * add, sub, mul and div
00650  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00651 
00652 
00653 /*
00654  * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00655  * operator(XprMatrix<E, Rows, Cols>, Matrix<T, Rows, Cols>)
00656  * operator(Matrix<T, Rows, Cols>, XprMatrix<E, Rows, Cols>)
00657  * Note: per se element wise
00658  */
00659 #define TVMET_IMPLEMENT_MACRO(NAME, OP)                 \
00660 template<class T1, class T2, std::size_t Rows, std::size_t Cols>          \
00661 inline                          \
00662 XprMatrix<                        \
00663   XprBinOp<                       \
00664     Fcnl_##NAME<T1, T2>,                    \
00665     MatrixConstReference<T1, Rows, Cols>,               \
00666     MatrixConstReference<T2, Rows, Cols>                \
00667   >,                          \
00668   Rows, Cols                        \
00669 >                         \
00670 operator OP (const Matrix<T1, Rows, Cols>& lhs, const Matrix<T2, Rows, Cols>& rhs) {  \
00671   return NAME(lhs, rhs);                    \
00672 }                         \
00673                           \
00674 template<class E, class T, std::size_t Rows, std::size_t Cols>            \
00675 inline                          \
00676 XprMatrix<                        \
00677   XprBinOp<                       \
00678     Fcnl_##NAME<typename E::value_type, T>,               \
00679     XprMatrix<E, Rows, Cols>,                   \
00680     MatrixConstReference<T, Rows, Cols>                 \
00681   >,                          \
00682   Rows, Cols                        \
00683 >                         \
00684 operator OP (const XprMatrix<E, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs) { \
00685   return NAME(lhs, rhs);                    \
00686 }                         \
00687                           \
00688 template<class T, class E, std::size_t Rows, std::size_t Cols>            \
00689 inline                          \
00690 XprMatrix<                        \
00691   XprBinOp<                       \
00692     Fcnl_##NAME<typename E::value_type, T>,               \
00693     MatrixConstReference<T, Rows, Cols>,                \
00694     XprMatrix<E, Rows, Cols>                    \
00695   >,                          \
00696   Rows, Cols                        \
00697 >                         \
00698 operator OP (const Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) { \
00699   return NAME(lhs, rhs);                    \
00700 }
00701 
00702 TVMET_IMPLEMENT_MACRO(add, +)     // per se element wise
00703 TVMET_IMPLEMENT_MACRO(sub, -)     // per se element wise
00704 namespace element_wise {
00705   TVMET_IMPLEMENT_MACRO(mul, *)     // see as prod()
00706   TVMET_IMPLEMENT_MACRO(div, /)     // not defined for matrizes
00707 }
00708 #undef TVMET_IMPLEMENT_MACRO
00709 
00710 
00711 /*
00712  * operator(Matrix<T, Rows, Cols>, POD)
00713  * operator(POD, Matrix<T, Rows, Cols>)
00714  * Note: operations +,-,*,/ are per se element wise
00715  */
00716 #define TVMET_IMPLEMENT_MACRO(NAME, OP, POD)      \
00717 template<class T, std::size_t Rows, std::size_t Cols>   \
00718 inline                \
00719 XprMatrix<              \
00720   XprBinOp<             \
00721     Fcnl_##NAME<T, POD >,         \
00722     MatrixConstReference<T, Rows, Cols>,      \
00723     XprLiteral<POD >            \
00724   >,                \
00725   Rows, Cols              \
00726 >               \
00727 operator OP (const Matrix<T, Rows, Cols>& lhs, POD rhs) { \
00728   return NAME (lhs, rhs);         \
00729 }               \
00730                 \
00731 template<class T, std::size_t Rows, std::size_t Cols>   \
00732 inline                \
00733 XprMatrix<              \
00734   XprBinOp<             \
00735     Fcnl_##NAME< POD, T>,         \
00736     XprLiteral< POD >,            \
00737     MatrixConstReference<T, Rows, Cols>       \
00738   >,                \
00739   Rows, Cols              \
00740 >               \
00741 operator OP (POD lhs, const Matrix<T, Rows, Cols>& rhs) { \
00742   return NAME (lhs, rhs);         \
00743 }
00744 
00745 TVMET_IMPLEMENT_MACRO(add, +, int)
00746 TVMET_IMPLEMENT_MACRO(sub, -, int)
00747 TVMET_IMPLEMENT_MACRO(mul, *, int)
00748 TVMET_IMPLEMENT_MACRO(div, /, int)
00749 
00750 #if defined(TVMET_HAVE_LONG_LONG)
00751 TVMET_IMPLEMENT_MACRO(add, +, long long int)
00752 TVMET_IMPLEMENT_MACRO(sub, -, long long int)
00753 TVMET_IMPLEMENT_MACRO(mul, *, long long int)
00754 TVMET_IMPLEMENT_MACRO(div, /, long long int)
00755 #endif // defined(TVMET_HAVE_LONG_LONG)
00756 
00757 TVMET_IMPLEMENT_MACRO(add, +, float)
00758 TVMET_IMPLEMENT_MACRO(sub, -, float)
00759 TVMET_IMPLEMENT_MACRO(mul, *, float)
00760 TVMET_IMPLEMENT_MACRO(div, /, float)
00761 
00762 TVMET_IMPLEMENT_MACRO(add, +, double)
00763 TVMET_IMPLEMENT_MACRO(sub, -, double)
00764 TVMET_IMPLEMENT_MACRO(mul, *, double)
00765 TVMET_IMPLEMENT_MACRO(div, /, double)
00766 
00767 #if defined(TVMET_HAVE_LONG_DOUBLE)
00768 TVMET_IMPLEMENT_MACRO(add, +, long double)
00769 TVMET_IMPLEMENT_MACRO(sub, -, long double)
00770 TVMET_IMPLEMENT_MACRO(mul, *, long double)
00771 TVMET_IMPLEMENT_MACRO(div, /, long double)
00772 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
00773 
00774 #undef TVMET_IMPLEMENT_MACRO
00775 
00776 
00777 #if defined(TVMET_HAVE_COMPLEX)
00778 /*
00779  * operator(Matrix<T, Rows, Cols>, complex<T>)
00780  * operator(complex<T>, Matrix<T, Rows, Cols>)
00781  * Note: operations +,-,*,/ are per se element wise
00782  * \todo type promotion
00783  */
00784 #define TVMET_IMPLEMENT_MACRO(NAME, OP)       \
00785 template<class T, std::size_t Rows, std::size_t Cols>   \
00786 inline                \
00787 XprMatrix<              \
00788   XprBinOp<             \
00789     Fcnl_##NAME< std::complex<T>, std::complex<T> >,    \
00790     MatrixConstReference< std::complex<T>, Rows, Cols>,   \
00791     XprLiteral<std::complex<T> >        \
00792   >,                \
00793   Rows, Cols              \
00794 >               \
00795 operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs, \
00796        const std::complex<T>& rhs) {      \
00797   return NAME (lhs, rhs);         \
00798 }               \
00799                 \
00800 template<class T, std::size_t Rows, std::size_t Cols>   \
00801 inline                \
00802 XprMatrix<              \
00803   XprBinOp<             \
00804     Fcnl_##NAME< std::complex<T>, std::complex<T> >,    \
00805     XprLiteral< std::complex<T> >,        \
00806     MatrixConstReference< std::complex<T>, Rows, Cols>    \
00807   >,                \
00808   Rows, Cols              \
00809 >               \
00810 operator OP (const std::complex<T>& lhs,      \
00811        const Matrix< std::complex<T>, Rows, Cols>& rhs) { \
00812   return NAME (lhs, rhs);         \
00813 }
00814 
00815 TVMET_IMPLEMENT_MACRO(add, +)
00816 TVMET_IMPLEMENT_MACRO(sub, -)
00817 TVMET_IMPLEMENT_MACRO(mul, *)
00818 TVMET_IMPLEMENT_MACRO(div, /)
00819 
00820 #undef TVMET_IMPLEMENT_MACRO
00821 
00822 #endif // defined(TVMET_HAVE_COMPLEX)
00823 
00824 
00825 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00826  * matrix specific operator*() = prod() operations
00827  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00828 
00829 
00837 template<class T1, std::size_t Rows1, std::size_t Cols1,
00838    class T2, std::size_t Cols2>
00839 inline
00840 XprMatrix<
00841   XprMMProduct<
00842     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00843     MatrixConstReference<T2, Cols1, Cols2>, Cols2
00844   >,
00845   Rows1, Cols2
00846 >
00847 operator*(const Matrix<T1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
00848   return prod(lhs, rhs);
00849 }
00850 
00851 
00858 template<class E1, std::size_t Rows1, std::size_t Cols1,
00859    class T2, std::size_t Cols2>
00860 inline
00861 XprMatrix<
00862   XprMMProduct<
00863     XprMatrix<E1, Rows1, Cols1>, Rows1, Cols1,
00864     MatrixConstReference<T2, Cols1, Cols2>, Cols2
00865   >,
00866   Rows1, Cols2
00867 >
00868 operator*(const XprMatrix<E1, Rows1, Cols1>& lhs, const Matrix<T2, Cols1, Cols2>& rhs) {
00869   return prod(lhs, rhs);
00870 }
00871 
00872 
00879 template<class T1, std::size_t Rows1, std::size_t Cols1,
00880    class E2, std::size_t Cols2>
00881 inline
00882 XprMatrix<
00883   XprMMProduct<
00884     MatrixConstReference<T1, Rows1, Cols1>, Rows1, Cols1,
00885     XprMatrix<E2, Cols1, Cols2>, Cols2
00886   >,
00887   Rows1, Cols2
00888 >
00889 operator*(const Matrix<T1, Rows1, Cols1>& lhs, const XprMatrix<E2, Cols1, Cols2>& rhs) {
00890   return prod(lhs, rhs);
00891 }
00892 
00893 
00894 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00895  * matrix-vector specific prod( ... ) operators
00896  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00897 
00898 
00906 template<class T1, std::size_t Rows, std::size_t Cols, class T2>
00907 inline
00908 XprVector<
00909   XprMVProduct<
00910     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00911     VectorConstReference<T2, Cols>
00912   >,
00913   Rows
00914 >
00915 operator*(const Matrix<T1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
00916   return prod(lhs, rhs);
00917 }
00918 
00919 
00926 template<class T1, class E2, std::size_t Rows, std::size_t Cols>
00927 inline
00928 XprVector<
00929   XprMVProduct<
00930     MatrixConstReference<T1, Rows, Cols>, Rows, Cols,
00931     XprVector<E2, Cols>
00932   >,
00933   Rows
00934 >
00935 operator*(const Matrix<T1, Rows, Cols>& lhs, const XprVector<E2, Cols>& rhs) {
00936   return prod(lhs, rhs);
00937 }
00938 
00939 
00946 template<class E1, class T2, std::size_t Rows, std::size_t Cols>
00947 inline
00948 XprVector<
00949   XprMVProduct<
00950     XprMatrix<E1, Rows, Cols>, Rows, Cols,
00951     VectorConstReference<T2, Cols>
00952   >,
00953   Rows
00954 >
00955 operator*(const XprMatrix<E1, Rows, Cols>& lhs, const Vector<T2, Cols>& rhs) {
00956   return prod(lhs, rhs);
00957 }
00958 
00959 
00960 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00961  * Matrix integer and compare operators
00962  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
00963 
00964 
00965 /*
00966  * operator(Matrix<T1, Rows, Cols>, Matrix<T2, Rows, Cols>)
00967  * operator(XprMatrix<E>, Matrix<T, Rows, Cols>)
00968  * operator(Matrix<T, Rows, Cols>, XprMatrix<E>)
00969  * Note: operations are per se element wise
00970  */
00971 #define TVMET_IMPLEMENT_MACRO(NAME, OP)             \
00972 template<class T1, std::size_t Rows, std::size_t Cols,          \
00973    class T2>                  \
00974 inline                      \
00975 XprMatrix<                    \
00976   XprBinOp<                   \
00977     Fcnl_##NAME<T1, T2>,                \
00978     MatrixConstReference<T1, Rows, Cols>,           \
00979     MatrixConstReference<T2, Rows, Cols>            \
00980   >,                      \
00981   Rows, Cols                    \
00982 >                     \
00983 operator OP (const Matrix<T1, Rows, Cols>& lhs,           \
00984        const Matrix<T2, Rows, Cols>& rhs) {         \
00985   typedef XprBinOp <                  \
00986     Fcnl_##NAME<T1, T2>,                \
00987     MatrixConstReference<T1, Rows, Cols>,           \
00988     MatrixConstReference<T2, Rows, Cols>            \
00989   >             expr_type;      \
00990   return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs.const_ref(), rhs.const_ref())); \
00991 }                     \
00992                       \
00993 template<class E,                 \
00994    class T, std::size_t Rows, std::size_t Cols>         \
00995 inline                      \
00996 XprMatrix<                    \
00997   XprBinOp<                   \
00998     Fcnl_##NAME<typename E::value_type, T>,           \
00999     XprMatrix<E, Rows, Cols>,               \
01000     MatrixConstReference<T, Rows, Cols>             \
01001   >,                      \
01002   Rows, Cols                    \
01003 >                     \
01004 operator OP (const XprMatrix<E, Rows, Cols>& lhs, const Matrix<T, Rows, Cols>& rhs) { \
01005   typedef XprBinOp<                 \
01006     Fcnl_##NAME<typename E::value_type, T>,           \
01007     XprMatrix<E, Rows, Cols>,               \
01008     MatrixConstReference<T, Rows, Cols>             \
01009   >                expr_type;     \
01010   return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs, rhs.const_ref()));   \
01011 }                     \
01012                       \
01013 template<class T, std::size_t Rows, std::size_t Cols,         \
01014    class E>                 \
01015 inline                      \
01016 XprMatrix<                    \
01017   XprBinOp<                   \
01018     Fcnl_##NAME<typename E::value_type, T>,           \
01019     MatrixConstReference<T, Rows, Cols>,            \
01020     XprMatrix<E, Rows, Cols>                \
01021   >,                      \
01022   Rows, Cols                    \
01023 >                     \
01024 operator OP (const Matrix<T, Rows, Cols>& lhs, const XprMatrix<E, Rows, Cols>& rhs) { \
01025   typedef XprBinOp<                 \
01026     Fcnl_##NAME<T, typename E::value_type>,           \
01027     MatrixConstReference<T, Rows, Cols>,            \
01028     XprMatrix<E, Rows, Cols>                \
01029   >              expr_type;     \
01030   return XprMatrix<expr_type, Rows, Cols>(expr_type(lhs.const_ref(), rhs));   \
01031 }
01032 
01033 // integer operators only, e.g used on double you wil get an error
01034 namespace element_wise {
01035   TVMET_IMPLEMENT_MACRO(mod, %)
01036   TVMET_IMPLEMENT_MACRO(bitxor, ^)
01037   TVMET_IMPLEMENT_MACRO(bitand, &)
01038   TVMET_IMPLEMENT_MACRO(bitor, |)
01039   TVMET_IMPLEMENT_MACRO(shl, <<)
01040   TVMET_IMPLEMENT_MACRO(shr, >>)
01041 }
01042 
01043 // necessary operators for eval functions
01044 TVMET_IMPLEMENT_MACRO(greater, >)
01045 TVMET_IMPLEMENT_MACRO(less, <)
01046 TVMET_IMPLEMENT_MACRO(greater_eq, >=)
01047 TVMET_IMPLEMENT_MACRO(less_eq, <=)
01048 TVMET_IMPLEMENT_MACRO(eq, ==)
01049 TVMET_IMPLEMENT_MACRO(not_eq, !=)
01050 TVMET_IMPLEMENT_MACRO(and, &&)
01051 TVMET_IMPLEMENT_MACRO(or, ||)
01052 
01053 #undef TVMET_IMPLEMENT_MACRO
01054 
01055 
01056 #if defined(TVMET_HAVE_COMPLEX)
01057 /*
01058  * operator(Matrix<T, Rows, Cols>, complex<T>)
01059  * operator(complex<T>, Matrix<T, Rows, Cols>)
01060  * Note: - per se element wise
01061  *       - bit ops on complex<int> doesn't make sense, stay away
01062  * \todo type promotion
01063  */
01064 #define TVMET_IMPLEMENT_MACRO(NAME, OP)            \
01065 template<class T, std::size_t Rows, std::size_t Cols>        \
01066 inline                     \
01067 XprMatrix<                   \
01068   XprBinOp<                  \
01069     Fcnl_##NAME< std::complex<T>, std::complex<T> >,         \
01070     MatrixConstReference< std::complex<T>, Rows, Cols>,        \
01071     XprLiteral<std::complex<T> >             \
01072   >,                     \
01073   Rows, Cols                   \
01074 >                    \
01075 operator OP (const Matrix< std::complex<T>, Rows, Cols>& lhs,      \
01076        const std::complex<T>& rhs) {           \
01077   typedef XprBinOp<                \
01078     Fcnl_##NAME< std::complex<T>, std::complex<T> >,         \
01079     MatrixConstReference< std::complex<T>, Rows, Cols>,        \
01080     XprLiteral< std::complex<T> >            \
01081   >             expr_type;   \
01082   return XprMatrix<expr_type, Rows, Cols>(           \
01083     expr_type(lhs.const_ref(), XprLiteral< std::complex<T> >(rhs))); \
01084 }                    \
01085                      \
01086 template<class T, std::size_t Rows, std::size_t Cols>        \
01087 inline                     \
01088 XprMatrix<                   \
01089   XprBinOp<                  \
01090     Fcnl_##NAME< std::complex<T>, std::complex<T> >,         \
01091     XprLiteral< std::complex<T> >,             \
01092     MatrixConstReference< std::complex<T>, Rows, Cols>         \
01093   >,                     \
01094   Rows, Cols                   \
01095 >                    \
01096 operator OP (const std::complex<T>& lhs,           \
01097        const Matrix< std::complex<T>, Rows, Cols>& rhs) {      \
01098   typedef XprBinOp<                \
01099     Fcnl_##NAME< std::complex<T>, std::complex<T> >,         \
01100     XprLiteral< std::complex<T> >,             \
01101     MatrixConstReference<T, Rows, Cols>            \
01102   >             expr_type;   \
01103   return XprMatrix<expr_type, Rows, Cols>(           \
01104     expr_type(XprLiteral< std::complex<T> >(lhs), rhs.const_ref())); \
01105 }
01106 
01107 // necessary operators for eval functions
01108 TVMET_IMPLEMENT_MACRO(greater, >)
01109 TVMET_IMPLEMENT_MACRO(less, <)
01110 TVMET_IMPLEMENT_MACRO(greater_eq, >=)
01111 TVMET_IMPLEMENT_MACRO(less_eq, <=)
01112 TVMET_IMPLEMENT_MACRO(eq, ==)
01113 TVMET_IMPLEMENT_MACRO(not_eq, !=)
01114 TVMET_IMPLEMENT_MACRO(and, &&)
01115 TVMET_IMPLEMENT_MACRO(or, ||)
01116 
01117 #undef TVMET_IMPLEMENT_MACRO
01118 
01119 #endif // defined(TVMET_HAVE_COMPLEX)
01120 
01121 
01122 /*
01123  * operator(Matrix<T, Rows, Cols>, POD)
01124  * operator(POD, Matrix<T, Rows, Cols>)
01125  * Note: operations are per se element wise
01126  */
01127 #define TVMET_IMPLEMENT_MACRO(NAME, OP, TP)        \
01128 template<class T, std::size_t Rows, std::size_t Cols>      \
01129 inline                   \
01130 XprMatrix<                 \
01131   XprBinOp<                \
01132     Fcnl_##NAME<T, TP >,             \
01133     MatrixConstReference<T, Rows, Cols>,         \
01134     XprLiteral<TP >              \
01135   >,                   \
01136   Rows, Cols                 \
01137 >                  \
01138 operator OP (const Matrix<T, Rows, Cols>& lhs, TP rhs) {     \
01139   typedef XprBinOp<              \
01140     Fcnl_##NAME<T, TP >,             \
01141     MatrixConstReference<T, Rows, Cols>,         \
01142     XprLiteral< TP >               \
01143   >             expr_type; \
01144   return XprMatrix<expr_type, Rows, Cols>(         \
01145     expr_type(lhs.const_ref(), XprLiteral< TP >(rhs)));      \
01146 }                  \
01147                    \
01148 template<class T, std::size_t Rows, std::size_t Cols>      \
01149 inline                   \
01150 XprMatrix<                 \
01151   XprBinOp<                \
01152     Fcnl_##NAME< TP, T>,             \
01153     XprLiteral< TP >,              \
01154     MatrixConstReference<T, Rows, Cols>          \
01155   >,                   \
01156   Rows, Cols                 \
01157 >                  \
01158 operator OP (TP lhs, const Matrix<T, Rows, Cols>& rhs) {     \
01159   typedef XprBinOp<              \
01160     Fcnl_##NAME< TP, T>,             \
01161     XprLiteral< TP >,              \
01162     MatrixConstReference<T, Rows, Cols>          \
01163   >             expr_type; \
01164   return XprMatrix<expr_type, Rows, Cols>(         \
01165     expr_type(XprLiteral< TP >(lhs), rhs.const_ref()));      \
01166 }
01167 
01168 // integer operators only, e.g used on double you wil get an error
01169 namespace element_wise {
01170   TVMET_IMPLEMENT_MACRO(mod, %, int)
01171   TVMET_IMPLEMENT_MACRO(bitxor, ^, int)
01172   TVMET_IMPLEMENT_MACRO(bitand, &, int)
01173   TVMET_IMPLEMENT_MACRO(bitor, |, int)
01174   TVMET_IMPLEMENT_MACRO(shl, <<, int)
01175   TVMET_IMPLEMENT_MACRO(shr, >>, int)
01176 }
01177 
01178 // necessary operators for eval functions
01179 TVMET_IMPLEMENT_MACRO(greater, >, int)
01180 TVMET_IMPLEMENT_MACRO(less, <, int)
01181 TVMET_IMPLEMENT_MACRO(greater_eq, >=, int)
01182 TVMET_IMPLEMENT_MACRO(less_eq, <=, int)
01183 TVMET_IMPLEMENT_MACRO(eq, ==, int)
01184 TVMET_IMPLEMENT_MACRO(not_eq, !=, int)
01185 TVMET_IMPLEMENT_MACRO(and, &&, int)
01186 TVMET_IMPLEMENT_MACRO(or, ||, int)
01187 
01188 #if defined(TVMET_HAVE_LONG_LONG)
01189 // integer operators only
01190 namespace element_wise {
01191   TVMET_IMPLEMENT_MACRO(mod, %, long long int)
01192   TVMET_IMPLEMENT_MACRO(bitxor, ^, long long int)
01193   TVMET_IMPLEMENT_MACRO(bitand, &, long long int)
01194   TVMET_IMPLEMENT_MACRO(bitor, |, long long int)
01195   TVMET_IMPLEMENT_MACRO(shl, <<, long long int)
01196   TVMET_IMPLEMENT_MACRO(shr, >>, long long int)
01197 }
01198 
01199 // necessary operators for eval functions
01200 TVMET_IMPLEMENT_MACRO(greater, >, long long int)
01201 TVMET_IMPLEMENT_MACRO(less, <, long long int)
01202 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long long int)
01203 TVMET_IMPLEMENT_MACRO(less_eq, <=, long long int)
01204 TVMET_IMPLEMENT_MACRO(eq, ==, long long int)
01205 TVMET_IMPLEMENT_MACRO(not_eq, !=, long long int)
01206 TVMET_IMPLEMENT_MACRO(and, &&, long long int)
01207 TVMET_IMPLEMENT_MACRO(or, ||, long long int)
01208 #endif // defined(TVMET_HAVE_LONG_LONG)
01209 
01210 // necessary operators for eval functions
01211 TVMET_IMPLEMENT_MACRO(greater, >, float)
01212 TVMET_IMPLEMENT_MACRO(less, <, float)
01213 TVMET_IMPLEMENT_MACRO(greater_eq, >=, float)
01214 TVMET_IMPLEMENT_MACRO(less_eq, <=, float)
01215 TVMET_IMPLEMENT_MACRO(eq, ==, float)
01216 TVMET_IMPLEMENT_MACRO(not_eq, !=, float)
01217 TVMET_IMPLEMENT_MACRO(and, &&, float)
01218 TVMET_IMPLEMENT_MACRO(or, ||, float)
01219 
01220 // necessary operators for eval functions
01221 TVMET_IMPLEMENT_MACRO(greater, >, double)
01222 TVMET_IMPLEMENT_MACRO(less, <, double)
01223 TVMET_IMPLEMENT_MACRO(greater_eq, >=, double)
01224 TVMET_IMPLEMENT_MACRO(less_eq, <=, double)
01225 TVMET_IMPLEMENT_MACRO(eq, ==, double)
01226 TVMET_IMPLEMENT_MACRO(not_eq, !=, double)
01227 TVMET_IMPLEMENT_MACRO(and, &&, double)
01228 TVMET_IMPLEMENT_MACRO(or, ||, double)
01229 
01230 #if defined(TVMET_HAVE_LONG_DOUBLE)
01231 // necessary operators for eval functions
01232 TVMET_IMPLEMENT_MACRO(greater, >, long double)
01233 TVMET_IMPLEMENT_MACRO(less, <, long double)
01234 TVMET_IMPLEMENT_MACRO(greater_eq, >=, long double)
01235 TVMET_IMPLEMENT_MACRO(less_eq, <=, long double)
01236 TVMET_IMPLEMENT_MACRO(eq, ==, long double)
01237 TVMET_IMPLEMENT_MACRO(not_eq, !=, long double)
01238 TVMET_IMPLEMENT_MACRO(and, &&, long double)
01239 TVMET_IMPLEMENT_MACRO(or, ||, long double)
01240 #endif // defined(TVMET_HAVE_LONG_DOUBLE)
01241 
01242 #undef TVMET_IMPLEMENT_MACRO
01243 
01244 
01245 
01246 
01247 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
01248  * global unary operators
01249  *+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
01250 
01251 
01252 /*
01253  * unary_operator(Matrix<T, Rows, Cols>)
01254  * Note: per se element wise
01255  */
01256 #define TVMET_IMPLEMENT_MACRO(NAME, OP)              \
01257 template <class T, std::size_t Rows, std::size_t Cols>           \
01258 inline                       \
01259 XprMatrix<                     \
01260   XprUnOp<                     \
01261     Fcnl_##NAME<T>,                  \
01262     MatrixConstReference<T, Rows, Cols>              \
01263   >,                       \
01264   Rows, Cols                     \
01265 >                      \
01266 operator OP (const Matrix<T, Rows, Cols>& rhs) {           \
01267   typedef XprUnOp<                   \
01268     Fcnl_##NAME<T>,                  \
01269     MatrixConstReference<T, Rows, Cols>              \
01270   >                expr_type;    \
01271   return XprMatrix<expr_type, Rows, Cols>(expr_type(rhs.const_ref())); \
01272 }
01273 
01274 TVMET_IMPLEMENT_MACRO(not, !)
01275 TVMET_IMPLEMENT_MACRO(compl, ~)
01276 TVMET_IMPLEMENT_MACRO(neg, -)
01277 #undef TVMET_IMPLEMENT_MACRO
01278 
01279 
01280 } // namespace tvmet
01281 
01282 #endif // TVMET_MATRIX_OPERATORS_H
01283 
01284 // Local Variables:
01285 // mode:C++
01286 // tab-width:8
01287 // End:

Author: