Abstract non Polymorphyc Matrix:
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines
Matrix_Lib.h
Go to the documentation of this file.
00001 // Matrix_Lib.h Copyright (C) 2004  adolfo@di-mare.com
00002 
00003 #ifdef Spanish_dox
00004 /** \file  Matrix_Lib.h
00005     \brief Funciones para manipular \c Matrix_BASE<>.
00006     \author Adolfo Di Mare <adolfo@di-mare.com>
00007     \date   2004
00008     - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04
00009 */
00010 #endif
00011 #ifdef English_dox
00012 /** \file  Matrix_Lib.h
00013     \brief Functions to manipulate \c Matrix_BASE<>.
00014     \author Adolfo Di Mare <adolfo@di-mare.com>
00015     \date   2004
00016     - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04
00017 */
00018 #endif
00019 
00020 #ifndef   Matrix_Lib_h
00021 #define   Matrix_Lib_h   // Evita la inclusión múltiple
00022 
00023 namespace Mx {
00024 
00025 #ifdef Spanish_dox
00026 /// Retorna \c "true" si la matriz \c M[][] es una matriz cuadrada
00027 #endif
00028 #ifdef English_dox
00029 /// Returns \c "true" if matrix \c M[][] is square.
00030 #endif
00031 template <class MAT>
00032 bool isSquare( const MAT& M ) {
00033     return M.rows() == M.cols();
00034 }
00035 
00036 #ifdef Spanish_dox
00037 /// Retorna \c "true" si la matriz \c M[][] es una matriz diagonal.
00038 #endif
00039 #ifdef English_dox
00040 /// Returns \c "true" if matrix \c M[][] is diagonal.
00041 #endif
00042 template <class MAT>
00043 bool isDiagonal( const MAT& M ) {
00044     assert( "This code has not been tested" );
00045     if (M.rows() != M.cols()) {
00046       return false;
00047     }
00048     typename MAT::value_type ZERO = 0;
00049     for (unsigned i=1; i < M.rows(); i++) {
00050         for (unsigned j=0; j < i; j++) {
00051             if (M(i,j) !=  ZERO) {
00052                 return false;
00053             } else if (M(j,i) !=  ZERO) {
00054                 return false;
00055             }
00056         }
00057     }
00058     return true;
00059 }
00060 
00061 #ifdef Spanish_dox
00062 /// Retorna \c "true" si la matriz \c M[][] es escalar.
00063 #endif
00064 #ifdef English_dox
00065 /// Returns \c "true" if matrix \c M[][] is scalar.
00066 #endif
00067 template <class MAT>
00068 bool isScalar( const MAT& M ) {
00069     assert( "This code has not been tested" );
00070     if ( ! isDiagonal( M ) ) {
00071         return false;
00072     }
00073     typename MAT::value_type S = M(0,0);
00074     for (unsigned i=1; i < M.rows(); i++) {
00075         if (M(i,i) != S) {
00076             return false;
00077         }
00078     }
00079    return true;
00080 }
00081 
00082 #ifdef Spanish_dox
00083 /// Retorna \c "true" si la matriz \c M[][] es unitaria.
00084 #endif
00085 #ifdef English_dox
00086 /// Returns \c "true" if matrix \c M[][] is a unit matrix.
00087 #endif
00088 template <class MAT>
00089 inline bool isUnit( const MAT& M ) {
00090     assert( "This code has not been tested" );
00091     typename MAT::value_type ONE = 1;
00092     return ( ONE == M(0,0) ? isScalar( M ) : false );
00093 }
00094 
00095 #ifdef Spanish_dox
00096 /// Convierte a \c M[][] en una matriz identidad de tamaño \c n x \c n.
00097 #endif
00098 #ifdef English_dox
00099 /// Transforms \c M[][] into a identity matrix of size \c n x \c n.
00100 #endif
00101 template <class MAT>
00102 void setUnit( const MAT& M , unsigned n ) {
00103     assert( "This code has not been tested" );
00104     M.reSize(n,n);
00105 
00106     for (unsigned i=1; i < M.rows(); ++i) {
00107         for (unsigned j=0; j < i; ++j) {
00108             M(i,j) = M(j,i) = typename MAT::value_type();
00109         }
00110         M(i,i) = typename MAT::value_type(1);
00111     }
00112 }
00113 
00114 #ifdef Spanish_dox
00115 /// Retorna \c "true" si la matriz \c M[][] es nula.
00116 #endif
00117 #ifdef English_dox
00118 /// Returns \c "true" if matrix \c M[][] is null.
00119 #endif
00120 template <class MAT>
00121 bool isNull( const MAT& M ) {
00122     assert( "This code has not been tested" );
00123     typename MAT::value_type ZERO = 0;
00124     for (unsigned i=0; i < M.rows(); i++) {
00125         for (unsigned j=0; j < M.cols(); j++) {
00126             if (M(i,j) != ZERO) {
00127                 return false;
00128             }
00129         }
00130     }
00131     return true;
00132 }
00133 
00134 #ifdef Spanish_dox
00135 /// Retorna \c "true" si la matriz \c M[][] es simétrica.
00136 #endif
00137 #ifdef English_dox
00138 /// Returns \c "true" if matrix \c M[][] is symetric.
00139 #endif
00140 template <class MAT>
00141 bool isSymmetric( const MAT& M ) {
00142     assert( "This code has not been tested" );
00143     if (M.rows() != M.cols()) {
00144         return false;
00145     }
00146     for (unsigned i=1; i < M.rows(); i++) {
00147         for (unsigned j=0; j < i; j++) {
00148             if (M(i,j) != M(j,i)) {
00149                 return false;
00150             }
00151         }
00152     }
00153     return true;
00154 }
00155 
00156 #ifdef Spanish_dox
00157 /// Retorna \c "true" si la matriz \c M[][] es triangular superior.
00158 #endif
00159 #ifdef English_dox
00160 /// Returns \c "true" if matrix \c M[][] is upper triangular.
00161 #endif
00162 template <class MAT>
00163 bool isUpperTiangular( const MAT& M ) {
00164     assert( "This code has not been tested" );
00165     if (M.rows() != M.cols()) {
00166         return false;
00167     }
00168 
00169     typename MAT::value_type ZERO = 0;
00170     for (unsigned i=1; i < M.rows(); i++) {
00171         for (unsigned j=0; j < i; j++) {
00172             if (M(i,j) != ZERO) {
00173                 return false;
00174             }
00175         }
00176     }
00177     return true;
00178 }
00179 
00180 #ifdef Spanish_dox
00181 /// Retorna \c "true" si la matriz \c M[][] es triangular inferior.
00182 #endif
00183 #ifdef English_dox
00184 /// Returns \c "true" if matrix \c M[][] is lower triangular.
00185 #endif
00186 template <class MAT>
00187 bool isLowerTiangular( const MAT& M ) {
00188     assert( "This code has not been tested" );
00189     if (M.rows() != M.cols()) {
00190         return false;
00191     }
00192 
00193     typename MAT::value_type ZERO = 0;
00194     for (unsigned j=1; j < M.cols(); j++) {
00195         for (unsigned i=0; i < j; i++) {
00196             if (M(i,j) != ZERO) {
00197                 return false;
00198             }
00199         }
00200     }
00201     return true;
00202 }
00203 
00204 } // namespace Mx
00205 
00206 #include <iostream> // istream && ostream
00207 #include "Matrix_BASE.h"
00208 
00209 #ifdef Spanish_dox
00210 /// Graba en el flujo \c COUT el valor de \c M[][].
00211 #endif
00212 #ifdef English_dox
00213 /// Stores into stream \c COUT the value for \c M[][].
00214 #endif
00215 template <class E>
00216 std::ostream& operator<<(std::ostream& COUT, const Mx::Matrix_BASE<E>& M) {
00217     COUT << '[' << M.rows() << 'x' << M.cols() << ']' << std::endl;
00218     for (unsigned i=0; i < M.rows(); ++i) {
00219         for (unsigned j=0; j < M.cols(); ++j) {
00220             COUT << "  " << M(i,j);
00221         }
00222         COUT << std::endl;
00223     }
00224     return COUT;
00225 }
00226 
00227 #ifdef Spanish_dox
00228 /// Obtiene del flujo \c CIN el valor para \c M[][].
00229 #endif
00230 #ifdef English_dox
00231 /// Gets from stream \c CIN the value for \c M[][].
00232 #endif
00233 template <class E>
00234 std::istream& operator>>(std::istream& CIN, Mx::Matrix_BASE<E>& M) {
00235     assert( "This code has not been tested" );
00236     unsigned rows,cols;
00237     CIN >> rows >> cols;
00238     M.reSize(rows,cols);
00239     for (unsigned i=0; i<rows; i++) {
00240         for (unsigned j=0; j<cols; j++) {
00241             CIN >> M(i,j);
00242         }
00243     }
00244     return CIN;
00245 }
00246 
00247 #ifdef Spanish_dox
00248     /// \c "Doxygen: Documentación en español"
00249     #define Spanish_dox "Doxygen: Documentación en español"
00250     /// \def   Matrix_Lib_h
00251     /// \brief Usada para evitar la inclusión múltiple.
00252 #endif
00253 #ifdef English_dox
00254     /// "Doxygen: English documentation"
00255     #define   English_dox   "Doxygen: English documentation"
00256     /// \def   Matrix_Lib_h
00257     /// \brief Used to avoid multiple inclusion.
00258 #endif
00259 
00260 #endif // Matrix_Lib_h
00261 
00262 // EOF: Matrix_Lib.h