ostream_mat.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup ostream
00017 //! @{
00018 
00019 class arma_ostream
00020   {
00021   public:
00022   
00023   template<typename eT>
00024   inline static u32 set_flags(std::ostream& o, const Mat<eT>& m);
00025   
00026   template<typename T>
00027   inline static u32 set_flags(std::ostream& o, const Mat< std::complex<T> >& m);
00028   
00029   };
00030 
00031 
00032 
00033 template<typename eT>
00034 inline
00035 u32
00036 arma_ostream::set_flags(std::ostream& o, const Mat<eT>& m)
00037   {
00038   o.unsetf(ios::showbase);
00039   o.unsetf(ios::uppercase);
00040   o.fill(' ');
00041   
00042   bool use_layout_B = false;
00043   bool use_layout_C = false;
00044   
00045   for(u32 i=0; i<m.n_elem; ++i)
00046     {
00047     const eT val = m.mem[i];
00048     
00049     if(
00050       val >= eT(+100) ||
00051       ( (is_signed<eT>::value == true) && (val <= eT(-100)) ) ||
00052       ( (is_non_integral<eT>::value == true) && (val > eT(0)) && (val <= eT(+1e-4)) ) ||
00053       ( (is_non_integral<eT>::value == true) && (is_signed<eT>::value == true) && (val < eT(0)) && (val >= eT(-1e-4)) ) 
00054       )
00055       {
00056       use_layout_C = true;
00057       break;
00058       }
00059       
00060     if(
00061       (val >= eT(+10)) || ( (is_signed<eT>::value == true) && (val <= eT(-10)) )
00062       )
00063       {
00064       use_layout_B = true;
00065       }
00066     }
00067   
00068   u32 cell_width;
00069   
00070   if(use_layout_C == true)
00071     {
00072     o.setf(ios::scientific);
00073     o.unsetf(ios::fixed);
00074     o.precision(4);
00075     cell_width = 13;
00076     }
00077   else
00078   if(use_layout_B == true)
00079     {
00080     o.unsetf(ios::scientific);
00081     o.setf(ios::fixed);
00082     o.precision(4);
00083     cell_width = 10;
00084     }
00085   else
00086     {
00087     o.unsetf(ios::scientific);
00088     o.setf(ios::fixed);
00089     o.precision(4);
00090     cell_width = 9;
00091     }
00092  
00093   return cell_width;
00094   }
00095 
00096 
00097 
00098 //! "better than nothing" settings for complex numbers
00099 template<typename T>
00100 inline
00101 u32
00102 arma_ostream::set_flags(std::ostream& o, const Mat< std::complex<T> >& m)
00103   {
00104   o.unsetf(ios::showbase);
00105   o.unsetf(ios::uppercase);
00106   o.fill(' ');
00107   
00108   o.setf(ios::scientific);
00109   o.setf(ios::showpos);
00110   o.unsetf(ios::fixed);
00111   o.precision(3);
00112   const u32 cell_width = 25;
00113   return cell_width;
00114   }
00115 
00116 
00117 
00118 //! Print a matrix to the specified stream
00119 template<typename eT>
00120 inline
00121 std::ostream&
00122 operator<< (std::ostream& o, const Mat<eT>& m)
00123   {
00124   arma_extra_debug_sigprint();
00125   
00126   const ios::fmtflags orig_flags = o.flags();
00127   const u32 cell_width = arma_ostream::set_flags(o, m);
00128   
00129   for(u32 row=0; row != m.n_rows; ++row)
00130     {
00131     for(u32 col=0; col != m.n_cols; ++col)
00132       {
00133       o.width(cell_width);
00134       o << m.at(row,col);
00135       }
00136     
00137     o << '\n';
00138     }
00139   
00140   o.flush();
00141   o.flags(orig_flags);
00142   
00143   return o;
00144   }
00145 
00146 
00147 
00148 
00149 
00150 //! @}