Abstract non Polymorphyc Matrix:
|
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