io.hh

Go to the documentation of this file.
00001 #ifndef DUNE_ISTLIO_HH
00002 #define DUNE_ISTLIO_HH
00003 
00004 #include<cmath>
00005 #include<complex>
00006 #include<ios>
00007 #include<iomanip>
00008 #include<fstream>
00009 #include<string>
00010 
00011 #include "istlexception.hh"
00012 #include <dune/common/fvector.hh>
00013 #include <dune/common/fmatrix.hh>
00014 #include "bcrsmatrix.hh"
00015 
00016 
00017 namespace Dune {
00018    
00029   //==== pretty printing of vectors
00030 
00031   // recursively print all the blocks
00032   template<class V>
00033   void recursive_printvector (std::ostream& s, const V& v, std::string rowtext, int& counter, 
00034                                                           int columns, int width, int precision)
00035   {
00036         for (typename V::ConstIterator i=v.begin(); i!=v.end(); ++i)
00037           recursive_printvector(s,*i,rowtext,counter,columns,width,precision);
00038   }
00039 
00040   // specialization for FieldVector
00041   template<class K, int n>
00042   void recursive_printvector (std::ostream& s, const FieldVector<K,n>& v, std::string rowtext, int& counter, 
00043                                                           int columns, int width, int precision)
00044   {
00045         // we now can print n numbers
00046         for (int i=0; i<n; i++)
00047           {
00048                 if (counter%columns==0)
00049                   { 
00050                         s << rowtext; // start a new row
00051                         s << " ";     // space in front of each entry
00052                         s.width(4);   // set width for counter
00053                         s << counter; // number of first entry in a line
00054                   }
00055                 s << " ";         // space in front of each entry
00056                 s.width(width);   // set width for each entry anew
00057                 s << v[i];        // yeah, the number !
00058                 counter++;        // increment the counter
00059                 if (counter%columns==0)
00060                   s << std::endl; // start a new line
00061           }
00062   }
00063 
00064 
00065   template<class V>
00066   void printvector (std::ostream& s, const V& v, std::string title, std::string rowtext, 
00067                                         int columns=1, int width=10, int precision=2)
00068   {
00069         // count the numbers printed to make columns
00070         int counter=0;
00071 
00072         // remember old flags
00073         std::ios_base::fmtflags oldflags = s.flags();
00074         
00075         // set the output format
00076         s.setf(std::ios_base::scientific, std::ios_base::floatfield);
00077         int oldprec = s.precision();
00078         s.precision(precision);
00079 
00080         // print title
00081         s << title << " [blocks=" << v.N() << ",dimension=" << v.dim() << "]" << std::endl;
00082 
00083         // print data from all blocks
00084         recursive_printvector(s,v,rowtext,counter,columns,width,precision);
00085 
00086         // check if new line is required
00087         if (counter%columns!=0)
00088           s << std::endl;
00089 
00090         // reset the output format
00091         s.flags(oldflags);
00092         s.precision(oldprec);
00093   }
00094 
00095 
00096   //==== pretty printing of matrices
00097 
00098 
00100   inline void fill_row (std::ostream& s, int m, int width, int precision)
00101   {
00102         for (int j=0; j<m; j++)
00103           {
00104                 s << " ";         // space in front of each entry
00105                 s.width(width);   // set width for each entry anew
00106                 s << ".";         // yeah, the number !
00107           }
00108   }
00109 
00111   template<class M>
00112   void print_row (std::ostream& s, const M& A, typename M::size_type I,
00113                   typename M::size_type J, typename M::size_type therow,
00114                   int width, int precision)
00115   {
00116         typename M::size_type i0=I;
00117         for (typename M::size_type i=0; i<A.N(); i++)
00118           {
00119                 if (therow>=i0 && therow<i0+A.rowdim(i))
00120                   {
00121                         // the row is in this block row !
00122                         typename M::size_type j0=J;
00123                         for (typename M::size_type j=0; j<A.M(); j++)
00124                           {
00125                                 // find this block
00126                                 typename M::ConstColIterator it = A[i].find(j);
00127                                 
00128                                 // print row or filler
00129                                 if (it!=A[i].end())
00130                                   print_row(s,*it,i0,j0,therow,width,precision);
00131                                 else
00132                                   fill_row(s,A.coldim(j),width,precision);
00133                                 
00134                                 // advance columns
00135                                 j0 += A.coldim(j);
00136                           }
00137                   }
00138                 // advance rows
00139                 i0 += A.rowdim(i);
00140           }
00141   }
00142 
00144   template<class K, int n, int m>
00145   void print_row (std::ostream& s, const FieldMatrix<K,n,m>& A, 
00146                   typename FieldMatrix<K,n,m>::size_type I, typename FieldMatrix<K,n,m>::size_type J,
00147                   typename FieldMatrix<K,n,m>::size_type therow, int width, int precision)
00148   {
00149     typedef typename FieldMatrix<K,n,m>::size_type size_type;
00150     
00151         for (size_type i=0; i<n; i++)
00152           if (I+i==therow)
00153                   for (int j=0; j<m; j++)
00154                         {
00155                           s << " ";         // space in front of each entry
00156                           s.width(width);   // set width for each entry anew
00157                           s << A[i][j];     // yeah, the number !
00158                         }
00159   }
00160 
00162   template<class K>
00163   void print_row (std::ostream& s, const FieldMatrix<K,1,1>& A, typename FieldMatrix<K,1,1>::size_type I, 
00164                   typename FieldMatrix<K,1,1>::size_type J, typename FieldMatrix<K,1,1>::size_type therow, 
00165                   int width, int precision)
00166   {
00167         if (I==therow)
00168           {
00169                 s << " ";         // space in front of each entry
00170                 s.width(width);   // set width for each entry anew
00171                 s << static_cast<K>(A);         // yeah, the number !
00172           }
00173   }
00174 
00178   template<class M>
00179   void printmatrix (std::ostream& s, const M& A, std::string title, std::string rowtext, 
00180                                         int width=10, int precision=2)
00181   {
00182     
00183         // remember old flags
00184         std::ios_base::fmtflags oldflags = s.flags();
00185 
00186         // set the output format
00187         s.setf(std::ios_base::scientific, std::ios_base::floatfield);
00188         int oldprec = s.precision();
00189         s.precision(precision);
00190 
00191         // print title
00192         s << title 
00193           << " [n=" << A.N() 
00194           << ",m=" << A.M() 
00195           << ",rowdim=" << A.rowdim() 
00196           << ",coldim=" << A.coldim() 
00197           << "]" << std::endl;
00198 
00199         // print all rows
00200         for (typename M::size_type i=0; i<A.rowdim(); i++)
00201           {
00202                 s << rowtext;  // start a new row
00203                 s << " ";      // space in front of each entry
00204                 s.width(4);    // set width for counter
00205                 s << i;        // number of first entry in a line
00206                 print_row(s,A,0,0,i,width,precision); // generic print
00207                 s << std::endl;// start a new line
00208           }
00209 
00210         // reset the output format
00211         s.flags(oldflags);
00212         s.precision(oldprec);
00213   }
00214 
00232   template<class B, int n, int m, class A>
00233   void printSparseMatrix(std::ostream& s, 
00234                          const BCRSMatrix<FieldMatrix<B,n,m>,A>& mat, 
00235                          std::string title, std::string rowtext, 
00236                          int width=3, int precision=2)
00237   {
00238     // remember old flags
00239     std::ios_base::fmtflags oldflags = s.flags();
00240     // set the output format
00241     s.setf(std::ios_base::scientific, std::ios_base::floatfield);
00242     int oldprec = s.precision();
00243     s.precision(precision);
00244     // print title
00245     s << title 
00246       << " [n=" << mat.N() 
00247       << ",m=" << mat.M() 
00248       << ",rowdim=" << mat.rowdim() 
00249       << ",coldim=" << mat.coldim() 
00250       << "]" << std::endl;
00251     
00252     typedef typename BCRSMatrix<FieldMatrix<B,n,m>,A>::ConstRowIterator Row;
00253     
00254     for(Row row=mat.begin(); row != mat.end();++row){
00255       int skipcols=0;
00256       bool reachedEnd=false;
00257       
00258       while(!reachedEnd){
00259         for(int innerrow=0; innerrow<n; ++innerrow){
00260           int count=0;
00261           typedef typename BCRSMatrix<FieldMatrix<B,n,m>,A>::ConstColIterator Col;
00262           Col col=row->begin();   
00263           for(; col != row->end(); ++col,++count){
00264             if(count<skipcols)
00265               continue;
00266             if(count>=skipcols+width)
00267               break;
00268             if(innerrow==0){
00269               if(count==skipcols){
00270                 s << rowtext;  // start a new row
00271                 s << " ";      // space in front of each entry
00272                 s.width(4);    // set width for counter
00273                 s << row.index()<<": ";        // number of first entry in a line
00274               }
00275               s.width(4);
00276               s<<col.index()<<": |";
00277             }else{
00278               if(count==skipcols){
00279                 for(int i=0; i < rowtext.length(); i++)
00280                   s<<" ";
00281                 s<<"       ";
00282               }
00283               s<<"      |";
00284             }
00285             for(int innercol=0; innercol < m; ++innercol){
00286               s.width(9);
00287               s<<(*col)[innerrow][innercol]<<" ";
00288             }
00289             
00290             s<<"|";
00291           }
00292           if(innerrow==n-1 && col==row->end())
00293             reachedEnd=true;
00294           else
00295             s<<std::endl;
00296         }
00297         skipcols+=width;
00298         s<<std::endl;
00299       }
00300       s<<std::endl;
00301     }
00302     
00303     // reset the output format
00304     s.flags(oldflags);
00305     s.precision(oldprec);
00306   }
00307   
00312     template <class FieldType, int rows, int cols>
00313     void writeMatrixToMatlabHelper(const FieldMatrix<FieldType,rows,cols>& matrix,
00314                                    int rowOffset, int colOffset,
00315                                    std::ostream& s)
00316     {
00317         for (int i=0; i<rows; i++)
00318             for (int j=0; j<cols; j++)
00319                 //+1 for Matlab numbering
00320                 s << rowOffset + i + 1 << " " << colOffset + j + 1 << " " << matrix[i][j] << std::endl;
00321         
00322     }
00323     
00324     template <class MatrixType>
00325     void writeMatrixToMatlabHelper(const MatrixType& matrix, 
00326                                    int externalRowOffset, int externalColOffset,
00327                                    std::ostream& s)
00328 {
00329     // Precompute the accumulated sizes of the columns
00330     std::vector<unsigned int> colOffset(matrix.M());
00331     if (colOffset.size() > 0)
00332         colOffset[0] = 0;
00333 
00334     for (int i=0; i<matrix.M()-1; i++)
00335         colOffset[i+1] = colOffset[i] + matrix.coldim(i);
00336     
00337     int rowOffset = 0;
00338 
00339     // Loop over all matrix rows
00340     for (int rowIdx=0; rowIdx<matrix.N(); rowIdx++) {
00341         
00342         const typename MatrixType::row_type& row = matrix[rowIdx];
00343 
00344         typename MatrixType::row_type::ConstIterator cIt   = row.begin();
00345         typename MatrixType::row_type::ConstIterator cEndIt = row.end();
00346         
00347         // Loop over all columns in this row
00348         for (; cIt!=cEndIt; ++cIt) 
00349             writeMatrixToMatlabHelper(*cIt, 
00350                                       externalRowOffset+rowOffset, 
00351                                       externalColOffset + colOffset[cIt.index()], 
00352                                       s);
00353 
00354         rowOffset += matrix.rowdim(rowIdx);
00355     }
00356     
00357 }
00358 
00370 template <class MatrixType>
00371 void writeMatrixToMatlab(const MatrixType& matrix, 
00372                          const std::string& filename)
00373 {
00374     std::ofstream outStream(filename.c_str());
00375 
00376     writeMatrixToMatlabHelper(matrix, 0, 0, outStream);
00377 }
00378 
00381 } // end namespace
00382 
00383 #endif

Generated on 9 Apr 2008 with Doxygen (ver 1.5.2) [logfile].