lkptr - simple reference LinKed PoinTeR:
test_RefMatrix.cpp
Go to the documentation of this file.
00001 // test_RefMatrix.cpp  (C)  2004 adolfo@di-mare.com
00002 
00003 /** \file  test_RefMatrix.cpp
00004     \brief Datos de prueba para la clase \c RefMatrix
00005 
00006     \author Adolfo Di Mare <adolfo@di-mare.com>
00007     \date   2004
00008 
00009     - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04
00010 */
00011 
00012 #include <iostream>
00013 #include <iomanip>   // setw(4)
00014 
00015 #include "RefMatrix.h"
00016 
00017 using namespace Mx;
00018 using namespace std;
00019 
00020 /// Retorna \c "true" si la matriz \c M es una matriz cuadrada
00021 template <class E>
00022 bool isSquare( const RefMatrix<E>& M ) {
00023     return M.rows() == M.cols();
00024 }
00025 
00026 /// Retorna \c "true" si la matriz es simétrica
00027 template <class E>
00028 bool isSymmetric( const RefMatrix<E>& M ) {
00029     assert( "This code has not been tested" );
00030     if (M.rows() != M.cols()) {
00031         return false;
00032     }
00033     for (unsigned i=1; i < M.rows(); i++) {
00034         for (unsigned j=0; j < i; j++) {
00035             if (M(i,j) != M(j,i)) {
00036                 return false;
00037             }
00038         }
00039     }
00040     return true;
00041 }
00042 
00043 /// Imprime por filas el valor de \c "M"
00044 template <class E>
00045 void print( const char* name, RefMatrix<E> & V ) {
00046     cout << endl << name << '[' << V.rows() << ',' << V.cols() << ']' << endl;
00047     for (unsigned i=0; i < V.rows(); ++i) {
00048         for (unsigned j=0; j < V.cols(); ++j) {
00049             cout << "  " << setw(4) << V(i,j);
00050         }
00051         cout << endl;
00052     }
00053 }
00054 
00055 /// Ejemplo de uso de referencia \c lkptr< RefMatrix<unsigned> >.
00056 void use_lkptr( unsigned M, unsigned N ) {
00057     lkptr< RefMatrix<unsigned> > A ( new RefMatrix<unsigned>(M,N) );
00058     RefMatrix<unsigned>& AA = *A; // AA(i,j) == (*A)(i,j)
00059 
00060     unsigned k = 0;
00061     for ( unsigned i=0; i < A->rows(); ++i ) {
00062         for ( unsigned j=0; j < A->cols(); ++j,++k ) {
00063             A->at(i,j) = k; AA(i,j) = k;
00064         }
00065     }
00066 
00067     lkptr< RefMatrix<unsigned> > B, C ( A ); // A y C comparten el valor
00068     assert( B.get() == 0 ); // B es un objeto nulo
00069     B = C; // A B y C comparten el valor
00070     B->reSize( B->cols(), B->rows() ); // todos fueron modificados
00071     assert( B == A );   // comparación de punteros
00072     assert( *B == *A ); // comparación de matrices
00073     B.reset( A->clone() ); // B tiene una copia de A
00074     B->reSize(N,M); // solo B cambia
00075     C = (C - C);
00076     assert( A->at(0,0) == 0 ); // porque C borró todo
00077     C = B + B - B;
00078     B->reSize( B->cols(), B->rows() ); // solo B cambia
00079     A = C * B; // ya ninguno comparte memoria
00080     assert( *A != *B && *B != *C && *C != *A ); // comparación de matrices
00081 }
00082 
00083 /// Programa que ejercita las principales funciones de las matrices
00084 int main() {
00085     const unsigned M = 5;
00086     const unsigned N = 8;
00087     use_lkptr( M, N );
00088     unsigned i,j,k;
00089     char * above = new char [10];
00090     typedef RefMatrix<unsigned> RefMatrix_unsigned;
00091     lkptr< RefMatrix<unsigned> > V ( new RefMatrix<unsigned>(M,N) );
00092     char * below = new char [10];
00093 
00094     RefMatrix<unsigned>& VV = *V; // VV(i,j) == (*V)(i,j)
00095     k = 0;
00096     for (i=0; i < V->rows(); ++i) {
00097         for (j=0; j < V->cols(); ++j,++k) {
00098             (*V)(i,j)  = 0;         // ok
00099             V->operator()(i,j) = k; // ok
00100             V->at(i,j) = k;         // ok
00101             VV(i,j) = k; /* !!!! */ // ok
00102         //  V(i,j) = k;    // no no no no
00103 
00104             assert(  V->at(i,j) ==  VV(i,j) );
00105             assert( &V->at(i,j) == &VV(i,j) );
00106         }
00107     }
00108 
00109     lkptr< RefMatrix<unsigned> > A;
00110     A = V;
00111     assert( A == V );
00112     print("A", *A);
00113 
00114     V->reShape(N,M);
00115     print("V", *V);
00116 
00117     // k = 0;
00118     for (i=0; i < V->rows(); ++i) {
00119         for (j=0; j < V->cols(); ++j) {
00120             V->operator()(i,j) = k++;
00121         }
00122     }
00123 
00124     lkptr< RefMatrix<unsigned> > B;
00125     B = V;
00126     assert( B == V );
00127     print("B", *B);
00128 
00129     lkptr<RefMatrix_unsigned> C = V;
00130     C = C + C;
00131     print("C", *C);
00132 
00133     C = A - A;
00134     print( "C", *C );
00135     assert( ! isSquare( *C ) && ! isSymmetric( *C ) );
00136 
00137     B->reShape( B->cols(), B->rows() );
00138     print("A", *A); // A es V es B es A ==> al cambiar 1, cambian todas
00139     assert( A->rows() == B->rows() && A->cols() == B->cols() );
00140     A.reset( B->clone() ); // Ahora A tiene una copia de los valores de B
00141     B->reShape( B->cols(), B->rows() ); // Cambian V,B pero no cambia A
00142     assert( V->rows() == B->rows() && V->cols() == B->cols() );
00143     print("B", *B);
00144     C = A * B;
00145     print("C", *C);
00146     assert( isSquare( *C ) && ! isSymmetric( *C ) );
00147 
00148     C = (A - A) * (B + B) - C;
00149     print( "C", *C ); // da números locos porque la matriz es "unsigned"
00150     assert( isSquare( *C ) && ! isSymmetric( *C ) );
00151 
00152     print("A", *A);
00153     print("B", *B);
00154     C = B * A;
00155     print("C", *C);
00156     assert( isSquare( *C ) && ! isSymmetric( *C ) );
00157 
00158     return 0;
00159 }
00160 
00161 // EOF: test_RefMatrix.cpp
00162 
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines