Abstract non Polymorphyc Matrix:
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines
Matrix_BASE.h
Go to the documentation of this file.
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