La Matriz Abstracta no Polimorfica:
|
00001 // Matrix_BASE.h Copyright (C) 2009 adolfo@di-mare.com 00002 00003 #ifdef Spanish_dox 00004 /** \file Matrix_BASE.h 00005 \brief Declaraciones y definiciones para la 00006 clase abstracta no polimórfica \c Matrix_BASE<>. 00007 \author Adolfo Di Mare <adolfo@di-mare.com> 00008 \date 2009 00009 - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04 00010 */ 00011 #endif 00012 #ifdef English_dox 00013 /** \file Matrix_BASE.h 00014 \brief Declarations and definitiones for the 00015 non polymorphic abstract class \c Matrix_BASE<>. 00016 \author Adolfo Di Mare <adolfo@di-mare.com> 00017 \date 2009 00018 - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04 00019 */ 00020 #endif 00021 00022 #ifndef Matrix_BASE_h 00023 #define Matrix_BASE_h // Evita la inclusión múltiple 00024 00025 /// Escuela de Ciencias de la Computación e Informática. 00026 /// \see http://www.ecci.ucr.ac.cr 00027 namespace ECCI {} 00028 00029 /// C++ STL 00030 /// \namespace std 00031 // Está acá para que Doxygen lo documente 00032 00033 #include <stdexcept> // throw out_of_range; 00034 00035 #ifdef Spanish_dox 00036 /// Matriz chirrisquitica de adolfo@di-mare.com 00037 #endif 00038 #ifdef English_dox 00039 /// Chirrisquitica matrix by adolfo@di-mare.com 00040 #endif 00041 namespace Mx { 00042 00043 // Clase base de la matriz chirrisquitica. 00044 template <class E> 00045 class Matrix_BASE { 00046 public: 00047 typedef E value_type; // nombres STL 00048 typedef value_type& reference; 00049 typedef const value_type& const_reference; 00050 protected: // "protected" evita que existan objetos de tipo Matrix_BASE<> 00051 Matrix_BASE(unsigned m = 1, unsigned n = 1) { } 00052 Matrix_BASE(const Matrix_BASE& M); 00053 Matrix_BASE(const E& val); 00054 ~Matrix_BASE() { } ///< Destructor. 00055 protected: 00056 unsigned rows() const; 00057 unsigned cols() const; 00058 unsigned size() const; 00059 unsigned count() const; 00060 unsigned capacity() const; 00061 protected: 00062 Matrix_BASE& operator= (const Matrix_BASE& M); 00063 Matrix_BASE& copy( const Matrix_BASE& M ); 00064 Matrix_BASE& move( Matrix_BASE& M ); 00065 Matrix_BASE& swap( Matrix_BASE& M ); 00066 void clear(); 00067 public: 00068 bool same( const Matrix_BASE & M ) const { return this == &M; } 00069 protected: 00070 bool equals( const Matrix_BASE & M ) const; ///< ¿¿¿ A == B ??? 00071 protected: 00072 E& operator()(unsigned i, unsigned j); 00073 const E& operator()(unsigned i, unsigned j) const; 00074 E& at(unsigned i, unsigned j); // throw (out_of_range); 00075 const E& at(unsigned i, unsigned j) const; 00076 00077 void reShape(unsigned m, unsigned n); 00078 void reSize( unsigned m, unsigned n); 00079 void transpose(); 00080 00081 void setDefault(const E& same); 00082 const E& getDefault(); 00083 public: 00084 template <class MAT> friend bool check_ok_Matrix( const MAT& M ); 00085 template <class T> friend class test_Matrix; ///< BUnit Test. 00086 00087 public: // operadores con una parámetro marcado como Matrix_BASE<> 00088 template <class MAT> friend MAT 00089 operator+ (const Matrix_BASE<typename MAT::value_type>& A, const MAT& B); 00090 template <class MAT> friend MAT 00091 operator- (const Matrix_BASE<typename MAT::value_type>& A, const MAT& B); 00092 template <class MAT> friend MAT 00093 operator* (const Matrix_BASE<typename MAT::value_type>& A, const MAT& B); 00094 template <class MAT> friend bool 00095 operator== ( const Matrix_BASE<typename MAT::value_type>& A, const MAT& B ); 00096 template <class MAT> friend bool 00097 operator!= ( const Matrix_BASE<typename MAT::value_type>& A, const MAT &B ); 00098 00099 public: // funciones amigas para implementar métodos abstractos no polimórficos 00100 template <class MAT> friend bool 00101 check_ok_Matrix( const MAT& M ); 00102 template <class MAT> friend unsigned 00103 count_Matrix( const MAT& M ); 00104 template <class MAT> friend void 00105 clear_Matrix( MAT& M ); 00106 template <class MAT> friend bool 00107 equals_Matrix( const MAT& A, const MAT& B ); 00108 template <class MAT> friend void 00109 add_Matrix( MAT& Res, const MAT& M ); 00110 template <class MAT> friend void 00111 substract_Matrix( MAT& Res, const MAT& M ); 00112 template <class MAT> friend void 00113 multiply_Matrix( MAT& Res, const MAT& A, const MAT& B ); 00114 template <class MAT> friend typename MAT::reference 00115 at_Matrix( MAT& M, unsigned i, unsigned j ); 00116 template <class MAT> friend typename MAT::const_reference 00117 at_Matrix( const MAT& M, unsigned i, unsigned j ); 00118 00119 }; // Matrix_BASE 00120 00121 #ifdef Spanish_dox 00122 /** Verificación genérica de la invariante de la clase \c check_ok(). 00123 - http://www.di-mare.com/adolfo/binder/c03.htm#k1-Rep 00124 00125 \remark 00126 Libera al programador de implementar el método \c Ok() 00127 - http://www.di-mare.com/adolfo/binder/c04.htm#sc11 00128 */ 00129 #endif 00130 #ifdef English_dox 00131 /** Generic verification of the class invariant \c check_ok(). 00132 - http://www.di-mare.com/adolfo/binder/c03.htm#k1-Rep 00133 00134 \remark 00135 Releaves the programner form implementing method \c Ok() 00136 - http://www.di-mare.com/adolfo/binder/c04.htm#sc11 00137 */ 00138 #endif 00139 template <class MAT> 00140 bool check_ok_Matrix( const MAT& M ) { 00141 if ( ! (&M != 0 ) ) { 00142 return false; /// - check_ok(): <code> &M != 0 </code>. 00143 } 00144 if ( M.rows() == 0 || M.cols() == 0 ) { // si alguno es cero... 00145 if ( M.rows() != 0 || M.cols() != 0 ) { // ... los 2 deben serlo 00146 return false; /// - check_ok(): <code>(M.rows() == 0) <==> (M.cols() == 0)</code> 00147 } 00148 } 00149 00150 for (unsigned i=0; i<M.rows(); ++i) { 00151 for (unsigned j=0; j<M.cols(); ++j) { 00152 if ( ! check_ok( M(i,j) ) ) { 00153 return false; /// - check_ok(): <code>check_ok( M(i,j) )</code> 00154 } 00155 } 00156 } 00157 return true; 00158 } 00159 00160 #ifdef Spanish_dox 00161 /// Implementación por defecto para \c Matrix_BASE<E>::count() 00162 #endif 00163 #ifdef English_dox 00164 /// Default implementation for \c Matrix_BASE<E>::count() 00165 #endif 00166 template <class MAT> unsigned 00167 count_Matrix( const MAT& M ) { 00168 return M.size(); 00169 } 00170 00171 #ifdef Spanish_dox 00172 /// Implementación por defecto para \c Matrix_BASE<E>::clear() 00173 #endif 00174 #ifdef English_dox 00175 /// Default implementation for \c Matrix_BASE<E>::clear() 00176 #endif 00177 template <class MAT> 00178 void clear_Matrix( MAT& M ) { 00179 M.reSize(1,1); 00180 M(0,0) = typename MAT::value_type(); 00181 } 00182 00183 #ifdef Spanish_dox 00184 /// Implementación por defecto para \c Matrix_BASE<E>::operator==() 00185 #endif 00186 #ifdef English_dox 00187 /// Default implementation for \c Matrix_BASE<E>::operator==() 00188 #endif 00189 template <class MAT> 00190 bool equals_Matrix( const MAT& A, const MAT& B ) { 00191 if ( A.rows() != B.rows() || A.cols() != B.cols() ) { 00192 return false; 00193 } 00194 00195 for (unsigned i=0; i<A.rows(); ++i) { 00196 for (unsigned j=0; j<A.cols(); ++j) { 00197 if ( A(i,j) != B(i,j) ) { 00198 return false; 00199 } 00200 } 00201 } 00202 return true; 00203 } 00204 00205 #include <cassert> 00206 00207 #ifdef Spanish_dox 00208 /** Implementación por defecto para \c operator+( Matrix_BASE<E>&, Matrix_BASE<E> ) 00209 00210 \pre 00211 - \c "*this" y \c "M" deben tener las mismas dimensiones. 00212 - <code> rows() == M.rows() && cols() == M.cols() </code>. 00213 00214 \remarks 00215 - Esta es la implementación para 00216 <code> Matrix_BASE<E> operator+( Matrix_BASE<E>&, Matrix_BASE<E> ) </code>. 00217 - El compilador tiene problemas en compilar un función amiga (<em>"friend"</em>) 00218 definida con plantillas si esa función amiga no está definida (implementada) 00219 dentro de la declaración de la clase. Para solventar esta deficiencia existe 00220 esta función que realiza el trabajo, aunque es poco cómodo de usar. 00221 */ 00222 #endif 00223 #ifdef English_dox 00224 /** Default implementation for \c operator+( Matrix_BASE<E>&, Matrix_BASE<E> ) 00225 00226 \pre 00227 - \c "*this" y \c "M" must have the same dimentions. 00228 - <code> rows() == M.rows() && cols() == M.cols() </code>. 00229 00230 \remarks 00231 - This is the implementation for 00232 <code> Matrix_BASE<E> operator+( Matrix_BASE<E>&, Matrix_BASE<E> ) </code>. 00233 - The compiler has problems compiling a friend function (<em>"friend"</em>) 00234 defined with templates if that friend function is not defined (implemented) 00235 within the class declaration. To overcome this deficiency there exists this 00236 function that does the work, although it is not convenient to use. 00237 */ 00238 #endif 00239 template <class MAT> void add_Matrix( MAT& Res, const MAT& M ) { 00240 // verifica que las dos matrices sean del mismo tamaño 00241 assert( "Matrix_BASE<E>::add()" && ( Res.rows() == M.rows() ) ); 00242 assert( "Matrix_BASE<E>::add()" && ( Res.cols() == M.cols() ) ); 00243 00244 // Como las matrices son del mismo tamaño basta sumarlas entrada por entrada. 00245 for ( unsigned i=0 ; i<Res.rows() ; ++i ) { 00246 for ( unsigned j=0 ; j<Res.cols() ; ++j ) { 00247 Res.operator()(i,j) += M(i,j); 00248 } 00249 } 00250 return; 00251 } 00252 00253 #ifdef Spanish_dox 00254 /// Implementación por defecto para \c operator-( Matrix_BASE<E>&, Matrix_BASE<E> ) 00255 #endif 00256 #ifdef English_dox 00257 /// Default implementation for \c operator-( Matrix_BASE<E>&, Matrix_BASE<E> ) 00258 #endif 00259 template <class MAT> void substract_Matrix( MAT& Res, const MAT& M ) { 00260 // verifica que las dos matrices sean del mismo tamaño 00261 assert( "Matrix_BASE<E>::substract()" && ( Res.rows() == M.rows() ) ); 00262 assert( "Matrix_BASE<E>::substract()" && ( Res.cols() == M.cols() ) ); 00263 00264 // Como las matrices son del mismo tamaño basta restarlas entrada por entrada. 00265 for ( unsigned i=0 ; i<Res.rows() ; ++i ) { 00266 for ( unsigned j=0 ; j<Res.cols() ; ++j ) { 00267 Res.operator()(i,j) -= M(i,j); 00268 } 00269 } 00270 return; 00271 } 00272 00273 #ifdef Spanish_dox 00274 /** Calcula la multiplicación <code> A * B </code> y almacena el resultado en \c "Res". 00275 - Las dimensiones de \c "*this" se ajustan de manera que: 00276 <br> <code> Res.rows() == A.rows() && Res.cols() == B.cols()</code> 00277 - Esta es la implementación de <code> Matrix_BASE<E> operator*() </code>. 00278 00279 \pre 00280 - \c "A" y \c "B" deben tener dimensiones compatibles. 00281 - <code> A.cols() == B.rows() </code>. 00282 - La multiplicación se hace [Fila x Columna], lo que implica que la cantidad 00283 de valores en la filas de \c "A" debe ser igual a la cantidad de columnas de \c "B". 00284 00285 \par Complejidad: 00286 O( <code> A.cols() * B.cols() * A.cols() </code> ) 00287 */ 00288 #endif 00289 #ifdef English_dox 00290 /** Calculates the multiplication <code> A * B </code> and stores the result in \c "Res". 00291 - The dimensions for \c "*this" get adjusted such that: 00292 <br> <code> Res.rows() == A.rows() && Res.cols() == B.cols()</code> 00293 - This is the implementation for <code> Matrix_BASE<E> operator*() </code>. 00294 00295 \pre 00296 - \c "A" y \c "B" must have compatible dimensions. 00297 - <code> A.cols() == B.rows() </code>. 00298 - The multiplication is carried out [Row x Column], which means that the 00299 number of valies in the rows for \c "A" must be equal to the number of 00300 columns of \c "B". 00301 00302 \par Complexity: 00303 O( <code> A.cols() * B.cols() * A.cols() </code> ) 00304 */ 00305 #endif 00306 template <class MAT> 00307 void multiply_Matrix( MAT& Res, const MAT& A, const MAT& B ) { 00308 // Verifica que las matrices se puedan multiplicar 00309 assert( "Matrix_List<E>::multiply()" && (A.cols() == B.rows()) ); 00310 00311 Res.reSize( A.rows(), B.cols() ); 00312 typename MAT::value_type sum; 00313 for (unsigned i=0; i<Res.rows(); i++) { 00314 for (unsigned j=0; j<Res.cols(); j++) { 00315 sum = typename MAT::value_type(); // sum = E(0); 00316 for (unsigned k=0; k<A.cols(); k++) { 00317 sum = sum + A(i,k) * B(k,j); 00318 } 00319 // this->(i,j) = sum; // produce un error de compilación 00320 // this->operator()(i,j) = sum; // SI funciona 00321 // (*this)(i,j) = sum; // SI funciona 00322 Res(i,j) = sum; // SI funciona 00323 } 00324 } 00325 return; 00326 } 00327 00328 #ifdef Spanish_dox 00329 /// Implementación por defecto para \c Matrix_BASE<E>::at() 00330 #endif 00331 #ifdef English_dox 00332 /// Default implementation for \c Matrix_BASE<E>::at() 00333 #endif 00334 template <class MAT> 00335 typename MAT::reference at_Matrix( MAT& M, unsigned i, unsigned j ) { 00336 if ( i>=M.rows() ) { 00337 throw std::out_of_range( "Mx::Matrix_BASE<E>::at(i,j) [ i>=M.rows() ]" ); 00338 } 00339 else if ( j>=M.cols() ) { 00340 throw std::out_of_range( "Mx::Matrix_BASE<E>::at(i,j) [ j>=M.cols() ]" ); 00341 } 00342 else { 00343 return M(i,j); 00344 } 00345 } 00346 00347 #ifdef Spanish_dox 00348 /// Implementación por defecto para \c Matrix_BASE<E>::at() const 00349 #endif 00350 #ifdef English_dox 00351 /// Default implementation for \c Matrix_BASE<E>::at() const 00352 #endif 00353 template <class MAT> 00354 typename MAT::const_reference at_Matrix( const MAT& M, unsigned i, unsigned j ) { 00355 if ( i>=M.rows() ) { 00356 throw std::out_of_range( "Mx::Matrix_BASE<E>::at(i,j) const [ i>=M.rows() ]" ); 00357 } 00358 else if ( j>=M.cols() ) { 00359 throw std::out_of_range( "Mx::Matrix_BASE<E>::at(i,j) const [ j>=M.cols() ]" ); 00360 } 00361 else { 00362 return M(i,j); 00363 } 00364 } 00365 00366 /// \c A+B 00367 template <class MAT> 00368 inline MAT operator+ (const Matrix_BASE<typename MAT::value_type>& A, const MAT& B) { 00369 MAT Res = *( // MAT Res = *( (MAT*)(&A) ); 00370 reinterpret_cast<MAT*>( 00371 const_cast< 00372 Matrix_BASE<typename MAT::value_type>* >(&A) ) ); 00373 add_Matrix(Res,B); // esta es la implementación por defecto 00374 return Res; 00375 /* NOTA 00376 La manera simple de implementar este operador es declararlo así: 00377 template <class MAT> MAT operator+( const MAT& , const MAT&); 00378 Desafortunadamente, cuando se usa la matriz junto con otras 00379 clases, como por ejemplo std::string<> u otra similar, esta 00380 definición produce un conflicto de ambigüedad, pues esta misma 00381 definición también calza como operador para la clase string<>. 00382 00383 La forma de evitar este choque es declarar "A", el primer 00384 parámetro, de un tipo marcado por la matriz. Por eso "A" está 00385 declarado así: 00386 const Matrix_BASE<typename MAT::value_type>& A; 00387 00388 Con esta modificación, ya la plantilla de matrices no calza con 00389 parámetros de otro tipo y así queda eliminado el conflicto con 00390 la clase string<>. 00391 00392 Sería más cómodo usar una plantilla de plantillas, como ésta: 00393 template <class MAT, class E> 00394 MAT<E> operator+( const MAT<E>& , const MAT<E>&); 00395 Este tipo de uso de plantillas es prohibo porque produce todavía 00396 más conflictos. Por eso, no queda más que forzar el uso del 00397 lenguaje usando punteros y cambios de tipo para lograr que esta 00398 versión del operator+() se use sólo para objetos derivados de la 00399 clase Matrix_BASE<>. 00400 00401 El truco para transformar una referencia a la clase base en una 00402 referencia a la clase derivada requiere del uso de punteros. Para 00403 transformar el parámetro "A" en un objeto del tipo del segundo 00404 parámetro "B" se usa esta secuencia de transformaciones de tipos 00405 y punteros: 00406 00407 1) Hace falta usar (&A) para trabajar con punteros en lugar de 00408 del objeto de tipo Matrix_BASE<>. 00409 2) Hace falta usar const_cast<> porque A es un parámetro "const" 00410 y la variable "Res" no está definida como objeto "const". 00411 3) Hace falta usar reinterpret_cast<> para cambiar el tipo de la 00412 clase base a la clase derivada en un contexto es que la clase 00413 derivada no es una clase que contiene métodos virtuales. 00414 Matrix_BASE<> no tiene VMT y, en consecuencia, usar 00415 dynamic_cast<> es un error de compilación. 00416 4) Hace falta usar punteros porque un objeto de tipo Matrix_BASE<> 00417 tiene un tamaño diferente al de cualquier de las clases 00418 derivadas de Matrix_BASE<>por lo que usar reinterpret_cast<> en 00419 esos objetos produce un error de compilación. 00420 5) Como todos los punteros tienen el mismo tamaño, sí es posible 00421 usar reinterpret_cast<> para transformar un puntero a la clase 00422 Matrix_BASE<> en un puntero a la clase derivada. 00423 6) Como lo que se hace al principio es tomar la dirección "&A", 00424 a fin de cuentas ese puntero debe ser dereferenciado usando el 00425 operador "*" para que lo utilice el constructor de copia. 00426 00427 Es mucho más sencillo usar el código sin "XXX_cast<>": 00428 MAT Res = *( (MAT*)(&A) ); 00429 En las implementaciones de las otras operaciones esta es la 00430 notación que se usa, porque es más corta, pese a que es mucho 00431 más peligrosa de usar en un contexto general. 00432 00433 Una vez que la matriz "Res" queda inicializada con una copia 00434 del valor del primer parámetro "A", se usa la plantilla genérica 00435 add_Matrix() para dejar en "Res" el resultado de la suma. Como 00436 el tipo de "Res" es el adecuado (no es Matrix_BASE<>), al retornar 00437 el compilador invoca el contructor de copia de la clase derivada. 00438 00439 Esta función está declarada "inline" porque el cambio de tipos no 00440 ocupa tiempo de ejecución y porque así el compilador tiene la 00441 oportunidad de suprimir la segunda invocación al constructor de 00442 copia (que sería invocada para retornar "Res"). 00443 */ 00444 } 00445 00446 /// \c A-B 00447 template <class MAT> 00448 inline MAT operator- (const Matrix_BASE<typename MAT::value_type>& A, const MAT& B) { 00449 MAT Res = *( (MAT*)(&A) ); substract_Matrix(Res,B); return Res; 00450 } 00451 00452 /// \c Res=A*B 00453 template <class MAT> 00454 inline MAT operator* (const Matrix_BASE<typename MAT::value_type>& A, const MAT& B) { 00455 MAT Res; multiply_Matrix(Res, *( (MAT*)(&A) ), B); return Res; 00456 } 00457 00458 /// ¿¿¿ (A == B) ??? 00459 template <class MAT> 00460 inline bool operator== ( const Matrix_BASE<typename MAT::value_type>& A, const MAT& B ) { 00461 return equals_Matrix( (*(MAT*)(&A)),B ); 00462 } 00463 00464 /// ¿¿¿ (A != B) ??? 00465 template <class MAT> 00466 inline bool operator!= ( const Matrix_BASE<typename MAT::value_type>& A, const MAT &B ) { 00467 return !(A==B); 00468 } 00469 00470 00471 /***********\ 00472 ** ** 00473 ** DOXYGEN ** 00474 ** ** 00475 \***********/ 00476 00477 00478 #ifdef Spanish_dox 00479 /// \c "Doxygen: Documentación en español" 00480 #define Spanish_dox "Doxygen: Documentación en español" 00481 /// \def Matrix_BASE_h 00482 /// \brief Usada para evitar la inclusión múltiple. 00483 #endif 00484 #ifdef English_dox 00485 /// "Doxygen: English documentation" 00486 #define English_dox "Doxygen: English documentation" 00487 /// \def Matrix_BASE_h 00488 /// \brief Used to avoid multiple inclusion. 00489 #endif 00490 00491 #ifdef Spanish_dox 00492 /** \class Matrix_BASE 00493 \brief Esta es la plantilla base para las implementacion de la clase matriz chirrisquitica. 00494 - La matriz tiene dimensiones \c rows() x \c cols(). 00495 - Se le puede cambia su dimensión dinámicamente con el método \c reSize(). 00496 - La clase \c E debe incluir un neutro para la adición, cuyo valor debe poderse 00497 obtener invocando \c Sparse_Matrix<E>::value_type(). 00498 - Las operaciones aritméticas "+" "-" "*" deben estar definidas para 00499 \c Matrix_BASE<E>::value_type y debe existir \c Matrix_BASE<E>::value_type(1). 00500 \see http://www.oonumerics.org/oon/ 00501 */ 00502 #endif 00503 #ifdef English_dox 00504 /** \class Matrix_BASE 00505 \brief This is the base template for the implementaciones of the chirrisquitica matrix. 00506 - The matrix has dimensions \c rows() x \c cols(). 00507 - Its dimensions can change dinamically using \c reSize(). 00508 - Call \c E must have a neutral for addition. Its value should be obtained 00509 invoking \c Sparse_Matrix<E>::value_type(). 00510 - The arithmetic operations "+" "-" "*" must be defined for 00511 \c Matrix_BASE<E>::value_type and \c Matrix_BASE<E>::value_type(1). 00512 \see http://www.oonumerics.org/oon/ 00513 */ 00514 #endif 00515 00516 #ifdef Spanish_dox 00517 /// \typedef Matrix_BASE<E>::value_type 00518 /// \brief Tipo del objeto almacenado, similar al nombre usado en STL 00519 00520 /// \typedef Matrix_BASE<E>::reference 00521 /// \brief Referencia al objeto almacenado, similar al nombre usado en STL 00522 00523 /// \typedef Matrix_BASE<E>::const_reference 00524 /// \brief Referencia constante al objeto almacenado, similar al nombre usado en STL 00525 #endif 00526 #ifdef English_dox 00527 /// \typedef Matrix_BASE<E>::value_type 00528 /// \brief Type of the stored object, similar to the name used in the STL 00529 00530 /// \typedef Matrix_BASE<E>::reference 00531 /// \brief Reference to the stored object, similar to the name used in the STL 00532 00533 /// \typedef Matrix_BASE<E>::const_reference 00534 /// \brief Reference [const] to the stored object, similar to the name used in the STL 00535 #endif 00536 00537 #ifdef Spanish_dox 00538 /** \fn Matrix_BASE<E>::Matrix_BASE(unsigned m, unsigned n); 00539 \brief Constructor de vector. 00540 - Obtiene suficiente memoria dinámica para almacenas los 00541 <code> n * m </code> valores de la matriz. 00542 - Si \c "value_type" es uno de los tipos escalares básicos, 00543 como lo son \c int o \c float, los valores almacenados 00544 en la matriz no son inicializados en cero. 00545 - Si \c "m" o \c "n" es cero, la matriz queda vacía. 00546 00547 \fn Matrix_BASE<E>::Matrix_BASE(const E& val); 00548 \brief Constructor escalar. 00549 - La matriz es escalar de dimensiones 1x1 y valor \c "V". 00550 00551 \fn Matrix_BASE<E>::Matrix_BASE( const Matrix_BASE& ); 00552 \brief Constructor de copia. 00553 */ 00554 #endif 00555 #ifdef English_dox 00556 /** \fn Matrix_BASE<E>::Matrix_BASE(unsigned m, unsigned n); 00557 \brief Vector constructor. 00558 - Allocates enough dynamic memory to store the <code> n * m </code> 00559 matrix values. 00560 - If \c "value_type" is one of the basic scalar types, as \c int 00561 or \c float, the stored values in the matrix will not be initialized 00562 to zero. 00563 - If \c "m" or \c "n" is zero, the matrix is empty. 00564 00565 \fn Matrix_BASE<E>::Matrix_BASE(const E& val); 00566 \brief Scalar constructor. 00567 - The matrix is scalar with dimension 1x1 and value \c "V". 00568 00569 \fn Matrix_BASE<E>::Matrix_BASE( const Matrix_BASE& ); 00570 \brief Copy constructor. 00571 */ 00572 #endif 00573 00574 #ifdef Spanish_dox 00575 /** 00576 \fn unsigned Matrix_BASE<E>::rows() const; 00577 \brief Cantidad de filas de la matriz. 00578 00579 \fn unsigned Matrix_BASE<E>::cols() const; 00580 \brief Cantidad de columnas de la matriz. 00581 00582 \fn unsigned Matrix_BASE<E>::size() const; 00583 \brief Cantidad de valores almacenados en la matriz. 00584 00585 \fn unsigned Matrix_BASE<E>::count() const; 00586 \brief Sinónimo de \c size(). 00587 00588 \fn unsigned Matrix_BASE<E>::capacity() const; 00589 \brief Cantidad máxima posible de valores diferentes que pueden ser almacenados en la matriz. 00590 */ 00591 #endif 00592 #ifdef English_dox 00593 /** 00594 \fn unsigned Matrix_BASE<E>::rows() const; 00595 \brief Number of rows in the matrix. 00596 00597 \fn unsigned Matrix_BASE<E>::cols() const; 00598 \brief Number of columns in the matrix. 00599 00600 \fn unsigned Matrix_BASE<E>::size() const; 00601 \brief Number of values stored in the matrix. 00602 00603 \fn unsigned Matrix_BASE<E>::count() const; 00604 \brief Sinonim of \c size(). 00605 00606 \fn unsigned Matrix_BASE<E>::capacity() const; 00607 \brief Maximum number of values that can be stored in the matrix. 00608 */ 00609 #endif 00610 00611 #ifdef Spanish_dox 00612 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::operator=(const Matrix_BASE &M); 00613 \brief Sinónimo de \c this->copy(M). 00614 \fn Matrix_BASE<E>& Matrix_BASE<E>::copy(const Matrix_BASE &M); 00615 \brief Copia desde \c "M". 00616 - Copia todo el valor de \c "M" sobre \c "*this" de forma que el nuevo valor de 00617 \c "*this" sea un duplicado exacto del valor de \c "M". 00618 - El valor anterior de \c "*this" se pierde. 00619 - El objeto \c "M" mantiene su valor. 00620 - Luego de la copia, cuando el valor de \c "M" cambia, el de \c "*this" no cambiará, 00621 y viceversa, pues la copia es una copia profunda; no es superficial. 00622 - Si \c "*this" es \c "M" su valor no cambia. 00623 - Después de esta operación siempre es verdadero que <code> *this == M </code>. 00624 00625 \returns \c "*this" 00626 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc05 00627 */ 00628 #endif 00629 #ifdef English_dox 00630 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::operator=(const Matrix_BASE &M); 00631 \brief Sinonim of \c this->copy(M). 00632 \fn Matrix_BASE<E>& Matrix_BASE<E>::copy(const Matrix_BASE &M); 00633 \brief Copies from \c "M". 00634 - Copies the whole value from \c "M" into \c "*this" in such a way that 00635 the new valuer for \c "*this" is an exact duplicate of the value in \c "M". 00636 - The previous value stored in \c "*this" is lost. 00637 - Object \c "M" maintains its value. 00638 - After the copy, when the value for \c "M" changes, the value for 00639 \c "*this" will not change, and viceversa, because the copy is a deep 00640 copy; it is not supperficial. 00641 - If \c "*this" is \c "M" its value will not change. 00642 - After this operation it is always true that <code> *this == M </code>. 00643 00644 \returns \c "*this" 00645 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc05 00646 */ 00647 #endif 00648 00649 #ifdef Spanish_dox 00650 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::move(Matrix_BASE &M); 00651 \brief Traslada el valor de \c "M" a \c "*this". 00652 - El valor anterior de \c "*this" se pierde 00653 - El nuevo valor de \c "*this" es el que \c "M" tuvo 00654 - \c "M" queda en el estado en que queda cualquier objeto 00655 cuando es inicializardo con el constructor de vector. 00656 - Si \c "*this" es \c "M" entonces su valor no cambia 00657 - En general, después de esta operación casi 00658 nunca ocurre que <code> (*this == M) </code> 00659 00660 \returns \c "*this" 00661 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc07 00662 */ 00663 #endif 00664 #ifdef English_dox 00665 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::move(Matrix_BASE &M); 00666 \brief Moves the value from \c "M" into \c "*this". 00667 - The previous value stored in \c "*this" is lost. 00668 - The new value for \c "*this" is what was stored in \c "M". 00669 - \c "M" remains in the state an object will have after being 00670 initialized by the vector contructor. 00671 - If \c "*this" is \c "M" its value will not change. 00672 - In general, after this operation, it will almost never ocurr 00673 that <code> (*this == M) </code>. 00674 00675 \returns \c "*this" 00676 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc07 00677 */ 00678 #endif 00679 00680 #ifdef Spanish_dox 00681 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::swap(Matrix_BASE &M); 00682 \brief Intercambia los valores de \c "*this" y \c "M". 00683 - En muchas ocasiones toma menos tiempo esta operación que 00684 \c copy() o \c move(). 00685 00686 \returns \c "*this" 00687 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc08 00688 */ 00689 #endif 00690 #ifdef English_dox 00691 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::swap(Matrix_BASE &M); 00692 \brief Interchanges the values of \c "*this" and \c "M". 00693 - In many ocations this operation takes less time than 00694 \c copy() or \c move(). 00695 00696 \returns \c "*this" 00697 \see http://www.di-mare.com/adolfo/binder/c04.htm#sc08 00698 */ 00699 #endif 00700 00701 #ifdef Spanish_dox 00702 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::clear(); 00703 \brief Deja el valor de \c "*this" en el valor en que lo 00704 inicializa el constructor de vector. 00705 */ 00706 #endif 00707 #ifdef English_dox 00708 /** \fn Matrix_BASE<E>& Matrix_BASE<E>::clear(); 00709 \brief Leaves \c "*this" with the value the 00710 vector constructor initializes it to. 00711 */ 00712 #endif 00713 00714 #ifdef Spanish_dox 00715 /// \fn bool Matrix_BASE<E>::same( const Matrix_BASE & M ) const; 00716 /// \brief Retorna \c true si \c "M" comparte su valor con \c "*this". 00717 #endif 00718 #ifdef English_dox 00719 /// \fn bool Matrix_BASE<E>::same( const Matrix_BASE & M ) const; 00720 /// \brief Returns \c true if \c "M" shares its value with \c "*this". 00721 #endif 00722 00723 #ifdef Spanish_dox 00724 /** \fn reference Matrix_BASE<E>::operator()(unsigned,unsigned); 00725 \brief Retorna una referencia al elemento \c [i][j] de la matriz. 00726 - \c M(i,j) significa lo que en arreglos es \c M[i][j]. 00727 - Esta referencia permite cambiar el valor almacenado. 00728 - <code>M(i,j) = val; // M(i,j) es un "lvalue" (modificable)</code> 00729 */ 00730 /** \fn const_reference Matrix_BASE<E>::operator()(unsigned,unsigned) const; 00731 \brief Retorna una referencia constante al elemento 00732 \c [i][j] de la matriz <strong>[CONST]</strong>. 00733 - \c M(i,j) significa lo que en arreglos es \c M[i][j]. 00734 - Esta referencia solo permite leer el valor almacenado. 00735 - <code>val = M(i,j); // M(i,j) es un "rvalue" (const)</code> 00736 */ 00737 /** \fn reference Matrix_BASE<E>::at(unsigned, unsigned); 00738 \brief Retorna una referencia al elemento \c [i][j] de la matriz. 00739 - Vefica que en la matriz exista el valor de índices \c [i][j]. 00740 - Si \c [i][j] está fuera de rango levanta una excepción de tipo 00741 \c std::out_of_range. 00742 - Esta referencia permite cambiar el valor almacenado. 00743 - <code>M.at(i,j) = val; // M.at(i,j) es un "lvalue" (modificable)</code> 00744 */ 00745 /** \fn const_reference Matrix_BASE<E>::at(unsigned, unsigned) const; 00746 \brief Retorna una referencia constante al elemento \c [i][j] 00747 de la matriz <strong>[CONST]</strong>. 00748 - Vefica que en la matriz exista el valor de índices \c [i][j]. 00749 - Si \c [i][j] está fuera de rango levanta una excepción de tipo 00750 \c std::out_of_range. 00751 - Esta referencia solo permite leer el valor almacenado. 00752 - <code>val = M.at(i,j); // M.at(i,j) es un "rvalue" (const)</code> 00753 */ 00754 #endif 00755 #ifdef English_dox 00756 /** \fn reference Matrix_BASE<E>::operator()(unsigned, unsigned); 00757 \brief Returns a reference to element \c [i][j] in the matrix. 00758 - \c M(i,j) means what in arrays is \c M[i][j]. 00759 - This reference allows modifying the stored value. 00760 - <code>M(i,j) = val; // M(i,j) is un "lvalue" (mutable)</code> 00761 */ 00762 /** \fn const_reference Matrix_BASE<E>::operator()(unsigned, unsigned) const; 00763 \brief Returns a const reference to element \c [i][j] in the matrix 00764 <strong>[CONST]</strong>. 00765 - \c M(i,j) means what in arrays is \c M[i][j]. 00766 - This reference only allows reading the stored value. 00767 - <code>val = M(i,j); // M(i,j) is a "rvalue" (const)</code> 00768 */ 00769 /** \fn reference Matrix_BASE<E>::at(unsigned, unsigned); 00770 \brief Returns a reference to element \c [i][j] in the matrix. 00771 - Verifyes that a value with indexes \c [i][j] exists in the matrix. 00772 - If \c [i][j] is out of range throws exception \c std::out_of_range. 00773 - This reference allows modifying the stored value. 00774 - <code>M.at(i,j) = val; // M.at(i,j) is un "lvalue" (mutable)</code> 00775 */ 00776 /** \fn const_reference Matrix_BASE<E>::at(unsigned, unsigned) const; 00777 \brief Returns a const reference to element \c [i][j] in the matrix 00778 <strong>[CONST]</strong>. 00779 - Verifyes that a value with indexes \c [i][j] exists in the matrix. 00780 - If \c [i][j] is out of range throws exception \c std::out_of_range. 00781 - This reference only allows reading the stored value. 00782 - <code>val = M.at(i,j); // M.at(i,j) is a "rvalue" (const)</code> 00783 */ 00784 #endif 00785 00786 #ifdef Spanish_dox 00787 /** \fn void Matrix_BASE<E>::reSize(unsigned m, unsigned n); 00788 \brief Le cambia las dimensiones a la matriz. 00789 - Si <code> (m*n == 0) </code> deja la matriz vacía. 00790 00791 \fn void Matrix_BASE<E>::reShape(unsigned m, unsigned n); 00792 \brief Le ajusta las dimensiones a la matriz. 00793 - Trata de cambiar las dimensiones de la matriz conservando los 00794 valores almacenados actuales. De esta forma, una matriz 4x12 00795 puede ser transformada en 8x6 sin tener que adquirir nueva 00796 memoria dinámica, lo que hace que esta operación en algunas 00797 ocasiones sea más rápida que \c reSize(m,n). 00798 - En muchos casos no es posible reajustar las dimensiones de la 00799 matriz. 00800 00801 \fn void Matrix_BASE<E>::transpose(); 00802 \brief Transforma la matriz en su transpuesta. 00803 */ 00804 #endif 00805 #ifdef English_dox 00806 /** \fn void Matrix_BASE<E>::reSize(unsigned m, unsigned n); 00807 \brief Changes the dimensions for the matrix. 00808 - If <code> (m*n == 0) </code> the matrix becomes empty. 00809 00810 \fn void Matrix_BASE<E>::reShape(unsigned m, unsigned n); 00811 \brief Reshapes the dimensions for the matrix. 00812 - Tries to change the dimensions fot the matrix while preserving 00813 current stored values. In this way, a 4x12 matrix can be 00814 transformed into a 8x6 without having to acquire new dynamic 00815 memory, which sometimes makes this operation faster than 00816 \c Resize(m,n). 00817 - In many cases it is not possible to reshape the dimensions of the matrix. 00818 00819 \fn void Matrix_BASE<E>::transpose(); 00820 \brief Transforms the matrix into its transpose. 00821 */ 00822 #endif 00823 00824 #ifdef Spanish_dox 00825 /** 00826 \fn Matrix_BASE<E>::setDefault(const E& same); 00827 \brief Define cuál es el valor almacenado en la mayor parte de la matriz. 00828 - En muchos casos reorganiza al matriz de manera que ocupe menos 00829 espacio usando como valor comodín a \c same. 00830 - Si <code>same != getDefault()</code> la matriz queda reducida 00831 como si hubiera sido invocado \c clear(). 00832 \fn Matrix_BASE<E>::getDefault(); 00833 \brief Valor almacenado en la mayor parte de la matriz. 00834 */ 00835 #endif 00836 #ifdef English_dox 00837 /** 00838 \fn Matrix_BASE<E>::setDefault(const E& same); 00839 \brief Defines which is the most common value stored in the matrix. 00840 - Oftentimes this method will reorganizce the matrix in such a way 00841 that less space is needed using \c same as the most common value. 00842 - If <code>same != getDefault()</code> the matrix becomes empty as 00843 if \c clear() had been invoked for it. 00844 \fn Matrix_BASE<E>::getDefault(); 00845 \brief Gets the most common value stored in the matrix. 00846 */ 00847 #endif 00848 00849 #ifdef Spanish_dox 00850 #endif 00851 #ifdef English_dox 00852 #endif 00853 00854 } // namespace Mx 00855 00856 #endif // Matrix_BASE_h 00857 00858 // EOF: Matrix_BASE.h