external.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
00007 
00008  *-----------------------------------------------------------------------*/
00013 #ifndef external_matrix_h
00014 #define external_matrix_h
00015 
00016 #include <cml/core/external_2D.h>
00017 #include <cml/matrix/matrix_expr.h>
00018 #include <cml/matrix/class_ops.h>
00019 #include <cml/matrix/matrix_unroller.h>
00020 #include <cml/matrix/dynamic.h>
00021 
00022 namespace cml {
00023 
00025 template<typename Element, int Rows, int Cols,
00026     typename BasisOrient, typename Layout>
00027 class matrix<Element,external<Rows,Cols>,BasisOrient,Layout>
00028 : public external_2D<Element,Rows,Cols,Layout>
00029 {
00030   public:
00031 
00032     /* Shorthand for the generator: */
00033     typedef external<Rows,Cols> generator_type;
00034 
00035     /* Shorthand for the array type: */
00036     typedef external_2D<Element,Rows,Cols,Layout> array_type;
00037 
00038     /* Shorthand for the type of this matrix: */
00039     typedef matrix<Element,generator_type,BasisOrient,Layout> matrix_type;
00040 
00041     /* For integration into the expression template code: */
00042     typedef matrix_type expr_type;
00043 
00044     /* For integration into the expression template code: */
00045     typedef matrix<Element,fixed<Rows,Cols>,BasisOrient,Layout> temporary_type;
00046     /* Note: this ensures that an external matrix is copied into the proper
00047      * temporary; external<> temporaries are not allowed.
00048      */
00049 
00050     /* Standard: */
00051     typedef typename array_type::value_type value_type;
00052     typedef typename array_type::reference reference;
00053     typedef typename array_type::const_reference const_reference;
00054 
00055     typedef matrix_type& expr_reference;
00056     typedef const matrix_type& expr_const_reference;
00057 
00058     /* For matching by basis: */
00059     typedef BasisOrient basis_orient;
00060 
00061     /* For matching by memory layout: */
00062     typedef typename array_type::layout layout;
00063 
00064     /* For matching by storage type if necessary: */
00065     typedef typename array_type::memory_tag memory_tag;
00066 
00067     /* For matching by size type if necessary: */
00068     typedef typename array_type::size_tag size_tag;
00069 
00070     /* For matching by resizability: */
00071     typedef typename array_type::resizing_tag resizing_tag;
00072 
00073     /* For matching by result-type: */
00074     typedef cml::et::matrix_result_tag result_tag;
00075 
00076     /* For matching by assignability: */
00077     typedef cml::et::assignable_tag assignable_tag;
00078 
00079     /* To simplify the matrix transpose operator: */
00080     typedef matrix<
00081         Element,
00082         typename array_type::transposed_type::generator_type,
00083         BasisOrient,
00084         Layout
00085     > transposed_type;
00086 
00087     /* To simplify the matrix row and column operators: */
00088     typedef vector<
00089         Element,
00090         typename array_type::row_array_type::generator_type
00091     > row_vector_type;
00092 
00093     typedef vector<
00094         Element,
00095         typename array_type::col_array_type::generator_type
00096     > col_vector_type;
00097 
00098 
00099   public:
00100 
00102     matrix_type& zero() {
00103         typedef cml::et::OpAssign<Element,Element> OpT;
00104         cml::et::UnrollAssignment<OpT>(*this,Element(0));
00105         return *this;
00106     }
00107 
00113     matrix_type& identity() {
00114         for(size_t i = 0; i < this->rows(); ++ i) {
00115             for(size_t j = 0; j < this->cols(); ++ j) {
00116                 (*this)(i,j) = value_type((i == j)?1:0);
00117             }
00118         }
00119         return *this;
00120     }
00121 
00127     matrix_type& transpose() {
00128         /* transpose() returns a temporary: */
00129         *this = transpose(*this);
00130         return *this;
00131     }
00132 
00138     matrix_type& inverse() {
00139         /* inverse() returns a temporary: */
00140         *this = cml::inverse(*this);
00141         return *this;
00142     }
00143 
00144     /* NOTE: minimize() and maximize() no longer supported (Jesse) */
00145 
00146     #if 0
00147 
00148     template<typename E, class AT, typename L>
00149     void minimize(const matrix<E,AT,basis_orient,L>& v) {
00150       /* XXX This should probably use ScalarPromote: */
00151       for (size_t i = 0; i < this->rows(); ++i) {
00152         for (size_t j = 0; j < this->cols(); ++j) {
00153           (*this)(i,j) = std::min((*this)(i,j),v(i,j));
00154         }
00155       }
00156     }
00157 
00159     template<typename E, class AT, typename L>
00160     void maximize(const matrix<E,AT,basis_orient,L>& v) {
00161       /* XXX This should probably use ScalarPromote: */
00162       for (size_t i = 0; i < this->rows(); ++i) {
00163         for (size_t j = 0; j < this->cols(); ++j) {
00164           (*this)(i,j) = std::max((*this)(i,j),v(i,j));
00165         }
00166       }
00167     }
00168     #endif
00169 
00170     /* Set each element to a random number in the range [min,max] */
00171     void random(ELEMENT_ARG_TYPE min, ELEMENT_ARG_TYPE max) {
00172       for(size_t i = 0; i < this->rows(); ++i) {
00173         for(size_t j = 0; j < this->cols(); ++j) {
00174           (*this)(i,j) = random_real(min,max);
00175         }
00176       }
00177     }
00178 
00179 
00180   public:
00181 
00192     explicit matrix(value_type ptr[Rows][Cols]) : array_type(ptr) {}
00193 
00204     explicit matrix(value_type* ptr) : array_type(ptr) {}
00205 
00206 
00207   public:
00208 
00210     matrix_size size() const {
00211         return matrix_size(this->rows(),this->cols());
00212     }
00213 
00215     value_type basis_element(size_t i, size_t j) const {
00216         return basis_element(i,j,basis_orient());
00217     }
00218 
00220     void set_basis_element(size_t i, size_t j, ELEMENT_ARG_TYPE s) {
00221         set_basis_element(i,j,s,basis_orient());
00222     }
00223 
00225     void set_row(size_t i, const row_vector_type& row) {
00226       for(size_t j = 0; j < this->cols(); ++ j) (*this)(i,j) = row[j];
00227     }
00228 
00230     void set_col(size_t j, const col_vector_type& col) {
00231       for(size_t i = 0; i < this->rows(); ++ i) (*this)(i,j) = col[i];
00232     }
00233 
00234 
00235   public:
00236 
00237     CML_ASSIGN_MAT_22
00238     CML_ASSIGN_MAT_33
00239     CML_ASSIGN_MAT_44
00240 
00241     /* Define class operators for external matrices. Note: external matrices
00242      * cannot be copy-constructed, but they can be assigned to:
00243      */
00244     CML_MAT_ASSIGN_FROM_MATTYPE
00245 
00246     CML_MAT_ASSIGN_FROM_MAT(=, et::OpAssign)
00247     CML_MAT_ASSIGN_FROM_MAT(+=, et::OpAddAssign)
00248     CML_MAT_ASSIGN_FROM_MAT(-=, et::OpSubAssign)
00249 
00250     CML_MAT_ASSIGN_FROM_MATXPR(=, et::OpAssign)
00251     CML_MAT_ASSIGN_FROM_MATXPR(+=, et::OpAddAssign)
00252     CML_MAT_ASSIGN_FROM_MATXPR(-=, et::OpSubAssign)
00253 
00254     CML_MAT_ASSIGN_FROM_SCALAR(*=, et::OpMulAssign)
00255     CML_MAT_ASSIGN_FROM_SCALAR(/=, et::OpDivAssign)
00256 
00257     CML_ACCUMULATED_MATRIX_MULT(const matrix_type&)
00258 
00259     template<typename E, class AT, typename BO, typename L>
00260         CML_ACCUMULATED_MATRIX_MULT(const TEMPLATED_MATRIX_MACRO&)
00261 
00262     template<class XprT>
00263         CML_ACCUMULATED_MATRIX_MULT(MATXPR_ARG_TYPE)
00264 
00265 
00266   protected:
00267 
00268     value_type basis_element(size_t i, size_t j, row_basis) const {
00269         return (*this)(i,j);
00270     }
00271 
00272     value_type basis_element(size_t i, size_t j, col_basis) const {
00273         return (*this)(j,i);
00274     }
00275 
00276     void set_basis_element(size_t i, size_t j, ELEMENT_ARG_TYPE s, row_basis) {
00277         (*this)(i,j) = s;
00278     }
00279 
00280     void set_basis_element(size_t i, size_t j, ELEMENT_ARG_TYPE s, col_basis) {
00281         (*this)(j,i) = s;
00282     }
00283 
00284 
00285   public:
00286 
00287     /* Braces should only be used for testing: */
00288 #if defined(CML_ENABLE_MATRIX_BRACES)
00289     CML_MATRIX_BRACE_OPERATORS
00290 #endif
00291 };
00292 
00294 template<typename Element, typename BasisOrient, typename Layout>
00295 class matrix<Element,external<-1,-1>,BasisOrient,Layout>
00296 : public external_2D<Element,-1,-1,Layout>
00297 {
00298   public:
00299 
00300     /* Shorthand for the generator: */
00301     typedef external<> generator_type;
00302 
00303     /* Shorthand for the array type: */
00304     typedef external_2D<Element,-1,-1,Layout> array_type;
00305 
00306     /* Shorthand for the type of this matrix: */
00307     typedef matrix<Element,generator_type,BasisOrient,Layout> matrix_type;
00308 
00309     /* For integration into the expression template code: */
00310     typedef matrix_type expr_type;
00311 
00312     /* For integration into the expression template code: */
00313     typedef matrix<Element,dynamic<>,BasisOrient,Layout> temporary_type;
00314     /* Note: this ensures that an external matrix is copied into the proper
00315      * temporary; external<> temporaries are not allowed.
00316      */
00317 
00318     /* Standard: */
00319     typedef typename array_type::value_type value_type;
00320     typedef typename array_type::reference reference;
00321     typedef typename array_type::const_reference const_reference;
00322 
00323     typedef matrix_type& expr_reference;
00324     typedef const matrix_type& expr_const_reference;
00325 
00326     /* For matching by basis: */
00327     typedef BasisOrient basis_orient;
00328 
00329     /* For matching by memory layout: */
00330     typedef typename array_type::layout layout;
00331 
00332     /* For matching by storage type if necessary: */
00333     typedef typename array_type::memory_tag memory_tag;
00334 
00335     /* For matching by size type if necessary: */
00336     typedef typename array_type::size_tag size_tag;
00337 
00338     /* For matching by resizability: */
00339     typedef typename array_type::resizing_tag resizing_tag;
00340 
00341     /* For matching by result-type: */
00342     typedef cml::et::matrix_result_tag result_tag;
00343 
00344     /* For matching by assignability: */
00345     typedef cml::et::assignable_tag assignable_tag;
00346 
00347     /* To simplify the matrix transpose operator: */
00348     typedef matrix<
00349         Element,
00350         typename array_type::transposed_type::generator_type,
00351         BasisOrient,
00352         Layout
00353     > transposed_type;
00354 
00355     /* To simplify the matrix row and column operators: */
00356     typedef vector<
00357         Element,
00358         typename array_type::row_array_type::generator_type
00359     > row_vector_type;
00360 
00361     typedef vector<
00362         Element,
00363         typename array_type::col_array_type::generator_type
00364     > col_vector_type;
00365 
00366 
00367   public:
00368 
00370     matrix_type& zero() {
00371         typedef cml::et::OpAssign<Element,Element> OpT;
00372         cml::et::UnrollAssignment<OpT>(*this,Element(0));
00373         return *this;
00374     }
00375 
00381     matrix_type& identity() {
00382         for(size_t i = 0; i < this->rows(); ++ i) {
00383             for(size_t j = 0; j < this->cols(); ++ j) {
00384                 (*this)(i,j) = value_type((i == j)?1:0);
00385             }
00386         }
00387         return *this;
00388     }
00389 
00395     matrix_type& transpose() {
00396         /* transpose() returns a temporary: */
00397         *this = cml::transpose(*this);
00398         return *this;
00399     }
00400 
00406     matrix_type& inverse() {
00407         /* inverse() returns a temporary: */
00408         *this = inverse(*this);
00409         return *this;
00410     }
00411 
00413     template<typename E, class AT, typename L>
00414     void minimize(const matrix<E,AT,basis_orient,L>& v) {
00415       /* XXX This should probably use ScalarPromote: */
00416       for (size_t i = 0; i < this->rows(); ++i) {
00417         for (size_t j = 0; j < this->cols(); ++j) {
00418           (*this)[i] = std::min((*this)(i,j),v(i,j));
00419         }
00420       }
00421     }
00422 
00424     template<typename E, class AT, class BO, typename L>
00425     void maximize(const matrix<E,AT,basis_orient,L>& v) {
00426       /* XXX This should probably use ScalarPromote: */
00427       for (size_t i = 0; i < this->rows(); ++i) {
00428         for (size_t j = 0; j < this->cols(); ++j) {
00429           (*this)[i] = std::max((*this)(i,j),v(i,j));
00430         }
00431       }
00432     }
00433 
00434     /* Set each element to a random number in the range [min,max] */
00435     void random(ELEMENT_ARG_TYPE min, ELEMENT_ARG_TYPE max) {
00436       for(size_t i = 0; i < this->rows(); ++i) {
00437         for(size_t j = 0; j < this->cols(); ++j) {
00438           (*this)(i,j) = cml::random_real(min,max);
00439         }
00440       }
00441     }
00442 
00443 
00444   public:
00445 
00458     explicit matrix(value_type* const ptr, size_t rows, size_t cols)
00459         : array_type(ptr,rows,cols) {}
00460 
00461 
00462   public:
00463 
00465     matrix_size size() const {
00466         return matrix_size(this->rows(),this->cols());
00467     }
00468 
00470     value_type basis_element(size_t i, size_t j) const {
00471         return basis_element(i,j,basis_orient());
00472     }
00473 
00475     void set_basis_element(size_t i, size_t j, ELEMENT_ARG_TYPE s) {
00476         set_basis_element(i,j,s,basis_orient());
00477     }
00478 
00479 
00480   public:
00481 
00482     CML_ASSIGN_MAT_22
00483     CML_ASSIGN_MAT_33
00484     CML_ASSIGN_MAT_44
00485 
00486     /* Define class operators for external matrices. Note: external matrices
00487      * cannot be copy-constructed, but they can be assigned to:
00488      */
00489     CML_MAT_ASSIGN_FROM_MATTYPE
00490 
00491     CML_MAT_ASSIGN_FROM_MAT(=, et::OpAssign)
00492     CML_MAT_ASSIGN_FROM_MAT(+=, et::OpAddAssign)
00493     CML_MAT_ASSIGN_FROM_MAT(-=, et::OpSubAssign)
00494 
00495     CML_MAT_ASSIGN_FROM_MATXPR(=, et::OpAssign)
00496     CML_MAT_ASSIGN_FROM_MATXPR(+=, et::OpAddAssign)
00497     CML_MAT_ASSIGN_FROM_MATXPR(-=, et::OpSubAssign)
00498 
00499     CML_MAT_ASSIGN_FROM_SCALAR(*=, et::OpMulAssign)
00500     CML_MAT_ASSIGN_FROM_SCALAR(/=, et::OpDivAssign)
00501 
00502     CML_ACCUMULATED_MATRIX_MULT(const matrix_type&)
00503 
00504     template<typename E, class AT, typename BO, typename L>
00505         CML_ACCUMULATED_MATRIX_MULT(const TEMPLATED_MATRIX_MACRO&)
00506 
00507     template<class XprT>
00508         CML_ACCUMULATED_MATRIX_MULT(MATXPR_ARG_TYPE)
00509 
00510 
00511   protected:
00512 
00513     value_type basis_element(size_t i, size_t j, row_basis) const {
00514         return (*this)(i,j);
00515     }
00516 
00517     value_type basis_element(size_t i, size_t j, col_basis) const {
00518         return (*this)(j,i);
00519     }
00520 
00521     void set_basis_element(size_t i, size_t j, ELEMENT_ARG_TYPE s, row_basis) {
00522         (*this)(i,j) = s;
00523     }
00524 
00525     void set_basis_element(size_t i, size_t j, ELEMENT_ARG_TYPE s, col_basis) {
00526         (*this)(j,i) = s;
00527     }
00528 
00529 
00530   public:
00531 
00532     /* Braces should only be used for testing: */
00533 #if defined(CML_ENABLE_MATRIX_BRACES)
00534     CML_MATRIX_BRACE_OPERATORS
00535 #endif
00536 };
00537 
00538 } // namespace cml
00539 
00540 #endif
00541 
00542 // -------------------------------------------------------------------------
00543 // vim:ft=cpp

Generated on Sat Jul 18 19:35:20 2009 for CML 1.0 by  doxygen 1.5.9