Commit 631243a0 authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Refactoring the matrix reader, implementing the matrix writer.

parent 64e9cb07
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
SET( headers tnlDenseMatrix_impl.h
SET( headers tnlMatrix_impl.h
             tnlDenseMatrix_impl.h
             tnlTridiagonalMatrix_impl.h
             tnlMultidiagonalMatrix_impl.h 
             tnlEllpackMatrix_impl.h
             tnlSlicedEllpackMatrix_impl.h
             tnlChunkedEllpackMatrix_impl.h
             tnlCSRMatrix_impl.h
             tnlMatrixReader_impl.h )
             tnlMatrixReader_impl.h
             tnlMatrixWriter_impl.h )

SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/matrices )
set( common_SOURCES
+218 −140
Original line number Diff line number Diff line
@@ -21,142 +21,55 @@
#include <iomanip>
#include <core/tnlString.h>
#include <core/vectors/tnlVector.h>
#include <core/tnlTimerRT.h>

using namespace std;

template< typename Matrix >
bool tnlMatrixReader::readMtxFile( std::istream& file,
bool tnlMatrixReader< Matrix >::readMtxFile( std::istream& file,
                                             Matrix& matrix,
                                   bool verbose,
                                   bool verify )
                                             bool verbose )
{
   typedef typename Matrix::IndexType IndexType;
   typedef typename Matrix::RealType RealType;
   IndexType rows, columns;
   bool symmetricMatrix;

   tnlString line;
   bool dimensionsLine( false ), formatOk( false );
   tnlList< tnlString > parsedLine;
   IndexType numberOfElements( 0 );
   IndexType size( 0 );
   bool symmetric( false );
   tnlVector< IndexType, tnlHost, IndexType > rowLengths;
   rowLengths.setName( "tnlMatrixReader::rowLengths");
   if( verbose )
      cout << "Counting the non-zero elements in rows..." << endl;
   while( line.getLine( file ) )
   {
      if( ! formatOk )
      {
         formatOk = checkMtxHeader( line, symmetric );
         if( formatOk && verbose )
         {
          if( symmetric )
             cout << "The matrix is SYMMETRIC." << endl;
         }
         continue;
      }
      if( line[ 0 ] == '%' ) continue;
      if( ! formatOk )
      {
         cerr << "Uknown format of the file. We expect line like this:" << endl;
         cerr << "%%MatrixMarket matrix coordinate real general" << endl;
         return false;
      }

      if( ! dimensionsLine )
      {
         parsedLine. EraseAll();
         line. parse( parsedLine );
         if( parsedLine. getSize() != 3 )
         {
           cerr << "Wrong number of parameters in the matrix header." << endl;
   if( ! readMtxHeader( file, rows, columns, symmetricMatrix, verbose ) )
      return false;
         }
         const IndexType rows = atoi( parsedLine[ 0 ]. getString() );
         const IndexType columns = atoi( parsedLine[ 1 ]. getString() );
         numberOfElements = atoi( parsedLine[ 1 ]. getString() );
         cout << "Matrix rows:       " << setw( 9 ) << right << rows << endl;
         cout << "Matrix columns:       " << setw( 9 ) << right << columns << endl;

         if( rows <= 0 || columns <= 0 )
         {
           cerr << "Wrong parameters in the matrix header." << endl;
           return false;
         }
   tnlVector< int, tnlHost, int > rowLengths;
   if( ! matrix.setDimensions( rows, columns ) ||
       ! rowLengths.setSize( rows ) )
   {
      cerr << "Not enough memory to allocate the sparse or the full matrix for testing." << endl;
      return false;
   }
         rowLengths.setValue( 0 );

         dimensionsLine = true;
         continue;
      }
      if( parsedLine. getSize() != 3 )
      {
         cerr << "Wrong number of parameters in the matrix row at line:" << line << endl;
   if( ! computeRowLengthsFromMtxFile( file, rowLengths, symmetricMatrix, verbose ) )
      return false;
      }
      parsedLine. EraseAll();
      line. parse( parsedLine );
      const IndexType row = atoi( parsedLine[ 0 ]. getString() );
      const IndexType column = atoi( parsedLine[ 1 ]. getString() );
      numberOfElements ++;
      if( verbose )
         cout << "Parsed thousands of elements:   " << setw( 9 ) << right << numberOfElements / 1000 << "\r" << flush;
      rowLengths[ row - 1 ]++;
      if( symmetric && row != column )
         rowLengths[ column - 1 ]++;
   }

   if( ! matrix.setRowLengths( rowLengths ) )
   {
      cerr << "Not enough memory to allocate the matrix." << endl;
      return false;
   }

   /****
    * Read the matrix elements
    */
   if( verbose )
      cout << endl;
   dimensionsLine = false;
   file.clear();
   file.seekg( 0,  ios::beg );
   IndexType parsedElements( 0 );
   if( verbose )
      cout << "Reading the matrix elements ..." << endl;
   while( line.getLine( file ) )
   {
      if( line[ 0 ] == '%' ) continue;
      if( ! dimensionsLine )
      {
         dimensionsLine = true;
         continue;
      }
      parsedLine.EraseAll();
      line.parse( parsedLine );
      const IndexType row = atoi( parsedLine[ 0 ].getString() );
      const IndexType column = atoi( parsedLine[ 1 ].getString() );
      const RealType value = ( RealType ) atof( parsedLine[ 2 ].getString() );
      matrix.setElement( row - 1, column - 1, value );
      if( symmetric && row != column )
         matrix.setElement( column - 1, row - 1, value );
      parsedElements++;
      if( verbose )
         cout << parsedElements << " / " << numberOfElements << "                       \r " << flush;
   if( ! readMatrixElementsFromMtxFile( file, matrix, symmetricMatrix, verbose ) )
      return false;
   return true;
}
   if( verbose )
      cout << endl;
   if( verify )

template< typename Matrix >
bool tnlMatrixReader< Matrix >::verifyMtxFile( std::istream& file,
                                               const Matrix& matrix,
                                               bool verbose )
{
      if( verbose )
         cout << "Verifying the matrix elements ... " << endl;
      dimensionsLine = false;
   bool symmetricMatrix( false );
   IndexType rows, columns;
   if( ! readMtxHeader( file, rows, columns, symmetricMatrix, false ) )
      return false;
   file.clear();
   file.seekg( 0, ios::beg );
      IndexType parsedElements( 0 );
   tnlString line;
   bool dimensionsLine( false );
   IndexType processedElements( 0 );
   tnlTimerRT timer;
   while( line.getLine( file ) )
   {
      if( line[ 0 ] == '%' ) continue;
@@ -165,29 +78,36 @@ bool tnlMatrixReader::readMtxFile( std::istream& file,
         dimensionsLine = true;
         continue;
      }
         parsedLine.EraseAll();
         line.parse( parsedLine );
         const IndexType row = atoi( parsedLine[ 0 ].getString() );
         const IndexType column = atoi( parsedLine[ 1 ].getString() );
         const RealType value = ( RealType ) atof( parsedLine[ 2 ].getString() );
      IndexType row, column;
      RealType value;
      if( ! parseMtxLineWithElement( line, row, column, value ) )
         return false;
      if( value != matrix.getElement( row-1, column-1 ) ||
             ( symmetric && value != matrix.getElement( column-1, row-1 ) ) )
          ( symmetricMatrix && value != matrix.getElement( column-1, row-1 ) ) )
      {
            cerr << "The elements differ at " << row-1 << " row " << column-1 << " column." << endl
         cerr << "*** !!! VERIFICATION ERROR !!! *** " << endl
              << "The elements differ at " << row-1 << " row " << column-1 << " column." << endl
              << "The matrix value is " << matrix.getElement( row-1, column-1 )
              << " while the file value is " << value << "." << endl;
         return false;
      }
      processedElements++;
      if( symmetricMatrix && row != column )
         processedElements++;
      if( verbose )
            cout << parsedElements << " / " << numberOfElements << "                       \r " << flush;
         cout << " Verifying the matrix elements ... " << processedElements << " / " << matrix.getNumberOfAllocatedElements() << "                       \r" << flush;
   }
   file.clear();
   long int fileSize = file.tellg();
   if( verbose )
         cout << endl;
   }
      cout << " Verifying the matrix elements ... " << processedElements << " / " << matrix.getNumberOfAllocatedElements()
           << " -> " << timer.GetTime()
           << " sec. i.e. " << fileSize / ( timer.GetTime() * ( 1 << 20 ))  << "MB/s." << endl;
   return true;
}

inline bool tnlMatrixReader::checkMtxHeader( const tnlString& header,
template< typename Matrix >
bool tnlMatrixReader< Matrix >::checkMtxHeader( const tnlString& header,
                                                bool& symmetric )
{
   tnlList< tnlString > parsedLine;
@@ -225,5 +145,163 @@ inline bool tnlMatrixReader::checkMtxHeader( const tnlString& header,
   return true;
}

template< typename Matrix >
bool tnlMatrixReader< Matrix >::readMtxHeader( std::istream& file,
                                               IndexType& rows,
                                               IndexType& columns,
                                               bool& symmetric,
                                               bool verbose )
{
   file.clear();
   file.seekg( 0, ios::beg );
   tnlString line;
   bool headerParsed( false );
   tnlList< tnlString > parsedLine;
   while( true )
   {
      line.getLine( file );
      if( ! headerParsed )
      {
           headerParsed = checkMtxHeader( line, symmetric );
           if( headerParsed && verbose )
           {
               if( symmetric )
                  cout << "The matrix is SYMMETRIC ... ";
           }
           continue;
      }
      if( line[ 0 ] == '%' ) continue;
      if( ! headerParsed )
      {
         cerr << "Uknown format of the file. We expect line like this:" << endl;
         cerr << "%%MatrixMarket matrix coordinate real general" << endl;
         return false;
      }

      parsedLine. EraseAll();
      line. parse( parsedLine );
      if( parsedLine. getSize() != 3 )
      {
         cerr << "Wrong number of parameters in the matrix header." << endl;
         return false;
      }
      rows = atoi( parsedLine[ 0 ]. getString() );
      columns = atoi( parsedLine[ 1 ]. getString() );
      if( verbose )
         cout << " The matrix has " << rows
              << " rows and " << columns << " columns. " << endl;

      if( rows <= 0 || columns <= 0 )
      {
         cerr << "Wrong parameters in the matrix header." << endl;
         return false;
      }
      return true;
   }
}

template< typename Matrix >
bool tnlMatrixReader< Matrix >::computeRowLengthsFromMtxFile( std::istream& file,
                                                              tnlVector< int, tnlHost, int >& rowLengths,
                                                              bool symmetricMatrix,
                                                              bool verbose )
{
   file.clear();
   file.seekg( 0,  ios::beg );
   rowLengths.setValue( 0 );
   tnlString line;
   bool dimensionsLine( false );
   IndexType numberOfElements( 0 );
   tnlTimerRT timer;
   while( line.getLine( file ) )
   {
      if( line[ 0 ] == '%' ) continue;
      if( ! dimensionsLine )
      {
         dimensionsLine = true;
         continue;
      }
      IndexType row, column;
      RealType value;
      if( ! parseMtxLineWithElement( line, row, column, value ) )
         return false;
      numberOfElements++;
      if( verbose )
         cout << " Counting the matrix elements ... " << numberOfElements / 1000 << " thousands      \r" << flush;
      rowLengths[ row - 1 ]++;
      if( symmetricMatrix && row != column )
         rowLengths[ column - 1 ]++;
   }
   file.clear();
   long int fileSize = file.tellg();
   if( verbose )
      cout << " Counting the matrix elements ... " << numberOfElements / 1000
           << " thousands  -> " << timer.GetTime()
           << " sec. i.e. " << fileSize / ( timer.GetTime() * ( 1 << 20 ))  << "MB/s." << endl;
   return true;
}

template< typename Matrix >
bool tnlMatrixReader< Matrix >::readMatrixElementsFromMtxFile( std::istream& file,
                                                               Matrix& matrix,
                                                               bool symmetricMatrix,
                                                               bool verbose )
{
   file.clear();
   file.seekg( 0,  ios::beg );
   tnlString line;
   bool dimensionsLine( false );
   IndexType processedElements( 0 );
   tnlTimerRT timer;
   while( line.getLine( file ) )
   {
      if( line[ 0 ] == '%' ) continue;
      if( ! dimensionsLine )
      {
         dimensionsLine = true;
         continue;
      }
      IndexType row, column;
      RealType value;
      if( ! parseMtxLineWithElement( line, row, column, value ) )
         return false;
      matrix.setElement( row - 1, column - 1, value );
      processedElements++;
      if( symmetricMatrix && row != column )
      {
         matrix.setElement( column - 1, row - 1, value );
         processedElements++;
      }
      if( verbose )
         cout << " Reading the matrix elements ... " << processedElements << " / " << matrix.getNumberOfAllocatedElements() << "                       \r" << flush;
   }
   file.clear();
   long int fileSize = file.tellg();
   if( verbose )
      cout << " Reading the matrix elements ... " << processedElements << " / " << matrix.getNumberOfAllocatedElements()
              << " -> " << timer.GetTime()
              << " sec. i.e. " << fileSize / ( timer.GetTime() * ( 1 << 20 ))  << "MB/s." << endl;
   return true;
}

template< typename Matrix >
bool tnlMatrixReader< Matrix >::parseMtxLineWithElement( const tnlString& line,
                                                         IndexType& row,
                                                         IndexType& column,
                                                         RealType& value )
{
   tnlList< tnlString > parsedLine;
   line.parse( parsedLine );
   if( parsedLine.getSize() != 3 )
   {
      cerr << "Wrong number of parameters in the matrix row at line:" << line << endl;
      return false;
   }
   row = atoi( parsedLine[ 0 ].getString() );
   column = atoi( parsedLine[ 1 ].getString() );
   value = ( RealType ) atof( parsedLine[ 2 ].getString() );
   return true;
}


#endif /* TNLMATRIXREADER_IMPL_H_ */
+102 −0
Original line number Diff line number Diff line
/***************************************************************************
                          tnlMatrixWriter_impl.h  -  description
                             -------------------
    begin                : Dec 18, 2013
    copyright            : (C) 2013 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TNLMATRIXWRITER_IMPL_H_
#define TNLMATRIXWRITER_IMPL_H_

template< typename Matrix >
bool tnlMatrixWriter< Matrix >::writeToGnuplot( std::ostream str,
                                                const Matrix& matrix,
                                                bool verbose )
{
   for( IndexType row = 0; row < matrix.getRows(); row ++ )
   {
      for( IndexType column = 0; column < matrix.getColumns(); column ++ )
      {
         RealType elementValue = maytrix.getElement( row, column );
         if(  elementValue != ( RealType ) 0.0 )
            str << column << " " << getSize() - row << " " << elementValue << endl;
      }
      if( verbose )
         cout << "Drawing the row " << row << "      \r" << flush;
   }
   if( verbose )
      cout << endl;
   return true;
}

template< typename Matrix >
bool tnlMatrixWriter< Matrix >::writeToEps( std::ostream str,
                                            const Matrix& matrix,
                                            bool verbose )
{
   const int elementSize = 10;
   if( ! writeEpsHeader( str, matrix, elementSize ) )
      return false;
   if( !writeEpsBody( str, matrix, elementSize, verbose ) )
      return false;

   str << "showpage" << endl;
   str << "%%EOF" << endl;

   if( verbose )
      cout << endl;
   return true;
}

template< typename Matrix >
bool tnlMatrixWriter< Matrix >::writeEpsHeader( std::ostream str,
                                                const Marix& matrix,
                                                const int elementSize )
{
   const double scale = elementSize * Max( matrix.getRows(), matrix.getColumns() );
   str << "%!PS-Adobe-2.0 EPSF-2.0" << endl;
   str << "%%BoundingBox: 0 0 " << scale << " " << scale << endl;
   str << "%%Creator: TNL" << endl;
   str << "%%LanguageLevel: 2" << endl;
   str << "%%EndComments" << endl << endl;
   str << "0 " << scale << " translate" << endl;
   return true;
}

template< typename Matrix >
bool tnlMatrixWriter< Matrix >::writeEpsBody( std::ostream str,
                                              const Marix& matrix,
                                              const int elementSize )
{
   IndexType lastRow( 0 ), lastColumn( 0 );
   for( IndexType row = 0; row < getSize(); row ++ )
   {
      for( IndexType column = 0; column < getSize(); column ++ )
      {
         RealType elementValue = getElement( row, column );
         if( elementValue != ( RealType ) 0.0 )
         {
            str << ( column - lastColumn ) * elementSize
                << " " << -( row - lastRow ) * elementSize
                << " translate newpath 0 0 " << elementSize << " " << elementSize << " rectstroke" << endl;
            lastColumn = column;
            lastRow = row;
         }
      }
      if( verbose )
         cout << "Drawing the row " << row << "      \r" << flush;
   }
   return true;
}

#endif /* TNLMATRIXWRITER_IMPL_H_ */
+24 −0
Original line number Diff line number Diff line
/***************************************************************************
                          tnlMatrix_impl.h  -  description
                             -------------------
    begin                : Dec 18, 2013
    copyright            : (C) 2013 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TNLMATRIX_IMPL_H_
#define TNLMATRIX_IMPL_H_




#endif /* TNLMATRIX_IMPL_H_ */
Loading