dune-fem  2.8-git
latextablewriter.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_LATEXTABLEWRITER_HH
2 #define DUNE_FEM_LATEXTABLEWRITER_HH
3 
4 #include <cmath>
5 #include <fstream>
6 #include <iomanip>
7 #include <limits>
8 #include <sstream>
9 #include <tuple>
10 #include <vector>
11 
12 #include <dune/common/exceptions.hh>
13 
14 namespace Dune
15 {
16 
17  namespace Fem
18  {
19 
20  // NoDataException
21  // ---------------
22 
23  struct NoDataException {};
24 
25 
26 
27  // AbstractColumnWriter
28  // --------------------
29 
37  template< class DataTuple >
39  {
42 
44  virtual ~AbstractColumnWriter () {}
45 
47  virtual Alignment alignment () const { return AlignCenter; }
49  virtual std::string entry ( const DataTuple & ) const = 0;
51  virtual std::string header () const = 0;
52  };
53 
54 
55 
56  // TupleDataSource
57  // ---------------
58 
59  template< int N >
61  {
62  template< class DataTuple >
63  struct Value { typedef typename std::tuple_element< N, DataTuple >::type Type; };
64 
65  template< class DataTuple >
66  typename Value< DataTuple >::Type get ( const DataTuple &data ) const
67  throw ()
68  {
69  return std::get< N >( data );
70  }
71  };
72 
73 
74 
75  // ArrayDataSource
76  // ---------------
77 
78  template< class DataSource >
80  {
81  template< class DataTuple >
82  struct Value
83  {
84  typedef typename DataSource::template Value< DataTuple >::Type::value_type Type;
85  };
86 
87  ArrayDataSource ( const int index, const DataSource &source = DataSource() )
88  : index_( index ), source_( source )
89  {}
90 
91  template< class DataTuple >
92  typename Value< DataTuple >::Type get ( const DataTuple &data ) const
93  throw ()
94  {
95  return source_.get( data )[ index_ ];
96  }
97 
98  private:
99  int index_;
100  DataSource source_;
101  };
102 
103 
104 
105  // EOCDataSource
106  // -------------
107 
108  template< class WidthDataSource, class ErrorDataSource >
110  {
111  template< class DataTuple >
112  struct Value
113  {
114  typedef double Type;
115  };
116 
117  explicit EOCDataSource ( const WidthDataSource &widthSource = WidthDataSource(),
118  const ErrorDataSource &errorSource = ErrorDataSource() )
119  : widthSource_( widthSource ),
120  errorSource_( errorSource ),
121  hOld_( std::numeric_limits< double >::infinity() )
122  {}
123 
124  explicit EOCDataSource ( const ErrorDataSource &errorSource )
125  : errorSource_( errorSource ),
126  hOld_( std::numeric_limits< double >::infinity() )
127  {}
128 
129  template< class DataTuple >
130  typename Value< DataTuple >::Type get ( const DataTuple &data ) const
131  {
132  double h = widthSource_.get( data );
133  double e = errorSource_.get( data );
134  std::swap( h, hOld_ );
135  std::swap( e, eOld_ );
136  if( h < std::numeric_limits< double >::infinity() )
137  return std::log( eOld_ / e ) / std::log( hOld_ / h );
138  else
139  throw NoDataException();
140  }
141 
142  private:
143  WidthDataSource widthSource_;
144  ErrorDataSource errorSource_;
145  mutable double hOld_;
146  mutable double eOld_;
147  };
148 
149 
150 
151  // NumberColumnWriter
152  // ------------------
153 
163  template< class DataTuple, class DataSource >
165  : public AbstractColumnWriter< DataTuple >
166  {
168 
169  public:
175  explicit NumberColumnWriter ( const std::string &header, const int decimals = 6,
176  const DataSource &source = DataSource() )
177  : header_( header ),
178  decimals_( decimals ),
179  source_( source )
180  {}
181 
187  NumberColumnWriter ( const std::string &header, const DataSource &source )
188  : header_( header ),
189  decimals_( 6 ),
190  source_( source )
191  {}
192 
194  typename BaseType::Alignment alignment () const
195  {
196  return BaseType::AlignRight;
197  }
198 
204  std::string entry ( const DataTuple &data ) const
205  {
206  return toString( source_.get( data ) );
207  }
208 
210  std::string header () const { return header_; }
211 
212  protected:
214  template< class Number >
215  std::string toString ( const Number &number ) const
216  {
217  std::ostringstream s;
218  s << std::fixed << std::setprecision( decimals_ );
219  s << "$" << number << "$";
220  return s.str();
221  }
222 
223  private:
224  std::string header_;
225  int decimals_;
226  DataSource source_;
227  };
228 
229 
230 
231  // LatexTableWriter
232  // ----------------
233 
240  template< class DataTuple >
242  {
246  typedef std::vector< const ColumnWriterType * > ColumnWriterVectorType;
247 
252  LatexTableWriter ( const std::string &filename, const ColumnWriterVectorType &columnWriter );
257 
259  void writeRow ( const DataTuple &data );
261  void writeSeparator ();
262 
263  private:
265  typedef typename ColumnWriterVectorType::const_iterator ColumnWriterIteratorType;
266 
268  void cleanUp ();
269 
271  std::string preamble () const;
273  std::string header () const;
274 
275  ColumnWriterVectorType columnWriters_;
276  std::ofstream out_;
277  };
278 
279 
280 
281  // Implementation of LatexTableWriter
282  // ----------------------------------
283 
284  template< class DataTuple >
286  ::LatexTableWriter ( const std::string &filename, const ColumnWriterVectorType &columnWriters )
287  : columnWriters_( columnWriters ),
288  out_( filename.c_str() )
289  {
290  if( !out_ )
291  {
292  cleanUp();
293  DUNE_THROW( IOError, "Unable to open '" << filename << "'." );
294  }
295  out_ << "\\begin{tabular}{" << preamble() << "}" << std::endl;
296  writeSeparator();
297  out_ << header() << " \\\\"<< std::endl;
298  writeSeparator();
299  }
300 
301 
302  template< class DataTuple >
304  {
305  writeSeparator();
306  out_ << "\\end{tabular}" << std::endl;
307  cleanUp();
308  }
309 
310 
311  template< class DataTuple >
312  inline void LatexTableWriter< DataTuple >::writeRow ( const DataTuple &data )
313  {
314  std::string separator = "";
315  const ColumnWriterIteratorType end = columnWriters_.end();
316  for( ColumnWriterIteratorType it = columnWriters_.begin(); it != end; ++it )
317  {
318  out_ << separator;
319  separator = " & ";
320  if( *it )
321  {
322  try
323  {
324  out_ << (*it)->entry( data );
325  }
326  catch( const NoDataException & )
327  {
328  out_ << "\\multicolumn{1}{|c|}{---}";
329  }
330  }
331  }
332  out_ << " \\\\" << std::endl;
333  }
334 
335 
336  template< class DataTuple >
338  {
339  int b = 0, e = 0;
340 
341  const ColumnWriterIteratorType end = columnWriters_.end();
342  for( ColumnWriterIteratorType it = columnWriters_.begin(); it != end; ++it, ++e )
343  {
344  if( !(*it) )
345  {
346  if( b < e )
347  out_ << "\\cline{" << (b+1) << "-" << e << "}";
348  b = e+1;
349  }
350  }
351  if( b < e )
352  out_ << "\\cline{" << (b+1) << "-" << e << "}";
353  out_ << std::endl;
354  }
355 
356 
357  template< class DataTuple >
359  {
360  const ColumnWriterIteratorType end = columnWriters_.end();
361  for( ColumnWriterIteratorType it = columnWriters_.begin(); it != end; ++it )
362  {
363  if( *it )
364  delete( *it );
365  }
366  }
367 
368 
369  template< class DataTuple >
370  inline std::string LatexTableWriter< DataTuple >::header () const
371  {
372  std::string header, separator;
373  const ColumnWriterIteratorType end = columnWriters_.end();
374  for( ColumnWriterIteratorType it = columnWriters_.begin(); it != end; ++it )
375  {
376  header += separator;
377  separator = " & ";
378  if( *it )
379  header += "\\multicolumn{1}{|c|}{" + (*it)->header() + "}";
380  }
381  return header;
382  }
383 
384 
385  template< class DataTuple >
386  inline std::string LatexTableWriter< DataTuple >::preamble () const
387  {
388  const char alignment[] = { 'l', 'c', 'r' };
389 
390  std::string preamble( "|" );
391  const ColumnWriterIteratorType end = columnWriters_.end();
392  for( ColumnWriterIteratorType it = columnWriters_.begin(); it != end; ++it )
393  {
394  if( *it )
395  preamble += alignment[ (*it)->alignment() ];
396  else
397  preamble += "@{}p{0.2em}@{}";
398  preamble += "|";
399  }
400  return preamble;
401  }
402 
403  } // namespace Fem
404 
405 } // namespace Dune
406 
407 #endif // #ifndef DUNE_FEM_LATEXTABLEWRITER_HH
Definition: bindguard.hh:11
static double log(const Double &v)
Definition: double.hh:876
Definition: latextablewriter.hh:23
Class representing column writer in general.
Definition: latextablewriter.hh:39
Alignment
The alignment for the data in this column.
Definition: latextablewriter.hh:41
@ AlignCenter
Definition: latextablewriter.hh:41
@ AlignRight
Definition: latextablewriter.hh:41
@ AlignLeft
Definition: latextablewriter.hh:41
virtual std::string header() const =0
virtual std::string entry(const DataTuple &) const =0
virtual ~AbstractColumnWriter()
Destructor.
Definition: latextablewriter.hh:44
virtual Alignment alignment() const
Definition: latextablewriter.hh:47
Definition: latextablewriter.hh:61
Value< DataTuple >::Type get(const DataTuple &data) const
Definition: latextablewriter.hh:66
Definition: latextablewriter.hh:63
std::tuple_element< N, DataTuple >::type Type
Definition: latextablewriter.hh:63
Definition: latextablewriter.hh:80
Value< DataTuple >::Type get(const DataTuple &data) const
Definition: latextablewriter.hh:92
ArrayDataSource(const int index, const DataSource &source=DataSource())
Definition: latextablewriter.hh:87
Definition: latextablewriter.hh:83
DataSource::template Value< DataTuple >::Type::value_type Type
Definition: latextablewriter.hh:84
Definition: latextablewriter.hh:110
EOCDataSource(const ErrorDataSource &errorSource)
Definition: latextablewriter.hh:124
Value< DataTuple >::Type get(const DataTuple &data) const
Definition: latextablewriter.hh:130
EOCDataSource(const WidthDataSource &widthSource=WidthDataSource(), const ErrorDataSource &errorSource=ErrorDataSource())
Definition: latextablewriter.hh:117
Definition: latextablewriter.hh:113
double Type
Definition: latextablewriter.hh:114
gets the N th element of a provided tuple assuming its a number
Definition: latextablewriter.hh:166
BaseType::Alignment alignment() const
set the aligment of the entries for this column in the latex table
Definition: latextablewriter.hh:194
NumberColumnWriter(const std::string &header, const DataSource &source)
Constructor of NumberColumnWriter where decimal default to 6.
Definition: latextablewriter.hh:187
std::string header() const
return Column titles in latex row format
Definition: latextablewriter.hh:210
std::string toString(const Number &number) const
converts number to std::string
Definition: latextablewriter.hh:215
std::string entry(const DataTuple &data) const
returns N the element from data tuple
Definition: latextablewriter.hh:204
NumberColumnWriter(const std::string &header, const int decimals=6, const DataSource &source=DataSource())
Definition: latextablewriter.hh:175
writes latex tables based on user-defined row structure
Definition: latextablewriter.hh:242
void writeRow(const DataTuple &data)
Write row to the table.
Definition: latextablewriter.hh:312
void writeSeparator()
Adds extra space between two columns in the latex table.
Definition: latextablewriter.hh:337
std::vector< const ColumnWriterType * > ColumnWriterVectorType
Abstract column vector type.
Definition: latextablewriter.hh:246
LatexTableWriter(const std::string &filename, const ColumnWriterVectorType &columnWriter)
Definition: latextablewriter.hh:286
~LatexTableWriter()
writes "\end{tabular}" to the latex file and removes column vector
Definition: latextablewriter.hh:303
AbstractColumnWriter< DataTuple > ColumnWriterType
Abstract column type.
Definition: latextablewriter.hh:244