00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_COLUMNIFY_H 00024 #define O2SCL_COLUMNIFY_H 00025 00026 /** \file columnify.h 00027 \brief Functions to create output in columns 00028 */ 00029 00030 #include <iostream> 00031 #include <string> 00032 #include <vector> 00033 #include <o2scl/misc.h> 00034 #include <o2scl/array.h> 00035 00036 #ifndef DOXYGENP 00037 namespace o2scl { 00038 #endif 00039 00040 /** 00041 \brief Create nicely formatted columns from a table of strings 00042 00043 This is a brute-force approach of order \f$ \mathrm{ncols} \times 00044 \mathrm{nrows} \f$. 00045 00046 \todo Move the screenify() functionality from misc.h into this class? 00047 */ 00048 class columnify { 00049 00050 public: 00051 00052 columnify() { 00053 } 00054 00055 /// Align the left-hand sides 00056 static const int align_left=1; 00057 /// Align the right-hand sides 00058 static const int align_right=2; 00059 /// Center, slightly to the left if spacing is uneven 00060 static const int align_lmid=3; 00061 /// Center, slightly to the right if spacing is uneven 00062 static const int align_rmid=4; 00063 /// Align with decimal points 00064 static const int align_dp=5; 00065 /** \brief Align negative numbers to the left and use a space for 00066 positive numbers 00067 */ 00068 static const int align_lnum=6; 00069 00070 /** \brief Take \c table and create a new object \c ctable with 00071 appropriately formatted columns 00072 00073 The table of strings should be stored in \c table in 00074 "column-major" order, so that \c table has the interpretation 00075 of a set of columns to be aligned. Before calling align(), \c 00076 ctable should be allocated so that at least the first \c nrows 00077 entries can be assigned, and \c align_spec should contain \c 00078 ncols entries specifying the style of alignment for each 00079 column. 00080 */ 00081 template<class mat_string_t, class vec_string_t, class vec_int_t> 00082 int align(const mat_string_t &table, size_t ncols, size_t nrows, 00083 vec_string_t &ctable, vec_int_t &align_spec) { 00084 00085 // Make space for the size information 00086 size_t *csizes=new size_t[ncols], *csizes2=new size_t[ncols]; 00087 for(size_t i=0;i<ncols;i++) { 00088 csizes[i]=0; 00089 csizes2[i]=0; 00090 } 00091 00092 // Compute the sizes of all the entries in all of the columns so 00093 // we know how many spaces to add 00094 for(size_t i=0;i<ncols;i++) { 00095 for(size_t j=0;j<nrows;j++) { 00096 if (align_spec[i]==align_dp) { 00097 size_t loc=table[i][j].find('.'); 00098 std::string left, right; 00099 if (loc!=std::string::npos) { 00100 left=table[i][j].substr(0,loc+1); 00101 right=table[i][j].substr(loc+1, 00102 table[i][j].length()-loc-1); 00103 } else { 00104 left=table[i][j]+' '; 00105 right=""; 00106 } 00107 if (left.length()>csizes[i]) csizes[i]=left.length(); 00108 if (right.length()>csizes2[i]) csizes2[i]=right.length(); 00109 } else { 00110 if (table[i][j].length()>csizes[i]) csizes[i]=table[i][j].length(); 00111 } 00112 } 00113 } 00114 00115 // Go through row by row, adding enough spaces to make one string 00116 // per row 00117 for(size_t j=0;j<nrows;j++) { 00118 00119 std::string tmp=""; 00120 00121 for(size_t i=0;i<ncols;i++) { 00122 00123 // Handle each alignment case separately 00124 if (align_spec[i]==align_right) { 00125 00126 for(size_t k=table[i][j].length();k<csizes[i];k++) { 00127 tmp+=' '; 00128 } 00129 tmp+=table[i][j]; 00130 if (i!=ncols-1) tmp+=' '; 00131 00132 } else if (align_spec[i]==align_left) { 00133 00134 tmp+=table[i][j]; 00135 for(size_t k=table[i][j].length();k<csizes[i];k++) { 00136 tmp+=' '; 00137 } 00138 if (i!=ncols-1) tmp+=' '; 00139 00140 } else if (align_spec[i]==align_lmid) { 00141 00142 size_t le=(csizes[i]-table[i][j].length())/2; 00143 size_t ri=csizes[i]-table[i][j].length()-le; 00144 for(size_t k=0;k<le;k++) tmp+=' '; 00145 tmp+=table[i][j]; 00146 for(size_t k=0;k<ri;k++) tmp+=' '; 00147 if (i!=ncols-1) tmp+=' '; 00148 00149 } else if (align_spec[i]==align_rmid) { 00150 00151 size_t ri=(csizes[i]-table[i][j].length())/2; 00152 size_t le=csizes[i]-table[i][j].length()-ri; 00153 for(size_t k=0;k<le;k++) tmp+=' '; 00154 tmp+=table[i][j]; 00155 for(size_t k=0;k<ri;k++) tmp+=' '; 00156 if (i!=ncols-1) tmp+=' '; 00157 00158 } else if (align_spec[i]==align_dp) { 00159 00160 size_t loc=table[i][j].find('.'); 00161 std::string left, right; 00162 if (loc!=std::string::npos) { 00163 left=table[i][j].substr(0,loc+1); 00164 right=table[i][j].substr(loc+1, 00165 table[i][j].length()-loc-1); 00166 } else { 00167 left=table[i][j]+' '; 00168 right=""; 00169 } 00170 00171 for(size_t k=left.length();k<csizes[i];k++) tmp+=' '; 00172 tmp+=left; 00173 tmp+=right; 00174 for(size_t k=right.length();k<csizes2[i];k++) tmp+=' '; 00175 if (i!=ncols-1) tmp+=' '; 00176 00177 } else if (align_spec[i]==align_lnum) { 00178 00179 if (table[i][j].length()==csizes[i]) { 00180 tmp+=table[i][j]; 00181 } else { 00182 if (table[i][j][0]>='0' && table[i][j][0]<='9') { 00183 tmp+=' '; 00184 tmp+=table[i][j]; 00185 for(size_t k=table[i][j].length();k<csizes[i]-1;k++) { 00186 tmp+=' '; 00187 } 00188 } else { 00189 tmp+=table[i][j]; 00190 for(size_t k=table[i][j].length();k<csizes[i];k++) { 00191 tmp+=' '; 00192 } 00193 } 00194 } 00195 if (i!=ncols-1) tmp+=' '; 00196 } 00197 00198 } 00199 00200 // Add the row to the user-specified array and go to the next row 00201 ctable[j]=tmp; 00202 00203 } 00204 00205 // Free the memory assocated with the column widths 00206 delete[] csizes; 00207 delete[] csizes2; 00208 00209 return 0; 00210 } 00211 00212 }; 00213 00214 /** 00215 \brief A operator for naive matrix output 00216 00217 The type \c mat_t can be any matrix type which allows 00218 individual element access using \c operator()(size_t,size_t). 00219 00220 This outputs all of the matrix elements using output settings 00221 specified by \c os. The alignment performed by \ref columnify 00222 using columnify::align_dp, i.e. the numbers are aligned by 00223 their decimal points. If the numbers have no decimal points, 00224 then the decimal point is assumed to be to the right of the 00225 last character in the string represetation of the number. 00226 */ 00227 template<class mat_t> int matrix_out_paren(std::ostream &os, mat_t &A, 00228 size_t nrows, size_t ncols) { 00229 00230 columnify co; 00231 std::string **stab; 00232 stab=o2scl::new_2d_array<std::string>(ncols,nrows); 00233 std::vector<std::string> ctable(nrows); 00234 std::vector<int> alig(ncols); 00235 00236 for(size_t j=0;j<ncols;j++) { 00237 alig[j]=columnify::align_dp; 00238 for(size_t i=0;i<nrows;i++) { 00239 stab[j][i]=dtos(A(i,j),os); 00240 } 00241 } 00242 co.align(stab,ncols,nrows,ctable,alig); 00243 for(size_t i=0;i<nrows;i++) { 00244 os << ctable[i] << std::endl; 00245 } 00246 00247 o2scl::delete_2d_array(stab,ncols); 00248 00249 return 0; 00250 } 00251 00252 /** 00253 \brief A operator for simple complex matrix output 00254 */ 00255 template<class mat_t> int matrix_cx_out_paren(std::ostream &os, mat_t &A, 00256 size_t nrows, size_t ncols) { 00257 00258 columnify co; 00259 std::string **stab; 00260 stab=o2scl::new_2d_array<std::string>(ncols,nrows); 00261 std::vector<std::string> ctable(nrows); 00262 std::vector<int> alig(ncols); 00263 00264 for(size_t j=0;j<ncols;j++) { 00265 alig[j]=columnify::align_left; 00266 for(size_t i=0;i<nrows;i++) { 00267 stab[j][i]=((std::string)"(")+dtos(A(i,j).dat[0],os)+ 00268 ((std::string)",")+dtos(A(i,j).dat[1],os)+((std::string)")"); 00269 } 00270 } 00271 co.align(stab,ncols,nrows,ctable,alig); 00272 for(size_t i=0;i<nrows;i++) { 00273 os << ctable[i] << std::endl; 00274 } 00275 00276 o2scl::delete_2d_array(stab,ncols); 00277 00278 return 0; 00279 } 00280 00281 /** 00282 \brief A operator for simple 2-d array output 00283 00284 The type \c mat_t can be any 2d-array type which allows 00285 individual element access using \c [size_t][size_t] 00286 00287 This outputs all of the matrix elements using output settings 00288 specified by \c os. The alignment performed by \ref columnify 00289 using columnify::align_dp, i.e. the numbers are aligned by 00290 their decimal points. If the numbers have no decimal points, 00291 then the decimal point is assumed to be to the right of the 00292 last character in the string represetation of the number. 00293 00294 \todo If all of the matrix elements are positive integers 00295 and scientific mode is not set, then we can avoid printing 00296 the extra spaces. 00297 */ 00298 template<class mat_t> int matrix_out(std::ostream &os, mat_t &A, 00299 size_t nrows, size_t ncols) { 00300 00301 columnify co; 00302 std::string **stab; 00303 stab=o2scl::new_2d_array<std::string>(ncols,nrows); 00304 std::vector<std::string> ctable(nrows); 00305 std::vector<int> alig(ncols); 00306 00307 for(size_t j=0;j<ncols;j++) { 00308 alig[j]=columnify::align_dp; 00309 for(size_t i=0;i<nrows;i++) { 00310 stab[j][i]=dtos(A[i][j],os); 00311 } 00312 } 00313 co.align(stab,ncols,nrows,ctable,alig); 00314 for(size_t i=0;i<nrows;i++) { 00315 os << ctable[i] << std::endl; 00316 } 00317 00318 o2scl::delete_2d_array(stab,ncols); 00319 00320 return 0; 00321 } 00322 00323 #ifndef DOXYGENP 00324 } 00325 #endif 00326 00327 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page