arma_ostream_meat.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 arma_ostream
00017 //! @{
00018 
00019 
00020 
00021 inline
00022 arma_ostream_state::arma_ostream_state(const std::ostream& o)
00023   : orig_flags    (o.flags())
00024   , orig_precision(o.precision())
00025   , orig_width    (o.width())
00026   , orig_fill     (o.fill())
00027   {
00028   }
00029 
00030 
00031 
00032 inline
00033 void
00034 arma_ostream_state::restore(std::ostream& o) const
00035   {
00036   o.flags    (orig_flags);
00037   o.precision(orig_precision);
00038   o.width    (orig_width);
00039   o.fill     (orig_fill);
00040   }
00041 
00042 
00043 
00044 //
00045 //
00046 
00047 
00048 
00049 template<typename eT>
00050 inline
00051 u32
00052 arma_ostream::modify_stream(std::ostream& o, const eT* data, const u32 n_elem)
00053   {
00054   o.unsetf(ios::showbase);
00055   o.unsetf(ios::uppercase);
00056   o.fill(' ');
00057 
00058   u32 cell_width;
00059   
00060   bool use_layout_B = false;
00061   bool use_layout_C = false;
00062   
00063   for(u32 i=0; i<n_elem; ++i)
00064     {
00065     const eT val = data[i];
00066     
00067     if(
00068       val >= eT(+100) ||
00069       ( (is_signed<eT>::value == true) && (val <= eT(-100)) ) ||
00070       ( (is_non_integral<eT>::value == true) && (val > eT(0)) && (val <= eT(+1e-4)) ) ||
00071       ( (is_non_integral<eT>::value == true) && (is_signed<eT>::value == true) && (val < eT(0)) && (val >= eT(-1e-4)) ) 
00072       )
00073       {
00074       use_layout_C = true;
00075       break;
00076       }
00077       
00078     if(
00079       (val >= eT(+10)) || ( (is_signed<eT>::value == true) && (val <= eT(-10)) )
00080       )
00081       {
00082       use_layout_B = true;
00083       }
00084     }
00085   
00086   if(use_layout_C == true)
00087     {
00088     o.setf(ios::scientific);
00089     o.unsetf(ios::fixed);
00090     o.precision(4);
00091     cell_width = 13;
00092     }
00093   else
00094   if(use_layout_B == true)
00095     {
00096     o.unsetf(ios::scientific);
00097     o.setf(ios::fixed);
00098     o.precision(4);
00099     cell_width = 10;
00100     }
00101   else
00102     {
00103     o.unsetf(ios::scientific);
00104     o.setf(ios::fixed);
00105     o.precision(4);
00106     cell_width = 9;
00107     }
00108   
00109   return cell_width;
00110   }
00111 
00112 
00113 
00114 //! "better than nothing" settings for complex numbers
00115 template<typename T>
00116 inline
00117 u32
00118 arma_ostream::modify_stream(std::ostream& o, const std::complex<T>* data, const u32 n_elem)
00119   {
00120   o.unsetf(ios::showbase);
00121   o.unsetf(ios::uppercase);
00122   o.fill(' ');
00123   
00124   o.setf(ios::scientific);
00125   o.setf(ios::showpos);
00126   o.unsetf(ios::fixed);
00127   
00128   u32 cell_width;
00129   
00130   o.precision(3);
00131   cell_width = 2 + 2*(1 + 3 + o.precision() + 5) + 1;
00132 
00133   return cell_width;
00134   }
00135 
00136 
00137 
00138 //! Print an element to the specified stream
00139 template<typename eT>
00140 arma_inline
00141 void
00142 arma_ostream::print_elem(std::ostream& o, const eT& x)
00143   {
00144   o << x;
00145   }
00146 
00147 
00148 
00149 //! Print a complex element to the specified stream
00150 //! EXPERIMENTAL !
00151 template<typename T>
00152 arma_inline
00153 void
00154 arma_ostream::print_elem(std::ostream& o, const std::complex<T>& x)
00155   {
00156   std::ostringstream ss;
00157   ss.flags(o.flags());
00158   //ss.imbue(o.getloc());
00159   ss.precision(o.precision());
00160 
00161   ss << '(' << x.real() << ',' << x.imag() << ')';
00162 
00163   o << ss.str();
00164   }
00165 
00166 
00167 
00168 //! Print a matrix to the specified stream
00169 template<typename eT>
00170 inline
00171 void
00172 arma_ostream::print(std::ostream& o, const Mat<eT>& m, const bool modify)
00173   {
00174   arma_extra_debug_sigprint();
00175   
00176   const arma_ostream_state stream_state(o);
00177 
00178   u32 cell_width;
00179   
00180   if(modify == true)
00181     {
00182     cell_width = arma_ostream::modify_stream(o, m.memptr(), m.n_elem);
00183     }
00184   else
00185     {
00186     cell_width = o.width();  // copy the user's cell width
00187     }
00188   
00189   if(cell_width > 0)
00190     {
00191     for(u32 row=0; row < m.n_rows; ++row)
00192       {
00193       for(u32 col=0; col < m.n_cols; ++col)
00194         {
00195         // the cell width appears to be reset after each element is printed,
00196         // hence we need to restore it
00197         o.width(cell_width);
00198         arma_ostream::print_elem(o, m.at(row,col));
00199         }
00200       
00201       o << '\n';
00202       }
00203     }
00204   else
00205     {
00206     for(u32 row=0; row < m.n_rows; ++row)
00207       {
00208       for(u32 col=0; col < m.n_cols-1; ++col)
00209         {
00210         arma_ostream::print_elem(o, m.at(row,col));
00211         o << ' ';
00212         }
00213       
00214       arma_ostream::print_elem(o, m.at(row, m.n_cols-1));
00215       o << '\n';
00216       }
00217     }
00218   
00219   o.flush();
00220   stream_state.restore(o);
00221   }
00222 
00223 
00224 
00225 //! Print a cube to the specified stream
00226 template<typename eT>
00227 inline
00228 void
00229 arma_ostream::print(std::ostream& o, const Cube<eT>& x, const bool modify)
00230   {
00231   arma_extra_debug_sigprint();
00232   
00233   const arma_ostream_state stream_state(o);
00234 
00235   u32 cell_width;
00236   
00237   if(modify == true)
00238     {
00239     cell_width = arma_ostream::modify_stream(o, x.memptr(), x.n_elem);
00240     }
00241   else
00242     {
00243     cell_width = o.width();
00244     }
00245   
00246   for(u32 slice=0; slice < x.n_slices; ++slice)
00247     {
00248     o << "[cube slice " << slice << ']' << '\n';
00249     o.width(cell_width);
00250     arma_ostream::print(o, x.slice(slice), false);
00251     o << '\n';
00252     }
00253 
00254   stream_state.restore(o);
00255   }
00256 
00257 
00258 
00259 
00260 //! Print a field to the specified stream
00261 //! Assumes type oT can be printed, i.e. oT has std::ostream& operator<< (std::ostream&, const oT&) 
00262 template<typename oT>
00263 inline
00264 void
00265 arma_ostream::print(std::ostream& o, const field<oT>& x)
00266   {
00267   arma_extra_debug_sigprint();
00268   
00269   const arma_ostream_state stream_state(o);
00270 
00271   const std::streamsize cell_width = o.width();
00272 
00273   for(u32 col=0; col<x.n_cols; ++col)
00274     {
00275     o << "[field column " << col << ']' << '\n'; 
00276     for(u32 row=0; row<x.n_rows; ++row)
00277       {
00278       o.width(cell_width);
00279       o << x.at(row,col) << '\n';
00280       }
00281     
00282     o << '\n';
00283     }
00284   
00285   o.flush();
00286   stream_state.restore(o);
00287   }
00288 
00289 
00290 
00291 //! Print a subfield to the specified stream
00292 //! Assumes type oT can be printed, i.e. oT has std::ostream& operator<< (std::ostream&, const oT&) 
00293 template<typename oT>
00294 inline
00295 void
00296 arma_ostream::print(std::ostream& o, const subview_field<oT>& x)
00297   {
00298   arma_extra_debug_sigprint();
00299   
00300   const arma_ostream_state stream_state(o);
00301   
00302   const std::streamsize cell_width = o.width();
00303   
00304   for(u32 col=0; col<x.n_cols; ++col)
00305     {
00306     o << "[subfield column " << col << ']' << '\n'; 
00307     for(u32 row=0; row<x.n_rows; ++row)
00308       {
00309       o.width(cell_width);
00310       o << x.at(row,col) << '\n';
00311       }
00312     
00313     o << '\n';
00314     }
00315   
00316   o.flush();
00317   stream_state.restore(o);
00318   }
00319 
00320 
00321 
00322 //! @}