table.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2020, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 #ifndef O2SCL_TABLE_H
24 #define O2SCL_TABLE_H
25 
26 /** \file table.h
27  \brief File defining \ref o2scl::table
28 */
29 
30 #include <iostream>
31 #include <fstream>
32 #include <string>
33 #include <cmath>
34 #include <sstream>
35 #include <map>
36 
37 #include <boost/numeric/ublas/vector.hpp>
38 #include <boost/numeric/ublas/matrix.hpp>
39 
40 #include <o2scl/misc.h>
41 #include <o2scl/interp.h>
42 
43 #include <o2scl/shunting_yard.h>
44 
45 #ifndef DOXYGEN_NO_O2NS
46 
47 namespace o2scl {
48  // Forward definition of the table class for HDF5 I/O
49  template<class vec_t> class table;
50  // Forward definition of matrix_view_table to extend
51  // friendship
52  template<class vec_t> class matrix_view_table;
53  // Forward definition of matrix_view_table_transpose to extend
54  // friendship
55  template<class vec_t> class matrix_view_table_transpose;
56 }
57 
58 // Forward definition of HDF5 I/O to extend friendship in table
59 namespace o2scl_hdf {
60  // Forward definition of hdf_file for function template argument below
61  class hdf_file;
62  // Forward definition of HDF5 I/O functions to extend friendship
63  template<class vec_t>
64  void hdf_input(hdf_file &hf, o2scl::table<vec_t> &t, std::string name);
65  void hdf_output(hdf_file &hf,
66  o2scl::table<std::vector<double> > &t,
67  std::string name);
68  template<class vec_t>
70  void hdf_output_data(hdf_file &hf,
71  o2scl::table<std::vector<double> > &t);
72 
73 }
74 
75 #endif
76 
77 #ifndef DOXYGEN_NO_O2NS
78 namespace o2scl {
79 #endif
80 
81  /** \brief Data \table class
82 
83  \b Summary \n
84 
85  A class to contain and manipulate several equally-sized columns
86  of data. The purpose of this class is to provide a structure
87  which allows one to refer to the columns using a name
88  represented by a string. Thus for a table object named \c t with
89  3 columns (named "colx", "coly" and "colz") and three rows, one
90  could do the following:
91  \include table_doc1.cpp
92  Note that the rows are numbered starting with 0 instead of
93  starting with 1.
94  To output all the rows of entire column, one can use
95  \include table_doc2.cpp
96  To output all the columns of an entire row (in the following
97  example it is the second row), labeled by their column name, one
98  can use:
99  \include table_doc3.cpp
100 
101  Methods are provided for interpolating columns, sorting
102  columns, finding data points, and several other manipulations
103  of the data.
104 
105  <B> Lookup, differentiation, integration, and
106  interpolation </b> \n
107 
108  Lookup, differentiation, integration, and interpolation are
109  automatically implemented using splines from the class \ref
110  interp_vec. A caching mechanism is implemented so that
111  successive interpolations, derivative evaluations or
112  integrations over the same two columns are fast.
113 
114  <B> Sorting </b>\n
115 
116  The columns are automatically sorted by name for speed, the
117  results can be accessed from \ref get_sorted_name(). Individual
118  columns can be sorted (\ref sort_column() ), or the entire table
119  can be sorted by one column (\ref sort_table() ).
120 
121  <B> Data representation </b> \n
122 
123  Each individual column is just a vector object.
124  The columns can be referred to in one of two ways:
125  - A numerical index from 0 to C-1 (where C is the number of
126  columns). For example, data can be accessed through \ref
127  table::get() and \ref table::set(size_t c, size_t r,
128  double val), or the overloaded [] operator, <tt>table[c][r]</tt>.
129  - A name of the column which is a string.
130  For example, data can be accessed with table::get(string cname,
131  int r) and table::set(string cname, int r, double val).
132 
133  The columns are organized in a both a <map> and a <vector>
134  structure so that finding a column by its index, using either of
135  \code
136  std::string table::get_column_name(size_t index);
137  ubvector &table::operator[](size_t index);
138  \endcode
139  takes only constant time, and finding a column by its name
140  using either of
141  \code
142  size_t lookup_column(std::string name) const;
143  const ubvector &get_column(std::string col) const;
144  \endcode
145  is O(log(C)). Insertion of a column ( \ref new_column() ) is
146  O(log(C)), but deletion ( \ref delete_column() ) is O(C). Adding
147  a row of data can be either O(1) or O(C), but row insertion and
148  deletion is slow, since the all of the rows must be shifted
149  accordingly.
150 
151  Because of the structure, this class is not suitable for the
152  matrix manipulation.
153 
154  <b>Vector types</b> \n
155 
156  The type <tt>vec_t</tt> can be any vector type with
157  <tt>operator[]</tt>, <tt>size()</tt> and <tt>resize()</tt>
158  methods. HDF5 I/O with vector types other than
159  <tt>std::vector<double> </tt> requires a copy. See the
160  the discussion in the sections \ref tensor_subsect
161  and \ref vec_io_cont_subsect of the user's guide for
162  more details.
163 
164  <b>Thread-safety</b> \n
165 
166  Generally, the member functions are only thread-safe
167  if they are <tt>const</tt> .
168 
169  \b I/O \b and \b command-line \b manipulation \n
170 
171  When data from an object of type \ref table is output to a file
172  through the <tt>hdf_output() function</tt> in \ref o2scl_hdf,
173  the table can be manipulated on the command-line through the \c
174  acol utility (see \ref acol_section).
175 
176  There is an example for the usage of this class given
177  in <tt>examples/ex_table.cpp</tt>.
178 
179  \future
180  - Create a sort_column_names() or a function to
181  arbitrarily rearrange the columns
182  - The present structure, \c
183  std::map<std::string,col,string_comp> atree and \c
184  std::vector<aiter> alist; could be replaced with \c
185  std::vector<col> list and \c std::map<std::string,int> tree
186  where the map just stores the index of the the column in the
187  list.
188  - Rewrite check_synchro into a full is_valid()-like
189  sanity check
190  */
191  template<class vec_t=std::vector<double> > class table {
192 
193  public:
194 
195  /// \name Constructors, destructors
196  //@{
197  /** \brief Create a new table with space for nlines<=cmaxlines.
198  */
199  table(size_t cmaxlines=0) {
200  nlines=0;
201  intp_set=false;
202  maxlines=cmaxlines;
204  }
205 
206  /** \brief Table destructor
207  */
208  virtual ~table() {
209  if (intp_set==true) {
210  delete si;
211  }
212  }
213 
214  /// Copy constructor
215  table(const table &t) {
216 
217  // Copy constants
218  constants=t.constants;
219 
220  // Copy interpolation type
221  itype=t.itype;
222 
223  // Copy the columns and data
224  nlines=t.get_nlines();
226 
227  for(size_t i=0;i<t.get_ncolumns();i++) {
228 
229  // Column name
230  std::string cname=t.get_column_name(i);
231 
232  // Insert column into tree
233  col s;
234  s.dat.resize(nlines);
235  s.index=atree.size();
236  atree.insert(make_pair(cname,s));
237 
238  // Insert in iterator index
239  aiter it=atree.find(cname);
240  alist.push_back(it);
241 
242  // Fill the data
243  for(size_t j=0;j<t.get_nlines();j++) {
244  it->second.dat[j]=t.get(cname,j);
245  }
246 
247  }
248 
249  intp_set=false;
250 
251  is_valid();
252 
253  return;
254  }
255 
256  /// Copy constructor
257  table &operator=(const table &t) {
258 
259  if (this!=&t) {
260 
261  clear();
262 
263  // Copy constants
264  constants=t.constants;
265 
266  // Copy the columns and data
267  nlines=t.get_nlines();
269 
270  // Copy interpolation type
271  itype=t.itype;
272 
273  for(size_t i=0;i<t.get_ncolumns();i++) {
274 
275  // Column name
276  std::string cname=t.get_column_name(i);
277 
278  // Insert column into tree
279  col s;
280  s.dat.resize(nlines);
281  s.index=atree.size();
282  atree.insert(make_pair(cname,s));
283 
284  // Insert in iterator index
285  aiter it=atree.find(cname);
286  alist.push_back(it);
287 
288  // Fill the data
289  for(size_t j=0;j<t.get_nlines();j++) {
290  it->second.dat[j]=t.get(cname,j);
291  }
292 
293  }
294 
295  if (intp_set) {
296  intp_set=false;
297  delete si;
298  }
299 
300  }
301 
302  is_valid();
303 
304  return *this;
305  }
306  //@}
307 
308  // --------------------------------------------------------
309  /** \name Basic get and set methods */
310  //@{
311  /** \brief Set row \c row of column named \c col to value \c val .
312  \f$ {\cal O}(\log(C)) \f$
313 
314  This function calls the error handler if the row is beyond
315  the end of the table or if the specified column is not found.
316  */
317  void set(std::string scol, size_t row, double val) {
318 
319  if (row>=nlines) {
320  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
321  " beyond end of table (nlines="+o2scl::szttos(nlines)+") in "+
322  "table::set(string,size_t,double).";
323  O2SCL_ERR(str.c_str(),exc_einval);
324  return;
325  }
326 
327  aiter it=atree.find(scol);
328  if (it==atree.end()) {
329  O2SCL_ERR((((std::string)"Column '")+scol+
330  "' not found in table::set(string,size_t,double).").c_str(),
331  exc_enotfound);
332  return;
333  }
334 
335  if ((intp_colx==scol || intp_coly==scol) && intp_set==true) {
336  delete si;
337  intp_set=false;
338  }
339 
340 #if !O2SCL_NO_RANGE_CHECK
341  if (row>=it->second.dat.size()) {
342  O2SCL_ERR("Vector size failure in table::set(string,size_t,double).",
343  exc_esanity);
344  }
345 #endif
346  it->second.dat[row]=val;
347 
348  return;
349  }
350 
351  /** \brief Set row \c row of column number \c icol to value \c val .
352  \f$ {\cal O}(1) \f$
353  */
354  void set(size_t icol, size_t row, double val) {
355 
356  if (row>=nlines) {
357  O2SCL_ERR2("Specified row beyond end of table in ",
358  "table::set(size_t,size_t,double).",exc_einval);
359  return;
360  }
361 
362  if (icol>=atree.size()) {
363  std::string err=((std::string)"Column index ")+szttos(icol)+
364  ">="+szttos(atree.size())+", in table::set(size_t,size_t,double).";
365  O2SCL_ERR(err.c_str(),exc_einval);
366  }
367 
368  std::string scol=get_column_name(icol);
369  if ((intp_colx==scol || intp_coly==scol) && intp_set==true) {
370  delete si;
371  intp_set=false;
372  }
373 
374 #if !O2SCL_NO_RANGE_CHECK
375  if (row>=alist[icol]->second.dat.size()) {
376  O2SCL_ERR("Vector size failure in table::set(size_t,size_t,double).",
377  exc_esanity);
378  }
379 #endif
380  alist[icol]->second.dat[row]=val;
381  return;
382  }
383 
384  /** \brief Set an entire row of data
385 
386  This function goes through \c v copying data until it runs out
387  of columns in the table or it runs out of entries in \c v,
388  whichever comes first.
389 
390  The type <tt>size_vec_t</tt> must be a type which has a
391  <tt>size()</tt> method.
392  */
393  template<class size_vec_t> void set_row(size_t row, size_vec_t &v) {
394  if (row>=get_nlines()) {
395  std::string err=((std::string)"Row out of range, ")+
396  szttos(row)+">="+szttos(get_nlines())+", in table::set_row().";
397  O2SCL_ERR(err.c_str(),exc_einval);
398  }
399  for(size_t i=0;i<get_ncolumns() && i<v.size();i++) {
400  alist[i]->second.dat[row]=v[i];
401  }
402  return;
403  }
404 
405  /** \brief Get value from row \c row of column named \c col.
406  \f$ {\cal O}(\log(C)) \f$
407  */
408  double get(std::string scol, size_t row) const {
409  double tmp;
410  aciter it=atree.find(scol);
411  if (it==atree.end()) {
412  O2SCL_ERR((((std::string)"Column '")+scol+
413  "' not found in table::get(string,size_t).").c_str(),
414  exc_enotfound);
415  return 0.0;
416  } else {
417  if (row>=nlines) {
418  std::string err=((std::string)"Row out of range, ")+
419  szttos(row)+">="+szttos(nlines)+", in table::get(string,size_t).";
420  O2SCL_ERR(err.c_str(),exc_einval);
421  }
422 #if !O2SCL_NO_RANGE_CHECK
423  if (row>=it->second.dat.size()) {
424  O2SCL_ERR("Vector size failure in table::get().",
425  exc_esanity);
426  }
427 #endif
428  tmp=it->second.dat[row];
429  }
430  return tmp;
431  }
432 
433  /** \brief Get value from row \c row of column number \c icol.
434  \f$ {\cal O}(1) \f$
435  */
436  double get(size_t icol, size_t row) const {
437  if (icol>=atree.size()) {
438  std::string err=((std::string)"Column out of range, ")+
439  szttos(icol)+">="+szttos(atree.size())+", in table::get(size_t,size_t).";
440  O2SCL_ERR(err.c_str(),exc_einval);
441  }
442  if (row>=nlines) {
443  std::string err=((std::string)"Row out of range, ")+
444  szttos(row)+">="+szttos(nlines)+", in table::get(size_t,size_t).";
445  O2SCL_ERR(err.c_str(),exc_einval);
446  }
447  return alist[icol]->second.dat[row];
448  }
449 
450  /** \brief Return the number of columns
451  */
452  size_t get_ncolumns() const {return atree.size();};
453  //@}
454 
455  // --------------------------------------------------------
456  /** \name Manipulate current and maximum number of rows */
457  //@{
458  /** \brief Return the number of lines
459  */
460  size_t get_nlines() const {return nlines;};
461 
462  /** \brief Set the number of lines
463 
464  This function is stingy about increasing the table memory
465  space and will only increase it enough to fit \c il lines.
466  Using it in succession to slowly increase the number of lines
467  in the table is likely to be inefficient compared to \ref
468  set_nlines_auto() in this case.
469  */
470  void set_nlines(size_t il) {
471 
472  // Try to increase the number of lines
473  if (il>maxlines) {
475  }
476 
477  // Now that maxlines is large enough, set the number of lines
478  nlines=il;
479 
480  // Reset the interpolation object for future interpolations
481  if (intp_set) {
482  intp_set=false;
483  delete si;
484  }
485 
486  return;
487  }
488 
489  /** \brief Return the maximum number of lines before a reallocation
490  is required
491  */
492  size_t get_maxlines() {return maxlines; };
493 
494  /** \brief Returns a copy of the row with value \c val in column
495  \c col. \f$ {\cal O}(R C) \f$
496 
497  This function searches the entire table for the row which has
498  the entry in column \c col which is closest to the value \c
499  val, and copies that row to the vector \c row.
500 
501  If the object \c row previously contains any data, it will be
502  lost.
503 
504  The type <tt>resize_vec_t</tt> must be a type which has
505  <tt>size()</tt> and <tt>resize()</tt> methods.
506  */
507  template<class resize_vec_t>
508  void get_row(std::string scol, double val, resize_vec_t &row) const {
509 
510  int irow=lookup(scol,val);
511  if (irow==exc_enotfound) {
512  O2SCL_ERR((((std::string)"Column '")+scol+"' not found in "+
513  "table::get_row(string,double,vec_t) const.").c_str(),
514  exc_enotfound);
515  return;
516  }
517  get_row(irow,row);
518  return;
519  }
520 
521  /** \brief Returns a copy of row number \c irow. \f$ {\cal O}(C) \f$
522 
523  This function returns a copy of row with index \c irow,
524  where \c irow ranges from 0 to <tt>get_nlines()-1</tt>,
525  inclusive.
526 
527  If the object \c row previously contains any data, it will be
528  lost.
529 
530  The type <tt>resize_vec_t</tt> must be a type which has
531  <tt>size()</tt> and <tt>resize()</tt> methods.
532  */
533  template<class resize_vec_t>
534  void get_row(size_t irow, resize_vec_t &row) const {
535 
536  if (irow+1>nlines) {
537  O2SCL_ERR((((std::string)"Row '")+ szttos(irow)+
538  "' not found in table::get_row(size_t,vec_t).").c_str(),
539  exc_enotfound);
540  return;
541  }
542 
543  int i;
544  aciter it;
545  row.resize(atree.size());
546  for(i=0,it=atree.begin();it!=atree.end();it++,i++) {
547  row[i]=(it->second.dat)[irow];
548  }
549  return;
550  }
551 
552  /** \brief Set the number of lines, increasing the size more
553  agressively
554 
555  This function is like set_nlines(), but doubles the maximum
556  column size if an increase in the maximum size is required
557  instead of simply making enough room for the current number of
558  lines. This function is used internally by \ref set() to
559  ensure that the cost of setting lines in sequence is linear
560  and not quadratic.
561  */
562  void set_nlines_auto(size_t il) {
563 
564  // Try to increase the number of lines
565  if (il>maxlines) {
566  size_t inc=il-maxlines;
567  if (inc<maxlines) inc=maxlines;
568  inc_maxlines(inc);
569  }
570 
571  // Now that maxlines is large enough, set the number of lines
572  nlines=il;
573 
574  // Reset the interpolation object for future interpolations
575  if (intp_set) {
576  intp_set=false;
577  delete si;
578  }
579 
580  return;
581  }
582 
583  /** \brief Manually increase the maximum number of lines
584  */
585  void inc_maxlines(size_t llines) {
586 
587  vec_t temp_col;
588 
589  // For the moment, we assume resizes are destructive, so
590  // we have to copy the data to a temporary and then
591  // copy it back
592  for(aiter it=atree.begin();it!=atree.end();it++) {
593 
594  // Copy data to temporary array
595  temp_col.resize(maxlines+llines);
596  for(size_t j=0;j<maxlines;j++) {
597  temp_col[j]=it->second.dat[j];
598  }
599 
600  // Resize
601  it->second.dat.resize(maxlines+llines);
602 
603  // Copy data back to resized array
604  for(size_t j=0;j<maxlines;j++) {
605  it->second.dat[j]=temp_col[j];
606  }
607 
608  }
609 
610  maxlines+=llines;
611 
612  return;
613  }
614 
615  /** \brief Manually set the maximum number of lines
616 
617  \note This function will call the error handler if
618  the argument <tt>llines</tt> is smaller than the
619  current number of lines in the table.
620  */
621  void set_maxlines(size_t llines) {
622 
623  if (llines==maxlines) return;
624  if (llines<nlines) {
625  O2SCL_ERR2("Cannot set maximum number of lines to be smaller ",
626  "than current size in table::set_maxlines().",
628 
629  }
630 
631  vec_t temp_col;
632 
633  // For the moment, we assume resizes are destructive, so
634  // we have to copy the data to a temporary and then
635  // copy it back
636  for(aiter it=atree.begin();it!=atree.end();it++) {
637 
638  // Copy data to temporary array
639  temp_col.resize(llines);
640  for(size_t j=0;j<nlines;j++) {
641  temp_col[j]=it->second.dat[j];
642  }
643 
644  // Resize
645  it->second.dat.resize(llines);
646 
647  // Copy data back to resized array
648  for(size_t j=0;j<nlines;j++) {
649  it->second.dat[j]=temp_col[j];
650  }
651 
652  }
653 
654  maxlines=llines;
655 
656  return;
657  }
658  //@}
659 
660  // --------------------------------------------------------
661  /** \name Column manipulation */
662  //@{
663  /** \brief Returns a reference to the column named \c col.
664  \f$ {\cal O}(\log(C)) \f$
665 
666  Note also that the vector object returned by this function may
667  be larger than the number of rows in the table, as the table
668  resizes these vectors automatically to make room for more data.
669  To get the number of valid data entries in the object,
670  use \ref get_nlines() instead of <tt>get_column().size()</tt>.
671  */
672  const vec_t &get_column(std::string scol) const {
673  aciter it=atree.find(scol);
674  if (it==atree.end()) {
675  O2SCL_ERR((((std::string)"Column '")+scol+
676  "' not found in table::get_column() const.").c_str(),
677  exc_enotfound);
678  return empty_col;
679  }
680  return it->second.dat;
681  }
682 
683  /** \brief Returns the column of index \c icol (const
684  version). \f$ {\cal O}(1) \f$
685 
686  Note that several of the methods require reallocation of
687  memory and refereces previously returned by this function will
688  be incorrect.
689 
690  Note also that the vector object returned by this function may
691  be larger than the number of rows in the table, as the table
692  resizes these vectors automatically to make room for more data.
693  To get the number of valid data entries in the object,
694  use \ref get_nlines() instead of <tt>operator[].size()</tt>.
695 
696  Unlike set(), this function will not automatically result in
697  an increase in the size of the table if the user attempts to
698  set an element beyond the current column range.
699 
700  This function will throw an exception if \c icol is out
701  of range unless <tt>O2SCL_NO_RANGE_CHECK</tt> is defined.
702  */
703  const vec_t &operator[](size_t icol) const {
704 #if !O2SCL_NO_RANGE_CHECK
705  if (icol>=atree.size()) {
706  O2SCL_ERR((((std::string)"Array index ")+szttos(icol)+
707  " out of bounds"+
708  " in table::operator[size_t] const. Size: "+
709  szttos(atree.size())+
710  " (index should be less than size).").c_str(),exc_eindex);
711  return empty_col;
712  }
713 #endif
714  return (alist[icol]->second.dat);
715  }
716 
717  /** \brief Returns the column named \c scol (const version).
718  \f$ {\cal O}(\log(C)) \f$
719 
720  Note that several of the methods require reallocation of
721  memory and refereces previously returned by this function will
722  be incorrect.
723 
724  Note also that the vector object returned by this function may
725  be larger than the number of rows in the table, as the table
726  resizes these vectors automatically to make room for more data.
727  To get the number of valid data entries in the object,
728  use \ref get_nlines() instead of <tt>operator[].size()</tt>.
729 
730  This function will throw an exception if \c icol is out
731  of range unless <tt>O2SCL_NO_RANGE_CHECK</tt> is defined.
732  */
733  const vec_t &operator[](std::string scol) const {
734  aciter it=atree.find(scol);
735 #if !O2SCL_NO_RANGE_CHECK
736  if (it==atree.end()) {
737  O2SCL_ERR((((std::string)"Column '")+scol+"' not found in table::"+
738  "operator[string] const.").c_str(),exc_enotfound);
739  return empty_col;
740  }
741 #endif
742  return (it->second.dat);
743  }
744 
745  /** \brief Add a new column owned by the \table \f$ {\cal O}(\log(C)) \f$
746 
747  \note This function does not set all the column entries to
748  zero in the case that a new column is added to a table which
749  already contains data.
750  */
751  void new_column(std::string head) {
752  if (head.length()==0) {
753  O2SCL_ERR2("Cannot add column with empty name in ",
754  "table::new_column().",exc_einval);
755  }
756  if (is_column(head)==true) {
757  O2SCL_ERR((((std::string)"Column '")+head+
758  "' already present in table::new_column().").c_str(),
759  exc_einval);
760  }
761  for(int i=0;i<((int)head.size());i++) {
762  if (head[i]==' ' || head[i]=='\t' || head[i]=='\n' || head[i]=='\r'
763  || head[i]=='\v' || head[i]=='\f') {
764  O2SCL_ERR((((std::string)"Invalid column name '")+head+
765  "' in table::new_column().").c_str(),
766  exc_einval);
767  }
768  }
769  col s;
770  s.dat.resize(maxlines);
771  s.index=((int)atree.size());
772  atree.insert(make_pair(head,s));
773  aiter it=atree.find(head);
774  alist.push_back(it);
775  return;
776  }
777 
778  /** \brief Add a new column by copying data from another vector
779 
780  This function copies \c sz elements of vector \c v into the
781  table in a new column named \c name. If \c sz is larger than
782  the current number of lines (as given, e.g. in \ref
783  get_nlines() ), then only the first part of the vector \c v is
784  copied, up to the current number of lines.
785 
786  This function calls the error handler if \c sz is zero.
787 
788  The type <tt>vec2_t</tt> can be any type with an
789  <tt>operator[]</tt> method.
790  */
791  template<class vec2_t> int new_column(std::string name,
792  size_t sz, vec2_t &v) {
793 
794  if (sz==0) {
795  O2SCL_ERR2("Sent column of zero size in ",
796  "table::new_column(string,size_t,vec2_t)",
797  exc_einval);
798  }
799 
800  // Create the space
801  int ret=new_column(name);
802  if (ret!=0) return ret;
803 
804  // Copy the data over
805  size_t mxl=sz;
806  if (sz>get_nlines()) mxl=get_nlines();
807  for(size_t i=0;i<mxl;i++) {
808  set(name,i,v[i]);
809  }
810 
811  return 0;
812  }
813 
814  /** \brief Returns the name of column \c col \f$ {\cal O}(1) \f$
815 
816  This will throw if \c icol is larger than or equal to
817  the number of columns.
818  */
819  std::string get_column_name(size_t icol) const {
820  if (icol+1>atree.size()) {
821  O2SCL_ERR((((std::string)"Index '")+o2scl::szttos(icol)+
822  " larger than number of "+
823  "columns in table::get_column_name().").c_str(),
824  exc_enotfound);
825  }
826  return alist[icol]->first;
827  }
828 
829  /** \brief Swap the data in column \c scol with that in vector \c v
830 
831  This requires that the column \c v must have the correct size,
832  that returned by \ref get_maxlines().
833 
834  This function is useful, in part, because if objects of type
835  <tt>vec_t</tt> have <tt>std::move</tt> defined, then the swap
836  doesn't require a full copy.
837  */
838  virtual void swap_column_data(std::string scol, vec_t &v) {
839  aiter its=atree.find(scol);
840  if (its==atree.end()) {
841  O2SCL_ERR((((std::string)"Column '")+scol+
842  " not found in table::swap_column_data().").c_str(),
843  exc_enotfound);
844  return;
845  }
846  if (v.size()!=its->second.dat.size()) {
847  O2SCL_ERR2("Vector sizes not commensurate in ",
848  "table::swap_column_data().",exc_einval);
849  }
850  std::swap(its->second.dat,v);
851  return;
852  }
853 
854  /** \brief Rename column named \c src to \c dest
855  \f$ {\cal O}(C) \f$
856  */
857  virtual void rename_column(std::string src, std::string dest) {
858  aiter its=atree.find(src);
859  if (its==atree.end()) {
860  O2SCL_ERR((((std::string)"Column '")+src+
861  " not found in table::rename_column().").c_str(),
862  exc_enotfound);
863  return;
864  }
865  new_column(dest);
866  aiter itd=atree.find(dest);
867  std::swap(its->second.dat,itd->second.dat);
868  delete_column(src);
869  return;
870  }
871 
872  /** \brief Delete column named \c scol \f$ {\cal O}(C) \f$
873 
874  This is slow because the iterators in \ref alist are mangled
875  and we have to call \ref reset_list() to get them back.
876  */
877  virtual void delete_column(std::string scol) {
878 
879  // Find the tree iterator for the element we want to erase
880  aiter it=atree.find(scol);
881  if (it==atree.end()) {
882  O2SCL_ERR((((std::string)"Column '")+scol+
883  " not found in table::delete_column().").c_str(),
884  exc_enotfound);
885  return;
886  }
887 
888  // Find the corresponding list iterator
889  aviter vit=alist.begin();
890  vit+=it->second.index;
891 
892  // Find the last element in the list and it's corresponding table
893  // entry. Change it's index to the index of the column to be
894  // deleted.
895  alist[alist.size()-1]->second.index=it->second.index;
896 
897  // Erase the elements from the list and the tree
898  atree.erase(it);
899  alist.erase(vit);
900 
901  // Reset the list to reflect the proper iterators
902  reset_list();
903 
904  if ((intp_colx==scol || intp_coly==scol) && intp_set==true) {
905  delete si;
906  intp_set=false;
907  }
908 
909  return;
910  }
911 
912  /** \brief Returns the name of column \c col in sorted order.
913  \f$ {\cal O}(1) \f$
914  */
915  std::string get_sorted_name(size_t icol) const {
916  if (icol+1>atree.size()) {
917  return "";
918  }
919  aciter it=atree.begin();
920  for(size_t i=0;i<icol;i++) it++;
921  return it->first;
922  }
923 
924  /** \brief Initialize all values of column named \c scol to \c val
925  \f$ {\cal O}(R \log(C)) \f$
926 
927  Note that this does not initialize elements beyond nlines so
928  that if the number of rows is increased afterwards, the new
929  rows will have uninitialized values.
930  */
931  void init_column(std::string scol, double val) {
932  /*
933  if (!std::isfinite(val)) {
934  O2SCL_ERR((((std::string)"Value '")+dtos(val)+
935  "' not finite for column '"+
936  scol+"' in table::init_column()").c_str(),exc_einval);
937  return;
938  }
939  */
940  aiter it=atree.find(scol);
941  if (it==atree.end()) {
942  O2SCL_ERR((((std::string)"Column '")+scol+
943  "' not found in table::init_column()").c_str(),
944  exc_enotfound);
945  return;
946  }
947  for(size_t i=0;i<nlines;i++) {
948  it->second.dat[i]=val;
949  }
950  if (intp_set && (scol==intp_colx || scol==intp_coly)) {
951  intp_set=false;
952  delete si;
953  }
954  return;
955  }
956 
957  /** \brief Return true if \c scol is a column in the current \table
958 
959  This function does not call the error handler if the column is
960  not found, but just silently returns false.
961  */
962  bool is_column(std::string scol) const {
963  aciter it=atree.find(scol);
964  if (it==atree.end()) return false;
965  return true;
966  }
967 
968  /** \brief Find the index for column named \c name
969  \f$ {\cal O}(\log(C)) \f$
970 
971  If the column is not present, this function calls the error
972  handler.
973  */
974  size_t lookup_column(std::string lname) const {
975  aciter it=atree.find(lname);
976  if (it==atree.end()) {
977  O2SCL_ERR("Column not found in table::lookup_column().",
978  exc_enotfound);
979  }
980  return it->second.index;
981  }
982 
983  /** \brief Copy data from column named \c src to column
984  named \c dest, creating a new column if necessary
985  \f$ {\cal O}(R \log(C)) \f$
986  */
987  virtual void copy_column(std::string src, std::string dest) {
988  if (!is_column(dest)) new_column(dest);
989  aiter its=atree.find(src);
990  if (its==atree.end()) {
991  O2SCL_ERR((((std::string)"Column '")+src+
992  " not found in table::copy_column().").c_str(),
993  exc_enotfound);
994  return;
995  }
996  aiter itd=atree.find(dest);
997  if (itd==atree.end()) {
998  O2SCL_ERR((((std::string)"Destination column '")+dest+
999  " not found in table::copy_column().").c_str(),
1000  exc_esanity);
1001  return;
1002  }
1003  for(size_t i=0;i<nlines;i++) {
1004  itd->second.dat[i]=its->second.dat[i];
1005  }
1006  return;
1007  }
1008 
1009  /** \brief Copy a column to a generic vector object
1010 
1011  \note It is assumed that the vector type is one that can be
1012  resized with <tt>resize()</tt>.
1013  */
1014  template<class resize_vec_t>
1015  void column_to_vector(std::string scol, resize_vec_t &v) const {
1016  v.resize(nlines);
1017  for(size_t i=0;i<nlines;i++) {
1018  v[i]=this->get(scol,i);
1019  }
1020  return;
1021  }
1022 
1023  /** \brief Copy to a column from a generic vector object
1024 
1025  The type <tt>vec2_t</tt> can be any type with an
1026  <tt>operator[]</tt> method.
1027  */
1028  template<class vec2_t>
1029  void copy_to_column(vec2_t &v, std::string scol) {
1030  for(size_t i=0;i<nlines;i++) {
1031  this->set(scol,i,v[i]);
1032  }
1033  return;
1034  }
1035 
1036  /** \brief Insert a column from a separate table, interpolating
1037  it into a new column
1038 
1039  Given a pair of columns ( \c src_index, \c src_col ) in a
1040  separate table (\c source), this creates a new column in the
1041  present table named \c src_col which interpolates \c loc_index
1042  into \c src_index. The interpolation objects from the \c
1043  source table will be used. If there is already a column in the
1044  present table named \c src_col, then this will fail.
1045  */
1046  template<class vec2_t>
1048  std::string src_index, std::string src_col,
1049  std::string dest_index, std::string dest_col="") {
1050 
1051  if (dest_col=="") dest_col=src_col;
1052 
1053  // Add the new column
1054  if (!is_column(dest_col)) new_column(dest_col);
1055 
1056  // Fill the new column
1057  for(size_t i=0;i<nlines;i++) {
1058  set(dest_col,i,source.interp(src_index,get(dest_index,i),src_col));
1059  }
1060 
1061  return;
1062  }
1063  //@}
1064 
1065  /** \brief Insert columns from a source table into the new
1066  table by interpolation (or extrapolation)
1067 
1068  This takes all of the columns in \c source, and adds them into
1069  the current table using interpolation, using the columns \c
1070  src_index and \c dest_index as the independent variable. The
1071  column named \c src_index is the column of the independent
1072  variable in \c source and the column named \c dest_index
1073  is the column of the independent variable in the current table.
1074  If \c dest_index is empty (the default) then the names in the
1075  two tables are taken to be the same.
1076 
1077  If necessary, columns are created in the current table for the
1078  dependent variable columns in \c source. Columns in the current
1079  table which do not correspond to dependent variable columns in
1080  \c source are left unchanged.
1081 
1082  If \c allow_extrap is false, then extrapolation is not allowed,
1083  and rows in the current table which have values of the independent
1084  variable which are outside the source table are unmodified.
1085 
1086  If a column for a dependent variable in \c source has the
1087  same name as \c dest_index, then it is ignored and not inserted
1088  into the current table.
1089 
1090  If the column named \c src_index cannot be found in
1091  \c source or the column names \c dest_index cannot be found
1092  in the current table, then the error handler is called.
1093 
1094  If the \c allow_extrap is false and either the minimum or
1095  maximum values of the column named \c src_index in the \c source
1096  table are not finite, then the error handler is called.
1097  */
1098  template<class vec2_t>
1099  void insert_table(table<vec2_t> &source, std::string src_index,
1100  bool allow_extrap=true, std::string dest_index="") {
1101 
1102  if (dest_index=="") dest_index=src_index;
1103 
1104  if (!source.is_column(src_index)) {
1105  O2SCL_ERR("Source indep. var. column not found.",o2scl::exc_einval);
1106  }
1107  if (!is_column(dest_index)) {
1108  O2SCL_ERR("Dest. indep. var. column not found.",o2scl::exc_einval);
1109  }
1110 
1111  // Find limits to avoid extrapolation if necessary
1112  double min=source.min(src_index);
1113  double max=source.max(src_index);
1114  if (allow_extrap==false) {
1115  if (!std::isfinite(min) || !std::isfinite(max)) {
1116  O2SCL_ERR2("Minimum or maximum of source index not finite ",
1117  "in table::insert_table().",exc_einval);
1118  }
1119  }
1120 
1121  // Create list of columns to interpolate
1122  std::vector<std::string> col_list;
1123  for(size_t i=0;i<source.get_ncolumns();i++) {
1124  std::string col_name=source.get_column_name(i);
1125  if (col_name!=src_index && col_name!=dest_index) {
1126  col_list.push_back(col_name);
1127  }
1128  }
1129 
1130  // Create new columns and perform interpolation
1131  for(size_t i=0;i<col_list.size();i++) {
1132  if (!is_column(col_list[i])) new_column(col_list[i]);
1133  for(size_t j=0;j<get_nlines();j++) {
1134  double val=get(dest_index,j);
1135  if (allow_extrap || (val>=min && val<=max)) {
1136  set(col_list[i],j,source.interp(src_index,val,col_list[i]));
1137  }
1138  }
1139  }
1140 
1141  return;
1142  }
1143 
1144  // --------------------------------------------------------
1145  /** \name Row maninpulation and data input */
1146  //@{
1147 
1148  /** \brief Insert a row before row \c n
1149 
1150  Acceptable values for \c n are between 0 and
1151  <tt>get_nlines()</tt> inclusive, with the maximum value
1152  denoting the addition of a row after the last row presently in
1153  the table.
1154  */
1155  void new_row(size_t n) {
1157 
1158  nlines++;
1159  for(int i=((int)nlines)-2;i>=((int)n);i--) {
1160  copy_row(i,i+1);
1161  }
1162 
1163  if (intp_set) {
1164  intp_set=false;
1165  delete si;
1166  }
1167 
1168  return;
1169  }
1170 
1171  /** \brief Copy the data in row \c src to row \c dest
1172 
1173  \comment
1174  AWS 4/12/18: No need to throw an exception here since get() and
1175  set() will take care of that already.
1176  \endcomment
1177  */
1178  void copy_row(size_t src, size_t dest) {
1179  for(int i=0;i<((int)atree.size());i++) {
1180  set(i,dest,get(i,src));
1181  }
1182  if (intp_set) {
1183  intp_set=false;
1184  delete si;
1185  }
1186  return;
1187  }
1188 
1189  /** \brief Delete the row with the entry closest to
1190  the value \c val in column \c scol \f$ {\cal O}(R C) \f$
1191  */
1192  void delete_row(std::string scol, double val) {
1193  // If lookup() fails, it will throw an exception,
1194  // so there's no need to double-check it here
1195  size_t irow=lookup(scol,val);
1196  delete_row(irow);
1197  return;
1198  }
1199 
1200  /** \brief Delete the row of index \c irow \f$ {\cal O}(R C) \f$
1201  */
1202  void delete_row(size_t irow) {
1203  if (nlines==0) {
1204  O2SCL_ERR2("No lines in table in ",
1205  "table::delete_row(size_t).",o2scl::exc_einval);
1206  }
1207  if (irow>=nlines) {
1208  std::string str=((std::string)"Cannot delete row ")+
1209  o2scl::szttos(irow)+" since there are only "+
1210  o2scl::szttos(nlines)+" lines in the table in "+
1211  "table::delete_row(size_t).";
1212  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
1213  }
1214  for(aiter it=atree.begin();it!=atree.end();it++) {
1215  // Can't do size_t because we have to compare to nlines-1
1216  for(int i=((int)irow);i<((int)nlines)-1;i++) {
1217  it->second.dat[i]=it->second.dat[i+1];
1218  }
1219  }
1220  nlines--;
1221  if (intp_set==true) {
1222  delete si;
1223  intp_set=false;
1224  }
1225  return;
1226  }
1227 
1228  /** \brief Delete all rows where \c func evaluates to a number greater
1229  than 0.5 \f$ {\cal O}(R C) \f$
1230 
1231  If no rows match the delete condition, this function silently
1232  performs no changes to the table.
1233  */
1234  void delete_rows_func(std::string func) {
1235  size_t new_nlines=0;
1236  for(size_t i=0;i<nlines;i++) {
1237  double val=row_function(func,i);
1238  if (val<0.5) {
1239  // If val<0.5, then the function was evaluated to false and
1240  // we want to keep the row, but if i==new_nlines, then
1241  // we don't need to copy because the row is already in
1242  // the correct place.
1243  if (i!=new_nlines) {
1244  for(aiter it=atree.begin();it!=atree.end();it++) {
1245  it->second.dat[new_nlines]=it->second.dat[i];
1246  }
1247  }
1248  new_nlines++;
1249  }
1250  }
1251  nlines=new_nlines;
1252  if (intp_set==true) {
1253  delete si;
1254  intp_set=false;
1255  }
1256  return;
1257  }
1258 
1259  /** \brief Copy all rows matching a particular condition to
1260  a new table
1261 
1262  This function begins by ensuring that all columns in the current
1263  table are present in \c dest, creating new columns in \c dest if
1264  necessary. It then copies all rows where \c func evaluates to a
1265  number greater than 0.5 to table \c dest by adding rows at
1266  the end of the table.
1267  */
1268  template<class vec2_t>
1269  void copy_rows(std::string func, table<vec2_t> &dest) {
1270 
1271  // Set up columns
1272  for(size_t i=0;i<get_ncolumns();i++) {
1273  std::string cname=get_column_name(i);
1274  if (dest.is_column(cname)==false) {
1275  dest.new_column(cname);
1276  }
1277  }
1278 
1279  size_t new_lines=dest.get_nlines();
1280  for(size_t i=0;i<nlines;i++) {
1281  double val=row_function(func,i);
1282  if (val>0.5) {
1283  dest.set_nlines_auto(new_lines+1);
1284  for(size_t j=0;j<get_ncolumns();j++) {
1285  std::string cname=get_column_name(j);
1286  dest.set(cname,new_lines);
1287  }
1288  new_lines++;
1289  }
1290  }
1291 
1292  return;
1293  }
1294 
1295  /** \brief Delete all rows between \c row_start and \c row_end
1296  \f$ {\cal O}(R C) \f$
1297 
1298  If <tt>row_start</tt> is less or equal to <tt>row_end</tt>,
1299  then all rows beginnning with <tt>row_start</tt> and
1300  ending with <tt>row_end</tt> are deleted (inclusive). If
1301  <tt>row_start</tt> is greater than <tt>row_end</tt>, then
1302  rows from the start of the table until <tt>row_end</tt> are
1303  deleted, as well as all rows from <tt>row_start</tt>
1304  through the end of the table.
1305 
1306  If either <tt>row_start</tt> or <tt>row_end</tt> are beyond the
1307  end of the table (greater than or equal to the value given by
1308  \ref get_nlines() ), an exception is thrown.
1309  */
1310  void delete_rows_ends(size_t row_start, size_t row_end) {
1311  if (row_start>=nlines || row_end>=nlines) {
1312  O2SCL_ERR2("Row specifications beyond end of table in ",
1313  "table::delete_rows_ends(size_t,size_t).",exc_einval);
1314  }
1315  size_t new_nlines=0;
1316  for(size_t i=0;i<nlines;i++) {
1317  if ((row_start<=row_end && (i<row_start || i>row_end)) ||
1318  (row_start>row_end && (i<row_start && i>row_end))) {
1319  for(aiter it=atree.begin();it!=atree.end();it++) {
1320  it->second.dat[new_nlines]=it->second.dat[i];
1321  }
1322  new_nlines++;
1323  }
1324  }
1325  nlines=new_nlines;
1326  if (intp_set==true) {
1327  delete si;
1328  intp_set=false;
1329  }
1330  return;
1331  }
1332 
1333  /** \brief Delete all rows in a specified list
1334 
1335  Given a list of rows in \c row_list, this function deletes all
1336  of the specified rows. If a row beyond the end of the table is
1337  in the list, the error handler is called.
1338 
1339  \note This function will proceed normally if a row is specified
1340  more than once in <tt>row_list</tt>.
1341  */
1342  template<class vec_size_t>
1343  void delete_rows_list(vec_size_t &row_list) {
1344 
1345  // First, check that they're all valid rows
1346  for(size_t j=0;j<row_list.size();j++) {
1347  if (row_list[j]>nlines) {
1348  O2SCL_ERR("Invalid row in table<>::delete_rows_list(vec_size_t &)",
1350  }
1351  }
1352 
1353  // Copy the data over, ensuring rows which are to be
1354  // deleted are skipped
1355  size_t new_nlines=0;
1356  for(size_t i=0;i<nlines;i++) {
1357  bool found=false;
1358  for(size_t j=0;j<row_list.size();j++) {
1359  if (row_list[j]==i) found=true;
1360  }
1361  if (found==false) {
1362  for(aiter it=atree.begin();it!=atree.end();it++) {
1363  it->second.dat[new_nlines]=it->second.dat[i];
1364  }
1365  new_nlines++;
1366  }
1367  }
1368 
1369  // Set the new line number and reset the interpolator
1370  nlines=new_nlines;
1371  if (intp_set==true) {
1372  delete si;
1373  intp_set=false;
1374  }
1375 
1376  return;
1377  }
1378 
1379  /** \brief Exaustively search for groups of rows which match within a
1380  specified tolerance and remove all but one of each group
1381 
1382  This function returns the number of rows deleted.
1383  */
1384  size_t delete_rows_tolerance(double tol_rel=1.0e-12,
1385  double tol_abs=1.0e-20,
1386  int verbose=0) {
1387  std::vector<size_t> list;
1388  for(size_t i=0;i<nlines;i++) {
1389  for(size_t j=i+1;j<nlines;j++) {
1390  bool match=true;
1391  if (i<nlines && j<nlines && j>i) {
1392  for(aiter it=atree.begin();it!=atree.end() && match==true;it++) {
1393  if (fabs(it->second.dat[i])>tol_abs ||
1394  fabs(it->second.dat[j])>tol_abs) {
1395  if (fabs(it->second.dat[i]-it->second.dat[j])/
1396  fabs(it->second.dat[i]+it->second.dat[j])>tol_rel) {
1397  match=false;
1398  }
1399  }
1400  }
1401  }
1402  if (match==true) {
1403  list.push_back(j);
1404  if (verbose>0) {
1405  std::cout << "Match between rows " << i << " and " << j
1406  << std::endl;
1407  if (verbose>1) {
1408  for(size_t k=0;k<get_ncolumns();k++) {
1409  std::cout << k << " " << get(k,i) << " " << get(k,j)
1410  << std::endl;
1411  }
1412  }
1413  }
1414  }
1415  }
1416  }
1417  if (list.size()>0) {
1418  delete_rows_list(list);
1419  } else if (verbose>0) {
1420  std::cout << "No matches found." << std::endl;
1421  }
1422  return list.size();
1423  }
1424 
1425  /** \brief Delete all rows which are identical to
1426  adjacent rows
1427 
1428  This function does silently does nothing if there are
1429  less than 2 rows in the table.
1430  */
1432  if (nlines>=2) {
1433  // Find duplicate rows
1434  std::vector<size_t> row_list;
1435  for(size_t i=0;i<nlines-1;i++) {
1436  bool match=true;
1437  for(aiter it=atree.begin();it!=atree.end() && match==true;it++) {
1438  if (it->second.dat[i+1]!=it->second.dat[i]) match=false;
1439  }
1440  if (match) row_list.push_back(i+1);
1441  }
1442  // Delete duplicates
1443  delete_rows_list(row_list);
1444  }
1445  return;
1446  }
1447 
1448  /** \brief Read a new set of names from \c newheads
1449 
1450  This function reads a set of white-space delimited column
1451  names from the string \c newheads, and creates a new column
1452  for each name which is specified.
1453 
1454  For example
1455  \code
1456  table t;
1457  t.line_of_names("position velocity acceleration");
1458  \endcode
1459  will create three new columns with the names "position",
1460  "velocity", and "acceleration".
1461  */
1462  void line_of_names(std::string newheads) {
1463  int ret=0;
1464  std::string head;
1465 
1466  std::istringstream is(newheads);
1467  while(is >> head) {
1468  new_column(head);
1469  }
1470 
1471  if (ret!=0) {
1472  O2SCL_ERR2("At least one new column failed in ",
1473  "table::line_of_names().",exc_efailed);
1474  }
1475 
1476  return;
1477  }
1478 
1479  /** \brief Read a line of data from the first \c nv entries in
1480  a vector and store as a new row in the table
1481 
1482  The type <tt>vec2_t</tt> can be any type with an
1483  <tt>operator[]</tt> method. Note that this function does not
1484  verify that \c nv is equal to the number of columns, so some of
1485  the columns may be uninitialized in the new row which is
1486  created.
1487 
1488  Similar to <tt>std::vector</tt>'s <tt>push_back()</tt> method,
1489  this function now internally increases the maximum table size
1490  geometrically to help avoid excessive memory rearrangements.
1491  */
1492  template<class vec2_t> void line_of_data(size_t nv, const vec2_t &v) {
1493  if (maxlines==0) inc_maxlines(1);
1495 
1496  if (intp_set) {
1497  intp_set=false;
1498  delete si;
1499  }
1500 
1501  if (nlines<maxlines && nv<=(atree.size())) {
1502 
1504  for(size_t i=0;i<nv;i++) {
1505  (*this).set(i,nlines-1,v[i]);
1506  }
1507 
1508  return;
1509  }
1510 
1511  O2SCL_ERR("Not enough lines or columns in line_of_data().",exc_einval);
1512  return;
1513  }
1514 
1515  /** \brief Read a line of data and store in a new row of the
1516  table
1517 
1518  The type <tt>vec2_t</tt> can be any type with an
1519  <tt>operator[]</tt> method. Note that this function does not
1520  verify that the vector size is equal to the number of columns,
1521  so some of the columns may be uninitialized in the new row which
1522  is created.
1523  */
1524  template<class vec2_t> void line_of_data(const vec2_t &v) {
1525  line_of_data(v.size(),v);
1526  return;
1527  }
1528  //@}
1529 
1530  // --------------------------------------------------------
1531  /** \name Lookup and search methods */
1532  //@{
1533 
1534  /** \brief Look for a value in an ordered column
1535  \f$ {\cal O}(\log(C) \log(R)) \f$
1536 
1537  This uses the function search_vec::ordered_lookup(), which
1538  offers caching and assumes the vector is monotonic. If you
1539  don't have monotonic data, you can still use the
1540  table::lookup() function, which is more general.
1541  */
1542  size_t ordered_lookup(std::string scol, double val) const {
1543  int ret;
1544  if (!std::isfinite(val)) {
1545  O2SCL_ERR((((std::string)"Value '")+dtos(val)+
1546  "' not finite for column '"+
1547  scol+"' in table::ordered_lookup()").c_str(),exc_einval);
1548  return exc_einval;
1549  }
1550  aciter it=atree.find(scol);
1551  if (it==atree.end()) {
1552  O2SCL_ERR((((std::string)"Column '")+scol+
1553  " not found in table::ordered_lookup().").c_str(),
1554  exc_enotfound);
1555  return exc_enotfound;
1556  }
1557 
1558  search_vec<vec_t> se(nlines,it->second.dat);
1559  ret=se.ordered_lookup(val);
1560  return ret;
1561  }
1562 
1563  /** \brief Exhaustively search column \c col for the value \c val
1564  \f$ {\cal O}(R \log(C)) \f$
1565  */
1566  size_t lookup(std::string scol, double val) const {
1567  if (!std::isfinite(val)) {
1568  O2SCL_ERR((((std::string)"Value '")+dtos(val)+
1569  "' not finite for column '"+
1570  scol+"' in table::lookup()").c_str(),exc_einval);
1571  return exc_einval;
1572  }
1573  aciter it=atree.find(scol);
1574  if (it==atree.end()) {
1575  O2SCL_ERR((((std::string)"Column '")+scol+" not found in "+
1576  "table::lookup().").c_str(),exc_enotfound);
1577  return exc_enotfound;
1578 
1579  }
1580 
1581  // Note that we cannot use the vector lookup() method here, because
1582  // the vector size may be larger than the actual table size.
1583 
1584  const vec_t &ov=it->second.dat;
1585  size_t row=0, i=0;
1586 
1587  // Find first finite row
1588  while(!std::isfinite(ov[i]) && i<nlines-1) i++;
1589  if (i==nlines-1) {
1590  O2SCL_ERR2("Entire array not finite in ",
1591  "table::lookup()",exc_einval);
1592  return 0;
1593  }
1594 
1595  // Beginning with that row, look for the closest value
1596  double bdiff=fabs(ov[i]-val);
1597  for(;i<nlines;i++) {
1598  if (std::isfinite(ov[i]) && fabs(ov[i]-val)<bdiff) {
1599  row=i;
1600  bdiff=fabs(ov[i]-val);
1601  }
1602  }
1603 
1604  return row;
1605  }
1606 
1607  /// Search column \c col for the value \c val and return value in \c col2
1608  double lookup_val(std::string scol, double val, std::string scol2) const {
1609  int i, indx=0;
1610  if (!std::isfinite(val)) {
1611  O2SCL_ERR((((std::string)"Value '")+dtos(val)+
1612  "' not finite for column '"+
1613  scol+"' in table::lookup_val()").c_str(),exc_einval);
1614  return exc_einval;
1615  }
1616  aciter it=atree.find(scol);
1617  if (it==atree.end()) {
1618  O2SCL_ERR((((std::string)"Column '")+scol+" not found in "+
1619  "table::lookup().").c_str(),exc_enotfound);
1620  return exc_enotfound;
1621  }
1622  return get(scol2,it->second.dat->lookup(val));
1623  }
1624 
1625  /** \brief Exhaustively search column \c col for the value \c val
1626  \f$ {\cal O}(R \log(C)) \f$
1627  */
1628  size_t lookup(int icol, double val) const {
1629  return lookup(get_column_name(icol),val);
1630  }
1631 
1632  /** \brief Exhaustively search column \c col for many occurences
1633  of \c val \f$ {\cal O}(R \log(C)) \f$
1634  */
1635  size_t mlookup(std::string scol, double val, std::vector<size_t> &results,
1636  double threshold=0.0) const {
1637  size_t i;
1638  if (!std::isfinite(val)) {
1639  O2SCL_ERR((((std::string)"Value '")+dtos(val)+
1640  "' not finite for column '"+
1641  scol+"' in table::mlookup()").c_str(),exc_einval);
1642  return exc_einval;
1643  }
1644  aciter it=atree.find(scol);
1645  if (it==atree.end()) {
1646  O2SCL_ERR((((std::string)"Column '")+scol+" not found in "+
1647  "table::mlookup().").c_str(),exc_enotfound);
1648  return exc_enotfound;
1649  }
1650  if (threshold==0.0) {
1651  for(i=0;i<nlines;i++) {
1652  if (it->second.dat[i]==val) {
1653  results.push_back(i);
1654  }
1655  }
1656  } else {
1657  for(i=0;i<nlines;i++) {
1658  if (fabs(it->second.dat[i]-val)<threshold) {
1659  results.push_back(i);
1660  }
1661  }
1662  }
1663  return results.size();
1664  }
1665  //@}
1666 
1667  // --------------------------------------------------------
1668  /** \name Interpolation, differentiation, integration, max, min */
1669  //@{
1670 
1671  /// Set the base interpolation objects
1672  void set_interp_type(size_t interp_type) {
1673  itype=interp_type;
1674  if (intp_set) {
1675  delete si;
1676  intp_set=false;
1677  }
1678  return;
1679  }
1680 
1681  /** \brief Get the interpolation type
1682  */
1683  size_t get_interp_type() const {
1684  return itype;
1685  }
1686 
1687  /** \brief Interpolate value \c x0 from column named \c sx
1688  into column named \c sy
1689 
1690  This function is \f$ {\cal O}(\log(R) \log(C)) \f$
1691  but can be as bad as \f$ {\cal O}(C \log(R) \f$ if the
1692  relevant columns are not well ordered.
1693  */
1694  double interp(std::string sx, double x0, std::string sy) {
1695  double ret;
1696  aiter itx=atree.find(sx), ity=atree.find(sy);
1697  if (itx==atree.end() || ity==atree.end()) {
1698  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
1699  "' not found in table::interp().").c_str(),
1700  exc_enotfound);
1701  return 0.0;
1702  }
1703  if (!std::isfinite(x0)) {
1704  O2SCL_ERR("x0 not finite in table::interp().",exc_einval);
1705  return exc_einval;
1706  }
1707  if (intp_set==false || sx!=intp_colx || sy!=intp_coly) {
1708  if (intp_set==true) {
1709  delete si;
1710  } else {
1711  intp_set=true;
1712  }
1713  si=new interp_vec<vec_t>(nlines,itx->second.dat,
1714  ity->second.dat,itype);
1715  intp_colx=sx;
1716  intp_coly=sy;
1717  }
1718  ret=si->eval(x0);
1719  return ret;
1720  }
1721 
1722  /** \brief Interpolate value \c x0 from column named \c sx
1723  into column named \c sy (const version)
1724 
1725  This function is \f$ {\cal O}(\log(R) \log(C)) \f$
1726  but can be as bad as \f$ {\cal O}(C \log(R) \f$ if the
1727  relevant columns are not well ordered.
1728  */
1729  double interp_const(std::string sx, double x0, std::string sy) const {
1730  double ret;
1731  aciter itx=atree.find(sx), ity=atree.find(sy);
1732  if (itx==atree.end() || ity==atree.end()) {
1733  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
1734  "' not found in table::interp_const().").c_str(),
1735  exc_enotfound);
1736  return 0.0;
1737  }
1738  if (!std::isfinite(x0)) {
1739  O2SCL_ERR("x0 not finite in table::interp_const().",exc_einval);
1740  return exc_einval;
1741  }
1742  interp_vec<vec_t> sic(nlines,itx->second.dat,ity->second.dat,itype);
1743 
1744  ret=sic.interp(x0);
1745  return ret;
1746  }
1747 
1748  /** \brief Interpolate value \c x0 from column with index
1749  \c ix into column with index \c iy
1750  \f$ {\cal O}(\log(R)) \f$
1751  */
1752  double interp(size_t ix, double x0, size_t iy) {
1753  return interp(get_column_name(ix),x0,get_column_name(iy));
1754  }
1755 
1756  /** \brief Interpolate value \c x0 from column with index \c ix
1757  into column with index \c iy \f$ {\cal O}(\log(R)) \f$
1758  */
1759  double interp_const(size_t ix, double x0, size_t iy) const {
1760  return interp_const(get_column_name(ix),x0,get_column_name(iy));
1761  }
1762 
1763  /** \brief Make a new column named \c yp which is the
1764  derivative \f$ y^{\prime}(x) \f$ formed from columns
1765  named \c x and \c y \f$ {\cal O}(R \log(C)) \f$
1766 
1767  If the column \c yp is not already in the table it is
1768  automatically created.
1769  */
1770  void deriv(std::string x, std::string y, std::string yp) {
1771 
1772  aiter itx, ity, ityp;
1773 
1774  itx=atree.find(x);
1775  ity=atree.find(y);
1776  ityp=atree.find(yp);
1777 
1778  if (ityp==atree.end()) {
1779  new_column(yp);
1780  ityp=atree.find(yp);
1781  }
1782 
1783  if (itx==atree.end() || ity==atree.end() || ityp==atree.end()) {
1784  O2SCL_ERR("Column not found in table::deriv(string,string,string).",
1785  exc_enotfound);
1786  return;
1787  }
1788 
1789  size_t ix=lookup_column(x);
1790  size_t iy=lookup_column(y);
1791  for(int i=0;i<((int)nlines);i++) {
1792  ityp->second.dat[i]=deriv(ix,(itx->second.dat)[i],iy);
1793  }
1794 
1795  return;
1796  }
1797 
1798  /** \brief Compute the first derivative of the function defined
1799  by x-values stored in column named \c sx and y-values stored
1800  in column named \c sy at the value \c x0
1801 
1802  This function is O(log(C)*log(R)) but can be as bad as
1803  O(log(C)*R) if the relevant columns are not well ordered.
1804  */
1805  double deriv(std::string sx, double x0, std::string sy) {
1806  double ret;
1807  aiter itx=atree.find(sx), ity=atree.find(sy);
1808  if (itx==atree.end() || ity==atree.end()) {
1809  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
1810  "' not found in table::deriv(string,double,string).").c_str(),
1811  exc_enotfound);
1812  return 0.0;
1813  }
1814  if (!std::isfinite(x0)) {
1815  O2SCL_ERR("x0 not finite in table::deriv(string,double,string).",
1816  exc_einval);
1817  return exc_einval;
1818  }
1819  if (intp_set==false || sx!=intp_colx || sy!=intp_coly) {
1820  if (intp_set==true) {
1821  delete si;
1822  } else {
1823  intp_set=true;
1824  }
1825  si=new interp_vec<vec_t>
1826  (nlines,itx->second.dat,ity->second.dat,itype);
1827 
1828  intp_colx=sx;
1829  intp_coly=sy;
1830  }
1831  ret=si->deriv(x0);
1832  return ret;
1833  }
1834 
1835  /** \brief Compute the first derivative of the function defined
1836  by x-values stored in column named \c sx and y-values stored
1837  in column named \c sy at the value \c x0 (const version)
1838 
1839  O(log(C)*log(R)) but can be as bad as O(log(C)*R) if
1840  the relevant columns are not well ordered.
1841  */
1842  double deriv_const(std::string sx, double x0, std::string sy) const {
1843  double ret;
1844  aciter itx=atree.find(sx), ity=atree.find(sy);
1845  if (itx==atree.end() || ity==atree.end()) {
1846  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
1847  "' not found in table::deriv_const().").c_str(),
1848  exc_enotfound);
1849  return 0.0;
1850  }
1851  if (!std::isfinite(x0)) {
1852  O2SCL_ERR("x0 not finite in table::deriv_const().",exc_einval);
1853  return exc_einval;
1854  }
1855  interp_vec<vec_t> sic
1856  (nlines,itx->second.dat,ity->second.dat,itype);
1857  ret=sic.deriv(x0);
1858  return ret;
1859  }
1860 
1861  /** \brief Compute the first derivative of the function defined
1862  by x-values stored in column with index \c ix and y-values stored
1863  in column with index \c iy at the value \c x0
1864 
1865  O(log(R)) but can be as bad as O(R) if the relevant columns
1866  are not well ordered.
1867  */
1868  double deriv(size_t ix, double x0, size_t iy) {
1869  return deriv(get_column_name(ix),x0,get_column_name(iy));
1870  }
1871 
1872  /** \brief Compute the first derivative of the function defined
1873  by x-values stored in column with index \c ix and y-values stored
1874  in column with index \c iy at the value \c x0 (const version)
1875 
1876  O(log(R)) but can be as bad as O(R) if
1877  the relevant columns are not well ordered.
1878  */
1879  double deriv_const(size_t ix, double x0, size_t iy) const {
1880  return deriv_const(get_column_name(ix),x0,get_column_name(iy));
1881  }
1882 
1883  /** \brief Create a new column named \c yp which is
1884  equal to the second derivative of the function defined by
1885  x-values stored in column named \c x and y-values
1886  stored in column named \c y, i.e.
1887  \f$ y^{\prime \prime}(x) \f$ - O(log(C)*R).
1888 
1889  If the column \c yp is not already in the table it is
1890  automatically created.
1891  */
1892  void deriv2(std::string x, std::string y, std::string yp) {
1893  aiter itx, ity, ityp;
1894 
1895  itx=atree.find(x);
1896  ity=atree.find(y);
1897  ityp=atree.find(yp);
1898 
1899  if (ityp==atree.end()) {
1900  new_column(yp);
1901  ityp=atree.find(yp);
1902  }
1903 
1904  if (itx==atree.end() || ity==atree.end() || ityp==atree.end()) {
1905  O2SCL_ERR("Column not found in table::deriv2(string,string,string).",
1906  exc_enotfound);
1907  return;
1908  }
1909 
1910  size_t ix=lookup_column(x);
1911  size_t iy=lookup_column(y);
1912  for(int i=0;i<((int)nlines);i++) {
1913  ityp->second.dat[i]=deriv2(ix,itx->second.dat[i],iy);
1914  }
1915 
1916  return;
1917  }
1918 
1919  /** \brief Compute the second derivative of the function defined
1920  by x-values stored in column named \c sx and y-values stored
1921  in column named \c sy at the value \c x0
1922 
1923  O(log(C)*log(R)) but can be as bad as O(log(C)*R) if
1924  the relevant columns are not well ordered.
1925  */
1926  double deriv2(std::string sx, double x0, std::string sy) {
1927  double ret;
1928  aiter itx=atree.find(sx), ity=atree.find(sy);
1929  if (itx==atree.end() || ity==atree.end()) {
1930  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
1931  "' not found in table::deriv2(string,double,string).").c_str(),
1932  exc_enotfound);
1933  return 0.0;
1934  }
1935  if (!std::isfinite(x0)) {
1936  O2SCL_ERR("x0 not finite in table::deriv2(string,double,string).",
1937  exc_einval);
1938  return exc_einval;
1939  }
1940  if (intp_set==false || sx!=intp_colx || sy!=intp_coly) {
1941  if (intp_set==true) {
1942  delete si;
1943  } else {
1944  intp_set=true;
1945  }
1946  si=new interp_vec<vec_t>
1947  (nlines,itx->second.dat,ity->second.dat,itype);
1948 
1949  intp_colx=sx;
1950  intp_coly=sy;
1951  }
1952  ret=si->deriv2(x0);
1953  return ret;
1954  }
1955 
1956  /** \brief The Compute the second derivative of the function defined
1957  by x-values stored in column named \c sx and y-values stored
1958  in column named \c sy at the value \c x0 (const version)
1959 
1960  O(log(C)*log(R)) but can be as bad as O(log(C)*R) if
1961  the relevant columns are not well ordered.
1962  */
1963  double deriv2_const(std::string sx, double x0, std::string sy) const {
1964  double ret;
1965  aciter itx=atree.find(sx), ity=atree.find(sy);
1966  if (itx==atree.end() || ity==atree.end()) {
1967  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
1968  "' not found in table::deriv2_const().").c_str(),
1969  exc_enotfound);
1970  return 0.0;
1971  }
1972  if (!std::isfinite(x0)) {
1973  O2SCL_ERR("x0 not finite in table::deriv2_const().",exc_einval);
1974  return exc_einval;
1975  }
1976  interp_vec<vec_t> sic
1977  (nlines,itx->second.dat,ity->second.dat,itype);
1978  ret=sic.deriv2(x0);
1979  return ret;
1980  }
1981 
1982  /** \brief Compute the second derivative of the function defined
1983  by x-values stored in column with index \c ix and y-values stored
1984  in column with index \c iy at the value \c x0
1985 
1986  O(log(R)) but can be as bad as O(R) if
1987  the relevant columns are not well ordered.
1988  */
1989  double deriv2(size_t ix, double x0, size_t iy) {
1990  return deriv2(get_column_name(ix),x0,get_column_name(iy));
1991  }
1992 
1993  /** \brief Compute the second derivative of the function defined
1994  by x-values stored in column with index \c ix and y-values stored
1995  in column with index \c iy at the value \c x0 (const version)
1996 
1997  O(log(R)) but can be as bad as O(R) if
1998  the relevant columns are not well ordered.
1999  */
2000  double deriv2_const(size_t ix, double x0, size_t iy) const {
2001  return deriv2_const(get_column_name(ix),x0,get_column_name(iy));
2002  }
2003 
2004  /** \brief Compute the integral of the function defined
2005  by x-values stored in column named \c sx and y-values stored
2006  in column named \c sy between the values \c x1 and \c x2
2007 
2008  O(log(C)*log(R)) but can be as bad as O(log(C)*R) if
2009  the relevant columns are not well ordered.
2010  */
2011  double integ(std::string sx, double x1, double x2, std::string sy) {
2012  double ret;
2013  aiter itx=atree.find(sx), ity=atree.find(sy);
2014  if (itx==atree.end() || ity==atree.end()) {
2015  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
2016  "' not found in table::integ"+
2017  "(string,double,double,string).").c_str(),
2018  exc_enotfound);
2019  return 0.0;
2020  }
2021  if (!std::isfinite(x1) || !std::isfinite(x2)) {
2022  std::string msg=((std::string)"Value x1=")+dtos(x1)+" or x2="+
2023  dtos(x2)+" not finite in table.integ(string,double,double,string).";
2024  O2SCL_ERR(msg.c_str(),exc_einval);
2025  }
2026  if (intp_set==false || sx!=intp_colx || sy!=intp_coly) {
2027  if (intp_set==true) {
2028  delete si;
2029  } else {
2030  intp_set=true;
2031  }
2032  si=new interp_vec<vec_t>
2033  (nlines,itx->second.dat,ity->second.dat,itype);
2034 
2035  intp_colx=sx;
2036  intp_coly=sy;
2037  }
2038  ret=si->integ(x1,x2);
2039  return ret;
2040  }
2041 
2042  /** \brief Compute the integral of the function defined
2043  by x-values stored in column named \c sx and y-values stored
2044  in column named \c sy between the values \c x1 and \c x2
2045  (const version)
2046 
2047  O(log(C)*log(R)) but can be as bad as O(log(C)*R) if
2048  the relevant columns are not well ordered.
2049  */
2050  double integ_const(std::string sx, double x1, double x2,
2051  std::string sy) const {
2052  double ret;
2053  aciter itx=atree.find(sx), ity=atree.find(sy);
2054  if (itx==atree.end() || ity==atree.end()) {
2055  O2SCL_ERR((((std::string)"Columns '")+sx+"' or '"+sy+
2056  "' not found in table::integ_const().").c_str(),
2057  exc_enotfound);
2058  return 0.0;
2059  }
2060  if (!std::isfinite(x1) || !std::isfinite(x2)) {
2061  O2SCL_ERR("x1 or x2 not finite in table::integ_const().",exc_einval);
2062  return exc_einval;
2063  }
2064  interp_vec<vec_t> sic
2065  (nlines,itx->second.dat,ity->second.dat,itype);
2066  ret=sic.integ(x1,x2);
2067  return ret;
2068  }
2069 
2070  /** \brief Compute the integral of the function defined
2071  by x-values stored in column with index \c ix and y-values stored
2072  in column with index \c iy between the values \c x1 and \c x2
2073 
2074  O(log(R)) but can be as bad as O(R) if
2075  the relevant columns are not well ordered.
2076  */
2077  double integ(size_t ix, double x1, double x2, size_t iy) {
2078  return integ(get_column_name(ix),x1,x2,
2079  get_column_name(iy));
2080  }
2081 
2082  /** \brief Compute the integral of the function defined
2083  by x-values stored in column with index \c ix and y-values stored
2084  in column with index \c iy between the values \c x1 and \c x2
2085  (const version)
2086 
2087  O(log(R)) but can be as bad as O(R) if
2088  the relevant columns are not well ordered.
2089  */
2090  double integ_const(size_t ix, double x1, double x2, size_t iy) const {
2091  return integ_const(get_column_name(ix),x1,x2,
2092  get_column_name(iy));
2093  }
2094 
2095  /** \brief Create a new column named \c ynew which is
2096  equal to the integral of the function defined by
2097  x-values stored in column named \c x and y-values
2098  stored in column named \c y
2099 
2100  This function is O(log(R)) but can be as bad as O(R) if the
2101  relevant columns are not well ordered.
2102 
2103  If the column \c ynew is not already in the table it is
2104  automatically created.
2105  */
2106  void integ(std::string x, std::string y, std::string ynew) {
2107  aiter itx, ity, itynew;
2108 
2109  itx=atree.find(x);
2110  ity=atree.find(y);
2111  itynew=atree.find(ynew);
2112 
2113  if (itynew==atree.end()) {
2114  new_column(ynew);
2115  itynew=atree.find(ynew);
2116  }
2117 
2118  if (itx==atree.end() || ity==atree.end() || itynew==atree.end()) {
2119  O2SCL_ERR("Column not found in table::integ(string,string,string).",
2120  exc_enotfound);
2121  return;
2122  }
2123 
2124  size_t ix=lookup_column(x);
2125  size_t iy=lookup_column(y);
2126  for(size_t i=0;i<nlines;i++) {
2127  itynew->second.dat[i]=integ(ix,(itx->second.dat)[0],
2128  (itx->second.dat)[i],iy);
2129  }
2130 
2131  return;
2132  }
2133 
2134  /** \brief Return column maximum. Makes no assumptions about
2135  ordering, \f$ {\cal O}(R) \f$
2136  */
2137  double max(std::string scol) const {
2138  double ret=0.0;
2139  int i;
2140  if (is_column(scol)==false) {
2141  O2SCL_ERR((((std::string)"Column '")+scol+
2142  "' not found in table::max().").c_str(),exc_enotfound);
2143  return 0.0;
2144  }
2145  const vec_t &dcol=get_column(scol);
2146  bool setb=false;
2147  for(i=0;i<((int)nlines);i++) {
2148  if (std::isfinite(dcol[i])) {
2149  if (setb==false) {
2150  ret=dcol[i];
2151  setb=true;
2152  } else if (dcol[i]>ret) {
2153  ret=dcol[i];
2154  }
2155  }
2156  }
2157  if (setb==false) {
2158  O2SCL_ERR((((std::string)"No finite values in column '")+scol+
2159  "' in table::max().").c_str(),exc_efailed);
2160  return 0.0;
2161  }
2162  return ret;
2163  }
2164 
2165  /** \brief Return column minimum. Makes no assumptions about
2166  ordering, \f$ {\cal O}(R) \f$
2167  */
2168  double min(std::string scol) const {
2169  double ret=0.0;
2170  int i;
2171  if (is_column(scol)==false) {
2172  O2SCL_ERR((((std::string)"Column '")+scol+
2173  "' not found in table::min().").c_str(),exc_enotfound);
2174  return 0.0;
2175  }
2176  const vec_t &dcol=get_column(scol);
2177  bool setb=false;
2178  for(i=0;i<((int)nlines);i++) {
2179  if (std::isfinite(dcol[i])) {
2180  if (setb==false) {
2181  ret=dcol[i];
2182  setb=true;
2183  } else if (dcol[i]<ret) {
2184  ret=dcol[i];
2185  }
2186  }
2187  }
2188  if (setb==false) {
2189  O2SCL_ERR((((std::string)"No finite values in column '")+scol+
2190  "' in table::min().").c_str(),exc_efailed);
2191  return 0.0;
2192  }
2193  return ret;
2194  }
2195  //@}
2196 
2197  // --------------------------------------------------------
2198  /** \name Subtable method */
2199  //@{
2200 
2201  /** \brief Make a subtable
2202 
2203  Uses the columns specified in \c list from the row \c top
2204  to the row of index \c bottom to generate a new table
2205  which is a copy of part of the original.
2206  */
2207  void subtable(std::string list, size_t top,
2208  size_t bottom, table<vec_t> &tnew) const {
2209 
2210  tnew.clear_all();
2211  int sublines, i;
2212  std::string head;
2213  aciter it;
2214 
2215  if (top>bottom) {
2216  size_t tmp=bottom;
2217  bottom=top;
2218  top=tmp;
2219  }
2220  sublines=bottom-top+1;
2221  if (nlines==0) {
2222  O2SCL_ERR2("Can't make a subtable of an empty table. ",
2223  "Returning 0 in table::subtable().",
2224  exc_einval);
2225  return;
2226  }
2227  if (bottom+1>nlines) {
2228  O2SCL_ERR2("Requested row beyond nlines. Adjusting ",
2229  "and continuing in table::subtable().",exc_einval);
2230  bottom=nlines-1;
2231  }
2232 
2233  std::istringstream is(list);
2234 
2235  tnew.set_nlines(sublines);
2236  while(is >> head) {
2237  it=atree.find(head);
2238  if (it==atree.end()) {
2239  O2SCL_ERR
2240  ((((std::string)"Couldn't find column named ")+head+
2241  " in table::subtable(). Returning 0.").c_str(),
2242  exc_einval);
2243  }
2244  tnew.new_column(head);
2245  vec_t &dcol=tnew.get_column(head);
2246  for(i=0;i<sublines;i++) {
2247  dcol[i]=it->second.dat[i+top];
2248  }
2249  }
2250  if (tnew.get_ncolumns()==0) {
2251  O2SCL_ERR("Subtable has no columns in table::subtable().",
2252  exc_einval);
2253  }
2254  //}
2255  tnew.nlines=sublines;
2256 
2257  return;
2258  }
2259  //@}
2260 
2261  // --------------------------------------------------------
2262  /** \name Clear methods */
2263  //@{
2264 
2265  /** \brief Zero the data entries but keep the column names
2266  and nlines fixed
2267  */
2268  void zero_table() {
2269  aiter it;
2270  for(it=atree.begin();it!=atree.end();it++) {
2271  for(int j=0;j<((int)nlines);j++) {
2272  it->second.dat[j]=0.0;
2273  }
2274  }
2275 
2276  if (intp_set) {
2277  intp_set=false;
2278  delete si;
2279  }
2280 
2281  return;
2282  }
2283 
2284  /** \brief Clear everything
2285  */
2286  virtual void clear() {
2287  clear_table();
2288  clear_constants();
2289  return;
2290  }
2291 
2292  /** \brief Clear the table and the column names (but leave constants)
2293  */
2294  virtual void clear_table() {
2295  atree.clear();
2296  alist.clear();
2297  nlines=0;
2298  if (intp_set==true) {
2299  delete si;
2300  intp_set=false;
2301  }
2302  return;
2303  }
2304 
2305  /** \brief Remove all of the data by setting the number
2306  of lines to zero
2307 
2308  This leaves the column names intact and does not remove
2309  the constants.
2310  */
2311  void clear_data() {
2312  nlines=0;
2313  if (intp_set==true) {
2314  delete si;
2315  intp_set=false;
2316  }
2317  return;
2318  }
2319 
2320  /// CLear all constants
2322  constants.clear();
2323  return;
2324  }
2325  //@}
2326 
2327  // --------------------------------------------------------
2328  /** \name Sorting methods */
2329  //@{
2330 
2331  /** \brief Sort the entire table by the column \c scol
2332 
2333  \note This function works by allocating space for an entirely
2334  new chunk of memory for the data in the table.
2335  */
2336  void sort_table(std::string scol) {
2337 
2338  size_t ncols=get_ncolumns(), nlins=get_nlines();
2339 
2340  // Make a copy of the table
2341  boost::numeric::ublas::matrix<double> data_copy(ncols,nlins);
2342  for(size_t i=0;i<ncols;i++) {
2343  for(size_t j=0;j<nlins;j++) {
2344  data_copy(i,j)=get(i,j);
2345  }
2346  }
2347 
2348  permutation order(nlins);
2349  aiter it=atree.find(scol);
2350  vec_t &data=it->second.dat;
2351  vector_sort_index(nlins,data,order);
2352  for(size_t i=0;i<ncols;i++) {
2353  for(size_t j=0;j<nlins;j++) {
2354  set(i,j,data_copy(i,order[j]));
2355  }
2356  }
2357 
2358  if (intp_set) {
2359  intp_set=false;
2360  delete si;
2361  }
2362 
2363  return;
2364  }
2365 
2366  /** \brief Individually sort the column \c scol
2367  */
2368  void sort_column(std::string scol) {
2369  int i;
2370  aiter it=atree.find(scol);
2371  if (it==atree.end()) {
2372  O2SCL_ERR((((std::string)"Column '")+scol+
2373  " not found in table::sort_column().").c_str(),
2374  exc_enotfound);
2375  return;
2376  }
2377 
2378  vector_sort_double(nlines,it->second.dat);
2379 
2380  if (intp_set && (scol==intp_colx || scol==intp_coly)) {
2381  intp_set=false;
2382  delete si;
2383  }
2384 
2385  return;
2386  }
2387  //@}
2388 
2389  // --------------------------------------------------------
2390  /** \name Summary method */
2391  //@{
2392  /** \brief Output a summary of the information stored
2393 
2394  Outputs the number of constants, the number of columns,
2395  a list of the column names, and the number of lines of
2396  data.
2397  */
2398  virtual void summary(std::ostream *out, size_t ncol=79) const {
2399 
2400  if (constants.size()==1) {
2401  (*out) << "1 constant:" << std::endl;
2402  } else {
2403  (*out) << constants.size() << " constants:" << std::endl;
2404  }
2405  std::map<std::string,double>::const_iterator mit;
2406  for(mit=constants.begin();mit!=constants.end();mit++) {
2407  (*out) << mit->first << " " << mit->second << std::endl;
2408  }
2409 
2410  // Output number of columns and preprend column numbers
2411  size_t nh=get_ncolumns(), nh2;
2412 
2413  if (nh==0) {
2414 
2415  (*out) << "No columns." << std::endl;
2416 
2417  } else {
2418 
2419  if (nh==1) {
2420  (*out) << "1 column: " << std::endl;
2421  } else {
2422  (*out) << nh << " columns: " << std::endl;
2423  }
2424  std::vector<std::string> h(nh);
2425  for(size_t i=0;i<nh;i++) {
2426  h[i]=szttos(i)+". "+get_column_name(i);
2427  }
2428 
2429  std::vector<std::string> h2;
2430  // Convert to string with width 'ncol'
2431  screenify(nh,h,h2,ncol);
2432  nh2=h2.size();
2433 
2434  // Output column names
2435  for(size_t i=0;i<nh2;i++) {
2436  (*out) << h2[i] << std::endl;
2437  }
2438 
2439  }
2440 
2441  if (get_nlines()==0) (*out) << "No lines of data." << std::endl;
2442  else if (get_nlines()==1) (*out) << "One line of data." << std::endl;
2443  (*out) << get_nlines() << " lines of data." << std::endl;
2444 
2445  return;
2446  }
2447  //@}
2448 
2449  /// \name Constant manipulation
2450  //@{
2451  /** \brief Add a constant, or if the constant already exists, change
2452  its value
2453  */
2454  virtual void add_constant(std::string name, double val) {
2455  if (constants.find(name)!=constants.end()) {
2456  constants.find(name)->second=val;
2457  return;
2458  }
2459  constants.insert(make_pair(name,val));
2460  return;
2461  }
2462 
2463  /** \brief Set a constant equal to a value, but don't add it if
2464  not already present
2465 
2466  If \c err_on_notfound is <tt>true</tt> (the default), then
2467  this function throws an exception if a constant with
2468  name \c name is not found. If \c err_on_notfound is
2469  <tt>false</tt>, then if a constant with name \c name
2470  is not found this function just silently returns
2471  \ref o2scl::exc_enotfound.
2472  */
2473  virtual int set_constant(std::string name, double val,
2474  bool err_on_notfound=true) {
2475  if (constants.find(name)!=constants.end()) {
2476  constants.find(name)->second=val;
2477  return 0;
2478  }
2479  if (err_on_notfound) {
2480  std::string err=((std::string)"No constant with name '")+name+
2481  "' in table::set_constant().";
2482  O2SCL_ERR(err.c_str(),exc_enotfound);
2483  }
2484  return exc_enotfound;
2485  }
2486 
2487  /// Test if \c name is a constant
2488  virtual bool is_constant(std::string name) const {
2489  if (constants.find(name)==constants.end()) {
2490  return false;
2491  }
2492  return true;
2493  }
2494 
2495  /// Get a constant
2496  virtual double get_constant(std::string name) const {
2497  if (constants.find(name)==constants.end()) {
2498  std::string err=((std::string)"No constant with name '")+name+
2499  "' in table::get_constant(string).";
2500  O2SCL_ERR(err.c_str(),exc_einval);
2501  }
2502  return constants.find(name)->second;
2503  }
2504 
2505  /// Get the number of constants
2506  virtual size_t get_nconsts() const {
2507  return constants.size();
2508  }
2509 
2510  /// Get a constant by index
2511  virtual void get_constant(size_t ix, std::string &name, double &val) const {
2512  if (ix<constants.size()) {
2513  std::map<std::string,double>::const_iterator cit=constants.begin();
2514  for(size_t i=0;i<ix;i++) cit++;
2515  name=cit->first;
2516  val=cit->second;
2517  return;
2518  }
2519  O2SCL_ERR("Index too large in table::get_constant(size_t,string,double).",
2520  exc_eindex);
2521  return;
2522  }
2523 
2524  /// Remove a constant
2525  virtual void remove_constant(std::string name) {
2526  if (constants.find(name)==constants.end()) {
2527  O2SCL_ERR2("Constant not present in ",
2528  "table::remove_constant().",o2scl::exc_einval);
2529  }
2530  constants.erase(name);
2531  return;
2532  }
2533  //@}
2534 
2535  /// \name Miscellaneous methods
2536  //@{
2537  /// Clear the current table and read from a generic data file
2538  virtual int read_generic(std::istream &fin, int verbose=0) {
2539 
2540  double data;
2541  std::string line;
2542  std::string cname;
2543 
2544  // Read first line and into list
2545  std::vector<std::string> onames, nnames;
2546  getline(fin,line);
2547  std::istringstream is(line);
2548  while (is >> cname) {
2549  onames.push_back(cname);
2550  if (verbose>2) {
2551  std::cout << "Read possible column name: " << cname << std::endl;
2552  }
2553  }
2554 
2555  // Count number of likely numbers in the first row
2556  size_t n_nums=0;
2557  for(size_t i=0;i<onames.size();i++) {
2558  if (is_number(onames[i])) n_nums++;
2559  }
2560 
2561  int irow=0;
2562 
2563  if (n_nums==onames.size()) {
2564 
2565  if (verbose>0) {
2566  std::cout << "First row looks like it contains numerical values."
2567  << std::endl;
2568  std::cout << "Creating generic column names: ";
2569  }
2570 
2571  for(size_t i=0;i<onames.size();i++) {
2572  nnames.push_back(((std::string)"c")+szttos(i+1));
2573  if (verbose>0) std::cout << nnames[i] << " ";
2574 
2575  }
2576  if (verbose>0) std::cout << std::endl;
2577 
2578  // Make columns
2579  for(size_t i=0;i<nnames.size();i++) {
2580  new_column(nnames[i]);
2581  }
2582 
2583  // Add first row of data
2584  set_nlines_auto(irow+1);
2585  for(size_t i=0;i<onames.size();i++) {
2586  set(i,irow,o2scl::stod(onames[i]));
2587  }
2588  irow++;
2589 
2590  } else {
2591 
2592  // Ensure good column names
2593  for(size_t i=0;i<onames.size();i++) {
2594  std::string temps=onames[i];
2595  make_fp_varname(temps);
2596  make_unique_name(temps,nnames);
2597  nnames.push_back(temps);
2598  if (temps!=onames[i] && verbose>0) {
2599  std::cout << "Converted column named '" << onames[i] << "' to '"
2600  << temps << "'." << std::endl;
2601  }
2602  }
2603 
2604  // Make columns
2605  for(size_t i=0;i<nnames.size();i++) {
2606  new_column(nnames[i]);
2607  }
2608 
2609  }
2610 
2611  // Read remaining rows
2612  while ((fin) >> data) {
2613  set_nlines_auto(irow+1);
2614  set(0,irow,data);
2615  for(size_t i=1;i<get_ncolumns();i++) {
2616  (fin) >> data;
2617  set(i,irow,data);
2618  }
2619  irow++;
2620  }
2621 
2622  if (intp_set) {
2623  intp_set=false;
2624  delete si;
2625  }
2626 
2627  return 0;
2628  }
2629 
2630  /** \brief Check if the tree and list are properly synchronized
2631  */
2632  void check_synchro() const {
2633  if (atree.size()!=alist.size()) {
2634  O2SCL_ERR2("Size of table and list do not match in ",
2635  "table::check_synchro().",exc_esanity);
2636  return;
2637  }
2638  for(aciter it=atree.begin();it!=atree.end();it++) {
2639  if (it->second.index!=alist[it->second.index]->second.index) {
2640  O2SCL_ERR((((std::string)"Problem with iterator for entry '")+
2641  it->first+"' in list in table::check_synchro().").c_str(),
2642  exc_esanity);
2643  }
2644  }
2645  for(int i=0;i<((int)atree.size());i++) {
2646  if (alist[i]->second.index!=i) {
2647  O2SCL_ERR((((std::string)"Problem with index of entry ")+
2648  itos(i)+" in list in table::check_synchro().").c_str(),
2649  exc_esanity);
2650  return;
2651  }
2652  }
2653  return;
2654  }
2655 
2656  /** \brief Check if the table object appears to be valid
2657  */
2658  void is_valid() const {
2659  if (maxlines<nlines) {
2660  O2SCL_ERR2("Value of maxlines smaller than nlines ",
2661  "in table::is_valid().",exc_esanity);
2662  }
2663  if (atree.size()!=alist.size()) {
2664  O2SCL_ERR2("Size of table and list do not match in ",
2665  "table::is_valid().",exc_esanity);
2666  return;
2667  }
2668  for(aciter it=atree.begin();it!=atree.end();it++) {
2669  if (it->second.dat.size()!=maxlines) {
2670  O2SCL_ERR2("Vector with size different than maxlines ",
2671  "in table::is_valid().",exc_esanity);
2672  }
2673  if (it->second.index!=alist[it->second.index]->second.index) {
2674  O2SCL_ERR((((std::string)"Problem with iterator for entry '")+
2675  it->first+"' in list in table::is_valid().").c_str(),
2676  exc_esanity);
2677  }
2678  }
2679  for(int i=0;i<((int)atree.size());i++) {
2680  if (alist[i]->second.index!=i) {
2681  O2SCL_ERR((((std::string)"Problem with index of entry ")+
2682  itos(i)+" in list in table::is_valid().").c_str(),
2683  exc_esanity);
2684  return;
2685  }
2686  }
2687  return;
2688  }
2689 
2690  /// Return the type, \c "table".
2691  virtual const char *type() { return "table"; }
2692  //@}
2693 
2694  /** \name Parsing mathematical functions specified as strings
2695  */
2696  //@{
2697  /** \brief Create new columns or recompute from a list of functions
2698 
2699  The list should be a space-delimited list of entries of the
2700  form <tt>name=function</tt> where <tt>name</tt> is the
2701  column name and <tt>function</tt> the function specifing the
2702  values for the column. If a column named <tt>name</tt> is
2703  already present, it is overwritten. Otherwise, a new column
2704  is created.
2705 
2706  \comment
2707  The formulas in \c list may depend on any of the column names
2708  that will be defined later in \c list. For example, for a
2709  table initially containing two columns, \c x and \c y, the
2710  calls
2711  \code
2712  function_columns("a=2*z z=x+y");
2713  \endcode
2714  \code
2715  function_columns("z=x+y a=2*z");
2716  \endcode
2717  both work.
2718  Circular dependencies do not work, for example
2719  \code
2720  function_columns("a=2*z z=a*3");
2721  \endcode
2722  will cause the error handler to be thrown.
2723  \endcomment
2724  */
2725  void functions_columns(std::string list) {
2726 
2727  // Separate the list into names and functions
2728  std::vector<std::string> funcs, names;
2729  {
2730  std::string stemp;
2731  std::istringstream is(list);
2732  while(is >> stemp) funcs.push_back(stemp);
2733  for(size_t i=0;i<(funcs.size());i++) {
2734  names.push_back(funcs[i].substr(0,funcs[i].find("=")));
2735  funcs[i]=funcs[i].substr(funcs[i].find("=")+1,
2736  funcs[i].length()-funcs[i].find("=")-1);
2737  if (names[i].length()==0 || funcs[i].length()==0) {
2738  O2SCL_ERR2("Name or function blank in ",
2739  "table::functions_columns().",exc_einval);
2740  }
2741  }
2742  }
2743 
2744  std::map<std::string,double> vars;
2745  std::map<std::string,double>::const_iterator mit;
2746  for(mit=constants.begin();mit!=constants.end();mit++) {
2747  vars[mit->first]=mit->second;
2748  }
2749 
2750  std::vector<calculator> calcs(funcs.size());
2751  std::vector<vec_t> newcols(funcs.size());
2752 
2753  for(size_t j=0;j<funcs.size();j++) {
2754  calcs[j].compile(funcs[j].c_str(),&vars);
2755  newcols[j].resize(maxlines);
2756  }
2757 
2758  // Calculate all of the columns in the newcols list:
2759  for(size_t i=0;i<nlines;i++) {
2760 
2761  // Record the values of the variables for this line:
2762  for(size_t j=0;j<atree.size();j++) {
2763  vars[get_column_name(j)]=(*this)[j][i];
2764  }
2765 
2766  // Evaluate the new columns
2767  for(size_t j=0;j<funcs.size();j++) {
2768  newcols[j][i]=calcs[j].eval(&vars);
2769  }
2770  }
2771 
2772  for(size_t j=0;j<funcs.size();j++) {
2773  if (!is_column(names[j])) {
2774  new_column(names[j]);
2775  }
2776  swap_column_data(names[j],newcols[j]);
2777  }
2778 
2779  return;
2780  }
2781 
2782  /** \brief Make a column from the function specified in
2783  <tt>function</tt> and add it to the table.
2784 
2785  If a column named \c scol already exists, the data already
2786  present is overwritten with the result. Otherwise, a new
2787  column is created and filled with the result.
2788  */
2789  void function_column(std::string function, std::string scol) {
2790  int ret, i, j;
2791  std::string vlist;
2792  aiter it;
2793 
2794  // Create new column if necessary
2795  if (!is_column(scol)) {
2796  new_column(scol);
2797  }
2798 
2799  // Find vector reference
2800  aiter it2=atree.find(scol);
2801  vec_t &colp=it2->second.dat;
2802 
2803  // Fill vector with result of function
2804  function_vector(function,colp);
2805 
2806  return;
2807  }
2808 
2809  /** \brief Compute a column from a function specified
2810  in a string
2811 
2812  The type \c resize_vec_t must have <tt>resize()</tt> and
2813  <tt>size()</tt> methods. If \c vec does not have enough space to
2814  hold the number of entries given by \ref get_nlines(), it is
2815  resized.
2816 
2817  \comment
2818  This function must return an int rather than void because
2819  of the presence of the 'throw_on_err' mechanism
2820  \endcomment
2821  */
2822  template<class resize_vec_t>
2823  int function_vector(std::string function, resize_vec_t &vec,
2824  bool throw_on_err=true) {
2825 
2826  // Parse function
2827  calculator calc;
2828  std::map<std::string,double> vars;
2829  std::map<std::string,double>::const_iterator mit;
2830  for(mit=constants.begin();mit!=constants.end();mit++) {
2831  vars[mit->first]=mit->second;
2832  }
2833  calc.compile(function.c_str(),&vars);
2834 
2835  // Resize vector if necessary
2836  if (vec.size()<nlines) vec.resize(nlines);
2837 
2838  // Create space for column values
2839  std::vector<double> vals(atree.size());
2840 
2841  // Create column from function
2842  for(size_t j=0;j<nlines;j++) {
2843  for(aciter it=atree.begin();it!=atree.end();it++) {
2844  vars[it->first]=it->second.dat[j];
2845  }
2846  vec[j]=calc.eval(&vars);
2847  }
2848 
2849  return 0;
2850  }
2851 
2852  /** \brief Compute a value by applying a function to a row
2853  */
2854  double row_function(std::string function, size_t row) const {
2855 
2856  // Parse function
2857  calculator calc;
2858  std::map<std::string,double> vars;
2859  std::map<std::string,double>::const_iterator mit;
2860  for(mit=constants.begin();mit!=constants.end();mit++) {
2861  vars[mit->first]=mit->second;
2862  }
2863  calc.compile(function.c_str(),&vars);
2864 
2865  for(aciter it=atree.begin();it!=atree.end();it++) {
2866  vars[it->first]=it->second.dat[row];
2867  }
2868 
2869  double dret=calc.eval(&vars);
2870  return dret;
2871  }
2872 
2873  /** \brief Find a row which maximizes a function
2874  */
2875  size_t function_find_row(std::string function) const {
2876 
2877  // Parse function
2878  calculator calc;
2879  std::map<std::string,double> vars;
2880  std::map<std::string,double>::const_iterator mit;
2881  for(mit=constants.begin();mit!=constants.end();mit++) {
2882  vars[mit->first]=mit->second;
2883  }
2884  calc.compile(function.c_str(),&vars);
2885 
2886  double best_val=0.0;
2887  size_t best_row=0;
2888  for(size_t row=0;row<nlines-1;row++) {
2889  for(aciter it=atree.begin();it!=atree.end();it++) {
2890  vars[it->first]=it->second.dat[row];
2891  }
2892  double dtemp=calc.eval(&vars);
2893  if (row==0) {
2894  best_val=dtemp;
2895  } else {
2896  if (dtemp>best_val) {
2897  best_val=dtemp;
2898  best_row=row;
2899  }
2900  }
2901  }
2902 
2903  return best_row;
2904  }
2905  //@}
2906 
2907  // --------------------------------------------------------
2908  // Allow HDF5 I/O functions to access table data
2909 
2910  friend void o2scl_hdf::hdf_output
2911  (o2scl_hdf::hdf_file &hf, table<> &t, std::string name);
2912 
2913  template<class vecf_t> friend void o2scl_hdf::hdf_input
2914  (o2scl_hdf::hdf_file &hf, table<vecf_t> &t, std::string name);
2915 
2916  friend void o2scl_hdf::hdf_output_data
2917  (o2scl_hdf::hdf_file &hf, table<> &t);
2918 
2919  template<class vecf_t> friend void o2scl_hdf::hdf_input_data
2921 
2922  // --------------------------------------------------------
2923  // Allow matrix_view_table and matrix_view_table_transpose access
2924 
2925  template<typename vecf_t> friend class matrix_view_table;
2926  template<typename vecf_t> friend class matrix_view_table_transpose;
2927 
2928  // --------------------------------------------------------
2929 
2930 #ifndef DOXYGEN_INTERNAL
2931 
2932  protected:
2933 
2934  /** \brief Returns a non-const reference to the column named \c col.
2935  \f$ {\cal O}(\log(C)) \f$
2936  */
2937  vec_t &get_column_no_const(std::string scol) {
2938  aiter it=atree.find(scol);
2939  if (it==atree.end()) {
2940  O2SCL_ERR((((std::string)"Column '")+scol+
2941  "' not found in table::get_column() const.").c_str(),
2942  exc_enotfound);
2943  return empty_col;
2944  }
2945  return it->second.dat;
2946  }
2947  /** \brief Set the elements of alist with the appropriate
2948  iterators from atree. \f$ {\cal O}(C) \f$
2949 
2950  Generally, the end-user shouldn't need this method. It is
2951  only used in delete_column() to rearrange the list when
2952  a column is deleted from the tree.
2953  */
2954  void reset_list() {
2955  aiter it;
2956  for(it=atree.begin();it!=atree.end();it++) {
2957  alist[it->second.index]=it;
2958  }
2959  return;
2960  }
2961 
2962  /** \brief Ensure a variable name does not match a function or contain
2963  non-alphanumeric characters
2964  */
2965  void make_fp_varname(std::string &s) {
2966  if (s=="abs" || s=="acos" || s=="acosh" || s=="asin" ||
2967  s=="asinh" || s=="atan" || s=="atan2" || s=="atanh" ||
2968  s=="ceil" || s=="cos" || s=="cosh" || s=="cot" || s=="csc" ||
2969  s=="eval" || s=="exp" || s=="floor" || s=="if" || s=="int" ||
2970  s=="log" || s=="log10" || s=="max" || s=="min" || s=="sec" ||
2971  s=="sin" || s=="sinh" || s=="sqrt" || s=="tan" || s=="tanh") {
2972  s=((std::string)"v_")+s;
2973  } else if (s[0]>='0' && s[0]<='9') {
2974  s=((std::string)"v_")+s;
2975  }
2976 
2977  for(size_t i=0;i<s.length();i++) {
2978  if (!isalpha(s[i]) && !isdigit(s[i]) && s[i]!='_') s[i]='_';
2979  }
2980 
2981  return;
2982  }
2983 
2984  /// Make sure a name is unique
2985  void make_unique_name(std::string &colx, std::vector<std::string> &cnames) {
2986  bool done;
2987 
2988  do {
2989  done=true;
2990  for(size_t i=0;i<cnames.size();i++) {
2991  if (colx==cnames[i]) {
2992  done=false;
2993  i=cnames.size();
2994  }
2995  }
2996  if (done==false) {
2997  colx+='_';
2998  }
2999  } while (done==false);
3000 
3001  return;
3002  }
3003 
3004  /** \brief The list of constants
3005  */
3006  std::map<std::string,double> constants;
3007 
3008  /** \brief Column structure for \ref table [protected]
3009 
3010  This struct is used internally by \ref table to organize the
3011  columns and need not be instantiated by the casual end-user.
3012  */
3013  class col {
3014  public:
3015  /// Pointer to column
3016  vec_t dat;
3017  /// Column index
3018  int index;
3019  col() {
3020  }
3021  /** \brief Copy constructor
3022  */
3023  col(const col &c) {
3024  dat=c.dat;
3025  index=c.index;
3026  }
3027  /** \brief Copy constructor for assignment operator
3028  */
3029  col &operator=(const col &c) {
3030  if (this!=&c) {
3031  dat=c.dat;
3032  index=c.index;
3033  }
3034  return *this;
3035  }
3036  };
3037 
3038  /// \name Iterator types
3039  //@{
3040  /// Map iterator type
3041  typedef typename std::map<std::string,col,
3042  std::greater<std::string> >::iterator aiter;
3043  /// Const map iterator type
3044  typedef typename std::map<std::string,col,
3045  std::greater<std::string> >::const_iterator
3047  /// Vector iterator type
3048  typedef typename std::vector<aiter>::iterator aviter;
3049  //@}
3050 
3051  /// \name Actual data
3052  //@{
3053  /// The size of allocated memory
3054  size_t maxlines;
3055  /// The size of presently used memory
3056  size_t nlines;
3057  /// The tree of columns
3058  std::map<std::string,col,std::greater<std::string> > atree;
3059  /// The list of tree iterators
3060  std::vector<aiter> alist;
3061  //@}
3062 
3063  /// \name Column manipulation methods
3064  //@{
3065  /// Return the iterator for a column
3066  aiter get_iterator(std::string lname) {
3067  aiter it=atree.find(lname);
3068  if (it==atree.end()) {
3069  O2SCL_ERR((((std::string)"Column '")+lname+
3070  " not found in table::get_iterator().").c_str(),
3071  exc_enotfound);
3072  }
3073  return it;
3074  }
3075  /// Return the column structure for a column
3076  col *get_col_struct(std::string lname) {
3077  aiter it=atree.find(lname);
3078  if (it==atree.end()) {
3079  O2SCL_ERR((((std::string)"Column '")+lname+
3080  " not found in table::get_col_struct().").c_str(),
3081  exc_enotfound);
3082  return 0;
3083  }
3084  return &(it->second);
3085  }
3086  /// Return the beginning of the column tree
3087  aiter begin() { return atree.begin(); }
3088  /// Return the end of the column tree
3089  aiter end() { return atree.end(); }
3090  //@}
3091 
3092  /// An empty vector for get_column()
3093  vec_t empty_col;
3094 
3095  /// \name Interpolation
3096  //@{
3097  /// True if the interpolation object is up-to-date
3098  bool intp_set;
3099 
3100  /// Current interpolation type
3101  size_t itype;
3102 
3103  /// Interpolation object
3105 
3106  /// The last x-column interpolated
3107  std::string intp_colx;
3108 
3109  /// The last y-column interpolated
3110  std::string intp_coly;
3111  //@}
3112 
3113 #endif
3114 
3115  };
3116 
3117  /** \brief View a o2scl::table object as a matrix
3118 
3119  \note This stores a pointer to the table and the user must ensure
3120  that the pointer is valid with the matrix view is accessed.
3121  */
3122  template<class vec_t=std::vector<double> >
3124 
3125  protected:
3126 
3127  /// The number of columns
3128  size_t nc;
3129  /// The number of lines in the table
3130  size_t nlines;
3131  /// Pointers to each column
3132  std::vector<const vec_t *> col_ptrs;
3133 
3134  public:
3135 
3136  /** \brief Create a matrix view object from the specified
3137  table and list of columns
3138  */
3140  nc=0;
3141  nlines=0;
3142  }
3143 
3144  /** \brief Create a matrix view object from the specified
3145  table and list of columns
3146  */
3148  std::vector<std::string> cols) {
3149  set(t,cols);
3150  }
3151 
3152  /** \brief Create a matrix view object from the specified
3153  table and list of columns
3154  */
3156  std::vector<std::string> cols) {
3157  nc=cols.size();
3158  col_ptrs.resize(nc);
3159  for(size_t i=0;i<nc;i++) {
3160  col_ptrs[i]=&t[cols[i]];
3161  }
3162  nlines=t.get_nlines();
3163  }
3164 
3165  /** \brief Return the number of rows
3166  */
3167  size_t size1() {
3168  return nlines;
3169  }
3170 
3171  /** \brief Return the number of columns
3172  */
3173  size_t size2() {
3174  if (nlines==0) return 0;
3175  return nc;
3176  }
3177 
3178  /** \brief Return a reference to the element at row \c row
3179  and column \c col
3180  */
3181  const double &operator()(size_t row, size_t col) const {
3182  if (row>=nlines) {
3183  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3184  " >= "+o2scl::szttos(nlines)+" in const_matrix_view_table"+
3185  "::operator().";
3186  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3187  }
3188  if (col>=nc) {
3189  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3190  " >= "+o2scl::szttos(nc)+" in const_matrix_view_table"+
3191  "::operator().";
3192  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3193  }
3194  const vec_t *cp=col_ptrs[col];
3195  return (*cp)[row];
3196  }
3197 
3198  /** \brief Swap method
3199  */
3202  using std::swap;
3203  swap(t1.nc,t2.nc);
3204  swap(t1.nlines,t2.nlines);
3205  swap(t1.col_ptrs,t2.col_ptrs);
3206  return;
3207  }
3208 
3209  };
3210 
3211  /** \brief View a o2scl::table object as a matrix
3212 
3213  \note This stores a pointer to the table and the user must ensure
3214  that the pointer is valid with the matrix view is accessed.
3215  */
3216  template<class vec_t=std::vector<double> >
3217  class matrix_view_table : public matrix_view {
3218 
3219  protected:
3220 
3221  /// The number of columns
3222  size_t nc;
3223  /// The number of lines in the table
3224  size_t nlines;
3225  /// Pointers to each column
3226  std::vector<vec_t *> col_ptrs;
3227 
3228  public:
3229 
3230  /** \brief Create a matrix view object from the specified
3231  table and list of columns
3232  */
3234  nc=0;
3235  nlines=0;
3236  }
3237 
3238  /** \brief Create a matrix view object from the specified
3239  table and list of columns
3240  */
3242  std::vector<std::string> cols) {
3243  set(t,cols);
3244  }
3245 
3246  /** \brief Create a matrix view object from the specified
3247  table and list of columns
3248  */
3250  std::vector<std::string> cols) {
3251  nc=cols.size();
3252  col_ptrs.resize(nc);
3253  for(size_t i=0;i<nc;i++) {
3254  col_ptrs[i]=&t.get_column_no_const(cols[i]);
3255  }
3256  nlines=t.get_nlines();
3257  }
3258 
3259  /** \brief Return the number of rows
3260  */
3261  size_t size1() {
3262  return nlines;
3263  }
3264 
3265  /** \brief Return the number of columns
3266  */
3267  size_t size2() {
3268  if (nlines==0) return 0;
3269  return nc;
3270  }
3271 
3272  /** \brief Return a reference to the element at row \c row
3273  and column \c col
3274  */
3275  const double &operator()(size_t row, size_t col) const {
3276  if (row>=nlines) {
3277  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3278  " >= "+o2scl::szttos(nlines)+" in matrix_view_table"+
3279  "::operator().";
3280  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3281  }
3282  if (col>=nc) {
3283  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3284  " >= "+o2scl::szttos(nc)+" in matrix_view_table"+
3285  "::operator().";
3286  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3287  }
3288  const vec_t *cp=col_ptrs[col];
3289  return (*cp)[row];
3290  }
3291 
3292  /** \brief Return a reference to the element at row \c row
3293  and column \c col
3294  */
3295  double &operator()(size_t row, size_t col) {
3296  if (row>=nlines) {
3297  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3298  " >= "+o2scl::szttos(nlines)+" in matrix_view_table"+
3299  "::operator().";
3300  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3301  }
3302  if (col>=nc) {
3303  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3304  " >= "+o2scl::szttos(nc)+" in matrix_view_table"+
3305  "::operator().";
3306  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3307  }
3308  vec_t *cp=col_ptrs[col];
3309  return (*cp)[row];
3310  }
3311 
3312  /** \brief Swap method
3313  */
3314  friend void swap(matrix_view_table &t1,
3315  matrix_view_table &t2) {
3316  using std::swap;
3317  swap(t1.nc,t2.nc);
3318  swap(t1.nlines,t2.nlines);
3319  swap(t1.col_ptrs,t2.col_ptrs);
3320  return;
3321  }
3322 
3323  };
3324 
3325  /** \brief View a o2scl::table object as a matrix
3326 
3327  \note This stores a pointer to the table and the user must ensure
3328  that the pointer is valid with the matrix view is accessed.
3329  */
3330  template<class vec_t=std::vector<double> >
3331  class matrix_view_table_transpose : public matrix_view {
3332 
3333  protected:
3334 
3335  /// The number of rows
3336  size_t nr;
3337  /// The number of lines in the table
3338  size_t nlines;
3339  /// Pointers to each column
3340  std::vector<vec_t *> col_ptrs;
3341 
3342  public:
3343 
3344  /** \brief Create a matrix view object from the specified
3345  table and list of columns
3346  */
3348  nr=0;
3349  nlines=0;
3350  }
3351 
3352  /** \brief Create a matrix view object from the specified
3353  table and list of columns
3354  */
3356  std::vector<std::string> rows) {
3357  set(t,rows);
3358  }
3359 
3360  /** \brief Create a matrix view object from the specified
3361  table and list of columns
3362  */
3364  std::vector<std::string> rows) {
3365  nr=rows.size();
3366  col_ptrs.resize(nr);
3367  for(size_t i=0;i<nr;i++) {
3368  col_ptrs[i]=&t.get_column_no_const(rows[i]);
3369  }
3370  nlines=t.get_nlines();
3371  }
3372 
3373  /** \brief Return the number of rows
3374  */
3375  size_t size1() {
3376  if (nlines==0) return 0;
3377  return nr;
3378  }
3379 
3380  /** \brief Return the number of columns
3381  */
3382  size_t size2() {
3383  return nlines;
3384  }
3385 
3386  /** \brief Return a reference to the element at row \c row
3387  and column \c col
3388  */
3389  const double &operator()(size_t row, size_t col) const {
3390  if (row>=nr) {
3391  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3392  " >= "+o2scl::szttos(nr)+" in matrix_view_table_transpose"+
3393  "::operator().";
3394  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3395  }
3396  if (col>=nlines) {
3397  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3398  " >= "+o2scl::szttos(nlines)+" in matrix_view_table_transpose"+
3399  "::operator().";
3400  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3401  }
3402  const vec_t *rp=col_ptrs[row];
3403  return (*rp)[col];
3404  }
3405 
3406  /** \brief Return a reference to the element at row \c row
3407  and column \c col
3408  */
3409  double &operator()(size_t row, size_t col) {
3410  if (row>=nr) {
3411  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3412  " >= "+o2scl::szttos(nr)+" in matrix_view_table_transpose"+
3413  "::operator().";
3414  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3415  }
3416  if (col>=nlines) {
3417  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3418  " >= "+o2scl::szttos(nlines)+" in matrix_view_table_transpose"+
3419  "::operator().";
3420  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3421  }
3422  vec_t *rp=col_ptrs[row];
3423  return (*rp)[col];
3424  }
3425 
3426  /** \brief Swap method
3427  */
3430  using std::swap;
3431  swap(t1.nc,t2.nc);
3432  swap(t1.nlines,t2.nlines);
3433  swap(t1.col_ptrs,t2.col_ptrs);
3434  return;
3435  }
3436 
3437  };
3438 
3439  /** \brief Swap part of a o2scl::table object into a matrix
3440  */
3442 
3443  protected:
3444 
3445  /// The number of columns
3446  size_t nc;
3447  /// The number of lines in the table
3448  size_t nlines;
3449  /// Array of columns
3450  std::vector<std::vector<double> > cols;
3451 
3452  public:
3453 
3454  /** \brief Create a matrix view object from the specified
3455  table and list of columns
3456  */
3458  nc=0;
3459  nlines=0;
3460  }
3461 
3462  /** \brief Create a matrix view object from the specified
3463  table and list of columns
3464  */
3465  matrix_swap_table(o2scl::table<std::vector<double> > &t,
3466  const std::vector<std::string> &col_names) {
3467  set(t,col_names);
3468  }
3469 
3470  /** \brief Create a matrix view object from the specified
3471  table and list of columns
3472  */
3473  void set(o2scl::table<std::vector<double> > &t,
3474  const std::vector<std::string> &col_names) {
3475  nc=cols.size();
3476  nlines=t.get_nlines();
3477  cols.resize(nc);
3478  for(size_t i=0;i<nc;i++) {
3479  // We have to make space for the vector before we use
3480  // table::swap_column_data()
3481  cols[i].resize(nlines);
3482  t.swap_column_data(col_names[i],cols[i]);
3483  }
3484  }
3485 
3486  /** \brief Return the number of rows
3487  */
3488  size_t size1() const {
3489  return nlines;
3490  }
3491 
3492  /** \brief Return the number of columns
3493  */
3494  size_t size2() const {
3495  if (nlines==0) return 0;
3496  return nc;
3497  }
3498 
3499  /** \brief Return a reference to the element at row \c row
3500  and column \c col
3501  */
3502  const double &operator()(size_t row, size_t col) const {
3503  if (row>=nlines) {
3504  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3505  " >= "+o2scl::szttos(nlines)+" in matrix_swap_table"+
3506  "::operator().";
3507  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3508  }
3509  if (col>=nc) {
3510  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3511  " >= "+o2scl::szttos(nc)+" in matrix_swap_table"+
3512  "::operator().";
3513  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3514  }
3515  return cols[col][row];
3516  }
3517 
3518  /** \brief Return a reference to the element at row \c row
3519  and column \c col
3520  */
3521  double &operator()(size_t row, size_t col) {
3522  if (row>=nlines) {
3523  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3524  " >= "+o2scl::szttos(nlines)+" in matrix_swap_table"+
3525  "::operator().";
3526  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3527  }
3528  if (col>=nc) {
3529  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3530  " >= "+o2scl::szttos(nc)+" in matrix_swap_table"+
3531  "::operator().";
3532  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3533  }
3534  return cols[col][row];
3535  }
3536 
3537  /** \brief Swap method
3538  */
3539  friend void swap(matrix_swap_table &t1,
3540  matrix_swap_table &t2) {
3541  using std::swap;
3542  swap(t1.nc,t2.nc);
3543  swap(t1.nlines,t2.nlines);
3544  swap(t1.cols,t2.cols);
3545  return;
3546  }
3547 
3548  };
3549 
3550  /** \brief View a o2scl::table object as a matrix
3551 
3552  \note This stores a pointer to the table and the user must ensure
3553  that the pointer is valid with the matrix view is accessed.
3554  */
3555  template<class vec_t=std::vector<double> >
3557  public const_matrix_view {
3558 
3559  protected:
3560 
3561  /** \brief The number of rows in the matrix (equal to the number of
3562  pointers to table columns)
3563  */
3564  size_t nr;
3565  /// Pointers to each row
3566  std::vector<const vec_t *> col_ptrs;
3567  /// Number of lines in the table
3568  size_t nlines;
3569 
3570  public:
3571 
3572  /** \brief Create a matrix view object from the specified
3573  table and list of rows
3574  */
3576  nr=0;
3577  nlines=0;
3578  }
3579 
3580  /** \brief Create a matrix view object from the specified
3581  table and list of rows
3582  */
3584  std::vector<std::string> rows) {
3585  set(t,rows);
3586  }
3587 
3588  /** \brief Create a matrix view object from the specified
3589  table and list of columns
3590  */
3592  std::vector<std::string> rows) {
3593  nr=rows.size();
3594  col_ptrs.resize(nr);
3595  for(size_t i=0;i<nr;i++) {
3596  col_ptrs[i]=&t[rows[i]];
3597  }
3598  nlines=t.get_nlines();
3599  }
3600 
3601  /** \brief Return the number of rows
3602  */
3603  size_t size1() {
3604  if (nlines==0) return 0;
3605  return nr;
3606  }
3607 
3608  /** \brief Return the number of columns
3609  */
3610  size_t size2() {
3611  return nlines;
3612  }
3613 
3614  /** \brief Swap method
3615  */
3618  using std::swap;
3619  swap(t1.nr,t2.nr);
3620  swap(t1.nlines,t2.nlines);
3621  swap(t1.col_ptrs,t2.col_ptrs);
3622  return;
3623  }
3624 
3625  /** \brief Return a reference to the element at row \c row
3626  and column \c col
3627  */
3628  const double &operator()(size_t row, size_t col) const {
3629  if (col>=nlines) {
3630  std::string str=((std::string)"Column ")+o2scl::szttos(col)+
3631  " >= "+o2scl::szttos(nlines)+" in const_matrix_view_table_transpose"+
3632  "::operator().";
3633  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3634  }
3635  if (row>=nr) {
3636  std::string str=((std::string)"Row ")+o2scl::szttos(row)+
3637  " >= "+o2scl::szttos(nr)+" in const_matrix_view_table_transpose"+
3638  "::operator().";
3639  O2SCL_ERR(str.c_str(),o2scl::exc_einval);
3640  }
3641  const vec_t *rp=col_ptrs[row];
3642  return (*rp)[col];
3643  }
3644 
3645  };
3646 
3647 #ifndef DOXYGEN_NO_O2NS
3648 }
3649 #endif
3650 
3651 #endif
o2scl::table::delete_idadj_rows
void delete_idadj_rows()
Delete all rows which are identical to adjacent rows.
Definition: table.h:1431
o2scl::table::intp_coly
std::string intp_coly
The last y-column interpolated.
Definition: table.h:3110
o2scl::table::integ_const
double integ_const(std::string sx, double x1, double x2, std::string sy) const
Compute the integral of the function defined by x-values stored in column named sx and y-values store...
Definition: table.h:2050
o2scl::const_matrix_view_table::const_matrix_view_table
const_matrix_view_table(o2scl::table< vec_t > &t, std::vector< std::string > cols)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3147
boost::numeric::ublas::matrix< double >
o2scl::table::function_column
void function_column(std::string function, std::string scol)
Make a column from the function specified in function and add it to the table.
Definition: table.h:2789
o2scl::table::lookup_val
double lookup_val(std::string scol, double val, std::string scol2) const
Search column col for the value val and return value in col2.
Definition: table.h:1608
o2scl::table::integ
void integ(std::string x, std::string y, std::string ynew)
Create a new column named ynew which is equal to the integral of the function defined by x-values sto...
Definition: table.h:2106
o2scl::matrix_view_table_transpose
View a o2scl::table object as a matrix.
Definition: table.h:55
o2scl::is_number
bool is_number(std::string s)
Return true if the string s is likely a integral or floating point number.
o2scl::matrix_swap_table::nc
size_t nc
The number of columns.
Definition: table.h:3446
o2scl::table::lookup
size_t lookup(int icol, double val) const
Exhaustively search column col for the value val .
Definition: table.h:1628
o2scl::table
Data table table class.
Definition: table.h:49
o2scl::table::functions_columns
void functions_columns(std::string list)
Create new columns or recompute from a list of functions.
Definition: table.h:2725
o2scl::table::get_nlines
size_t get_nlines() const
Return the number of lines.
Definition: table.h:460
o2scl::matrix_swap_table::matrix_swap_table
matrix_swap_table()
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3457
o2scl::table::si
interp_vec< vec_t > * si
Interpolation object.
Definition: table.h:3104
o2scl::table::line_of_data
void line_of_data(size_t nv, const vec2_t &v)
Read a line of data from the first nv entries in a vector and store as a new row in the table.
Definition: table.h:1492
o2scl::const_matrix_view_table_transpose::const_matrix_view_table_transpose
const_matrix_view_table_transpose(o2scl::table< vec_t > &t, std::vector< std::string > rows)
Create a matrix view object from the specified table and list of rows.
Definition: table.h:3583
o2scl::table::lookup_column
size_t lookup_column(std::string lname) const
Find the index for column named name .
Definition: table.h:974
o2scl::const_matrix_view_table_transpose::size2
size_t size2()
Return the number of columns.
Definition: table.h:3610
o2scl::table::get_row
void get_row(std::string scol, double val, resize_vec_t &row) const
Returns a copy of the row with value val in column col. .
Definition: table.h:508
o2scl::table::set_row
void set_row(size_t row, size_vec_t &v)
Set an entire row of data.
Definition: table.h:393
o2scl::permutation
A class for representing permutations.
Definition: permutation.h:70
o2scl::table::table
table(size_t cmaxlines=0)
Create a new table with space for nlines<=cmaxlines.
Definition: table.h:199
o2scl::table::copy_to_column
void copy_to_column(vec2_t &v, std::string scol)
Copy to a column from a generic vector object.
Definition: table.h:1029
o2scl::table::set_nlines
void set_nlines(size_t il)
Set the number of lines.
Definition: table.h:470
o2scl::matrix_view_table_transpose::nr
size_t nr
The number of rows.
Definition: table.h:3336
o2scl::table::constants
std::map< std::string, double > constants
The list of constants.
Definition: table.h:3006
o2scl::table::clear
virtual void clear()
Clear everything.
Definition: table.h:2286
o2scl::table::copy_rows
void copy_rows(std::string func, table< vec2_t > &dest)
Copy all rows matching a particular condition to a new table.
Definition: table.h:1269
o2scl::table::get_col_struct
col * get_col_struct(std::string lname)
Return the column structure for a column.
Definition: table.h:3076
o2scl::dtos
std::string dtos(const fp_t &x, int prec=6, bool auto_prec=false)
Convert a double to a string.
Definition: string_conv.h:77
o2scl::interp_vec::integ
virtual double integ(const double x1, const double x2) const
Give the value of the integral .
Definition: interp.h:1958
o2scl::table::set_constant
virtual int set_constant(std::string name, double val, bool err_on_notfound=true)
Set a constant equal to a value, but don't add it if not already present.
Definition: table.h:2473
o2scl::table::row_function
double row_function(std::string function, size_t row) const
Compute a value by applying a function to a row.
Definition: table.h:2854
o2scl::table::mlookup
size_t mlookup(std::string scol, double val, std::vector< size_t > &results, double threshold=0.0) const
Exhaustively search column col for many occurences of val .
Definition: table.h:1635
o2scl::matrix_view_table
View a o2scl::table object as a matrix.
Definition: table.h:52
o2scl::matrix_swap_table::size1
size_t size1() const
Return the number of rows.
Definition: table.h:3488
o2scl::const_matrix_view_table_transpose::const_matrix_view_table_transpose
const_matrix_view_table_transpose()
Create a matrix view object from the specified table and list of rows.
Definition: table.h:3575
o2scl::table::new_column
void new_column(std::string head)
Add a new column owned by the table table .
Definition: table.h:751
o2scl::table::remove_constant
virtual void remove_constant(std::string name)
Remove a constant.
Definition: table.h:2525
o2scl::exc_efailed
@ exc_efailed
generic failure
Definition: err_hnd.h:61
o2scl::table::itype
size_t itype
Current interpolation type.
Definition: table.h:3101
o2scl::table::copy_row
void copy_row(size_t src, size_t dest)
Copy the data in row src to row dest.
Definition: table.h:1178
o2scl::matrix_view_table_transpose::operator()
const double & operator()(size_t row, size_t col) const
Return a reference to the element at row row and column col.
Definition: table.h:3389
o2scl::table::function_find_row
size_t function_find_row(std::string function) const
Find a row which maximizes a function.
Definition: table.h:2875
o2scl::const_matrix_view_table::const_matrix_view_table
const_matrix_view_table()
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3139
o2scl::table::deriv
void deriv(std::string x, std::string y, std::string yp)
Make a new column named yp which is the derivative formed from columns named x and y .
Definition: table.h:1770
O2SCL_ERR2
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
o2scl::table::get_iterator
aiter get_iterator(std::string lname)
Return the iterator for a column.
Definition: table.h:3066
o2scl::matrix_view_table::size2
size_t size2()
Return the number of columns.
Definition: table.h:3267
o2scl::const_matrix_view_table
View a o2scl::table object as a matrix.
Definition: table.h:3123
o2scl::table::new_column
int new_column(std::string name, size_t sz, vec2_t &v)
Add a new column by copying data from another vector.
Definition: table.h:791
o2scl
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
Definition: anneal.h:42
o2scl::table::col::dat
vec_t dat
Pointer to column.
Definition: table.h:3016
o2scl::table::delete_row
void delete_row(std::string scol, double val)
Delete the row with the entry closest to the value val in column scol .
Definition: table.h:1192
o2scl::table::get_sorted_name
std::string get_sorted_name(size_t icol) const
Returns the name of column col in sorted order. .
Definition: table.h:915
o2scl::const_matrix_view_table_transpose::nlines
size_t nlines
Number of lines in the table.
Definition: table.h:3568
o2scl::table::line_of_data
void line_of_data(const vec2_t &v)
Read a line of data and store in a new row of the table.
Definition: table.h:1524
o2scl::matrix_swap_table::swap
friend void swap(matrix_swap_table &t1, matrix_swap_table &t2)
Swap method.
Definition: table.h:3539
o2scl::table::sort_table
void sort_table(std::string scol)
Sort the entire table by the column scol.
Definition: table.h:2336
o2scl::table::read_generic
virtual int read_generic(std::istream &fin, int verbose=0)
Clear the current table and read from a generic data file.
Definition: table.h:2538
o2scl::matrix_view
A simple matrix view object.
Definition: vector.h:2909
o2scl::exc_enotfound
@ exc_enotfound
Generic "not found" result.
Definition: err_hnd.h:117
o2scl::table::maxlines
size_t maxlines
The size of allocated memory.
Definition: table.h:3054
o2scl::table::new_row
void new_row(size_t n)
Insert a row before row n.
Definition: table.h:1155
o2scl::table::col::index
int index
Column index.
Definition: table.h:3018
o2scl::table::get_nconsts
virtual size_t get_nconsts() const
Get the number of constants.
Definition: table.h:2506
o2scl::table::begin
aiter begin()
Return the beginning of the column tree.
Definition: table.h:3087
o2scl::table::delete_row
void delete_row(size_t irow)
Delete the row of index irow .
Definition: table.h:1202
o2scl::table::get_column_no_const
vec_t & get_column_no_const(std::string scol)
Returns a non-const reference to the column named col. .
Definition: table.h:2937
o2scl::table::integ
double integ(std::string sx, double x1, double x2, std::string sy)
Compute the integral of the function defined by x-values stored in column named sx and y-values store...
Definition: table.h:2011
o2scl::stod
double stod(std::string s)
Convert a string to a double.
o2scl::table::deriv2
double deriv2(std::string sx, double x0, std::string sy)
Compute the second derivative of the function defined by x-values stored in column named sx and y-val...
Definition: table.h:1926
o2scl::const_matrix_view_table_transpose::size1
size_t size1()
Return the number of rows.
Definition: table.h:3603
o2scl::matrix_view_table_transpose::nlines
size_t nlines
The number of lines in the table.
Definition: table.h:3338
o2scl::table::set
void set(std::string scol, size_t row, double val)
Set row row of column named col to value val . .
Definition: table.h:317
o2scl::matrix_view_table_transpose::matrix_view_table_transpose
matrix_view_table_transpose()
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3347
o2scl::table::column_to_vector
void column_to_vector(std::string scol, resize_vec_t &v) const
Copy a column to a generic vector object.
Definition: table.h:1015
o2scl::table::interp
double interp(std::string sx, double x0, std::string sy)
Interpolate value x0 from column named sx into column named sy.
Definition: table.h:1694
o2scl::const_matrix_view_table_transpose::swap
friend void swap(const_matrix_view_table_transpose &t1, const_matrix_view_table_transpose &t2)
Swap method.
Definition: table.h:3616
o2scl::table::make_fp_varname
void make_fp_varname(std::string &s)
Ensure a variable name does not match a function or contain non-alphanumeric characters.
Definition: table.h:2965
o2scl::table::alist
std::vector< aiter > alist
The list of tree iterators.
Definition: table.h:3060
o2scl::table::nlines
size_t nlines
The size of presently used memory.
Definition: table.h:3056
o2scl::table::col::col
col(const col &c)
Copy constructor.
Definition: table.h:3023
o2scl_hdf::hdf_input
void hdf_input(hdf_file &hf, o2scl::table< vec_t > &t, std::string name)
Input a o2scl::table object from a hdf_file.
Definition: hdf_io.h:148
o2scl::table::is_valid
void is_valid() const
Check if the table object appears to be valid.
Definition: table.h:2658
o2scl::table::subtable
void subtable(std::string list, size_t top, size_t bottom, table< vec_t > &tnew) const
Make a subtable.
Definition: table.h:2207
o2scl::matrix_view_table::set
void set(o2scl::table< vec_t > &t, std::vector< std::string > cols)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3249
o2scl::matrix_view_table::operator()
const double & operator()(size_t row, size_t col) const
Return a reference to the element at row row and column col.
Definition: table.h:3275
o2scl::const_matrix_view_table::size2
size_t size2()
Return the number of columns.
Definition: table.h:3173
o2scl::const_matrix_view_table::nlines
size_t nlines
The number of lines in the table.
Definition: table.h:3130
o2scl::table::col
Column structure for table [protected].
Definition: table.h:3013
o2scl::table::interp_const
double interp_const(std::string sx, double x0, std::string sy) const
Interpolate value x0 from column named sx into column named sy (const version)
Definition: table.h:1729
o2scl_inte_qng_coeffs::x2
static const double x2[5]
Definition: inte_qng_gsl.h:66
o2scl::table::min
double min(std::string scol) const
Return column minimum. Makes no assumptions about ordering, .
Definition: table.h:2168
o2scl::table::delete_rows_list
void delete_rows_list(vec_size_t &row_list)
Delete all rows in a specified list.
Definition: table.h:1343
o2scl::interp_vec
Interpolation class for pre-specified vector.
Definition: interp.h:1795
o2scl::matrix_view_table::operator()
double & operator()(size_t row, size_t col)
Return a reference to the element at row row and column col.
Definition: table.h:3295
o2scl::table::set_maxlines
void set_maxlines(size_t llines)
Manually set the maximum number of lines.
Definition: table.h:621
o2scl::const_matrix_view_table_transpose::col_ptrs
std::vector< const vec_t * > col_ptrs
Pointers to each row.
Definition: table.h:3566
o2scl::table::get_constant
virtual void get_constant(size_t ix, std::string &name, double &val) const
Get a constant by index.
Definition: table.h:2511
o2scl::table::swap_column_data
virtual void swap_column_data(std::string scol, vec_t &v)
Swap the data in column scol with that in vector v.
Definition: table.h:838
o2scl::calculator::compile
void compile(const char *expr, std::map< std::string, double > *vars=0, bool debug=false, std::map< std::string, int > opPrec=opPrecedence)
Compile expression expr using variables specified in vars and return an integer to indicate success o...
o2scl::screenify
void screenify(size_t nin, const string_arr_t &in_cols, std::vector< std::string > &out_cols, size_t max_size=80)
Reformat the columns for output of width size.
Definition: misc.h:200
o2scl::table::deriv2
double deriv2(size_t ix, double x0, size_t iy)
Compute the second derivative of the function defined by x-values stored in column with index ix and ...
Definition: table.h:1989
o2scl::table::end
aiter end()
Return the end of the column tree.
Definition: table.h:3089
o2scl::const_matrix_view_table_transpose::nr
size_t nr
The number of rows in the matrix (equal to the number of pointers to table columns)
Definition: table.h:3564
o2scl::table::get_constant
virtual double get_constant(std::string name) const
Get a constant.
Definition: table.h:2496
o2scl::const_matrix_view_table_transpose::operator()
const double & operator()(size_t row, size_t col) const
Return a reference to the element at row row and column col.
Definition: table.h:3628
o2scl::vector_sort_index
void vector_sort_index(size_t n, const vec_t &data, vec_size_t &order)
Create a permutation which sorts the first n elements of a vector (in increasing order)
Definition: vector.h:800
o2scl::matrix_view_table_transpose::size1
size_t size1()
Return the number of rows.
Definition: table.h:3375
o2scl::table::integ
double integ(size_t ix, double x1, double x2, size_t iy)
Compute the integral of the function defined by x-values stored in column with index ix and y-values ...
Definition: table.h:2077
o2scl::matrix_view_table_transpose::set
void set(o2scl::table< vec_t > &t, std::vector< std::string > rows)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3363
o2scl::const_matrix_view_table_transpose
View a o2scl::table object as a matrix.
Definition: table.h:3556
o2scl::const_matrix_view_table::set
void set(o2scl::table< vec_t > &t, std::vector< std::string > cols)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3155
o2scl::matrix_swap_table::operator()
const double & operator()(size_t row, size_t col) const
Return a reference to the element at row row and column col.
Definition: table.h:3502
o2scl_inte_qng_coeffs::x1
static const double x1[5]
Definition: inte_qng_gsl.h:48
o2scl::table::inc_maxlines
void inc_maxlines(size_t llines)
Manually increase the maximum number of lines.
Definition: table.h:585
o2scl::matrix_view_table_transpose::size2
size_t size2()
Return the number of columns.
Definition: table.h:3382
o2scl::table::col::operator=
col & operator=(const col &c)
Copy constructor for assignment operator.
Definition: table.h:3029
o2scl::matrix_view_table_transpose::swap
friend void swap(matrix_view_table_transpose &t1, matrix_view_table_transpose &t2)
Swap method.
Definition: table.h:3428
o2scl::exc_einval
@ exc_einval
invalid argument supplied by user
Definition: err_hnd.h:59
o2scl::calculator
Evaluate a mathematical expression in a string.
Definition: shunting_yard.h:119
o2scl::table::add_constant
virtual void add_constant(std::string name, double val)
Add a constant, or if the constant already exists, change its value.
Definition: table.h:2454
o2scl::table::operator[]
const vec_t & operator[](std::string scol) const
Returns the column named scol (const version). .
Definition: table.h:733
o2scl::matrix_view_table_transpose::col_ptrs
std::vector< vec_t * > col_ptrs
Pointers to each column.
Definition: table.h:3340
o2scl::matrix_view_table::swap
friend void swap(matrix_view_table &t1, matrix_view_table &t2)
Swap method.
Definition: table.h:3314
o2scl::const_matrix_view_table_transpose::set
void set(o2scl::table< vec_t > &t, std::vector< std::string > rows)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3591
o2scl::matrix_view_table::nc
size_t nc
The number of columns.
Definition: table.h:3222
o2scl::table::sort_column
void sort_column(std::string scol)
Individually sort the column scol.
Definition: table.h:2368
o2scl::table::set
void set(size_t icol, size_t row, double val)
Set row row of column number icol to value val . .
Definition: table.h:354
o2scl::table::delete_column
virtual void delete_column(std::string scol)
Delete column named scol .
Definition: table.h:877
o2scl::matrix_view_table::nlines
size_t nlines
The number of lines in the table.
Definition: table.h:3224
o2scl::matrix_swap_table::size2
size_t size2() const
Return the number of columns.
Definition: table.h:3494
o2scl_hdf
The O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl namespace ...
Definition: table.h:59
o2scl::const_matrix_view_table::swap
friend void swap(const_matrix_view_table &t1, const_matrix_view_table &t2)
Swap method.
Definition: table.h:3200
o2scl::table::deriv2
void deriv2(std::string x, std::string y, std::string yp)
Create a new column named yp which is equal to the second derivative of the function defined by x-val...
Definition: table.h:1892
o2scl::table::reset_list
void reset_list()
Set the elements of alist with the appropriate iterators from atree. .
Definition: table.h:2954
o2scl::table::aiter
std::map< std::string, col, std::greater< std::string > >::iterator aiter
Map iterator type.
Definition: table.h:3042
o2scl::table::make_unique_name
void make_unique_name(std::string &colx, std::vector< std::string > &cnames)
Make sure a name is unique.
Definition: table.h:2985
o2scl::search_vec
Searching class for monotonic data with caching.
Definition: search_vec.h:74
o2scl::table::deriv
double deriv(std::string sx, double x0, std::string sy)
Compute the first derivative of the function defined by x-values stored in column named sx and y-valu...
Definition: table.h:1805
o2scl::table::aciter
std::map< std::string, col, std::greater< std::string > >::const_iterator aciter
Const map iterator type.
Definition: table.h:3046
o2scl::table::get_maxlines
size_t get_maxlines()
Return the maximum number of lines before a reallocation is required.
Definition: table.h:492
o2scl::table::summary
virtual void summary(std::ostream *out, size_t ncol=79) const
Output a summary of the information stored.
Definition: table.h:2398
o2scl::table::delete_rows_tolerance
size_t delete_rows_tolerance(double tol_rel=1.0e-12, double tol_abs=1.0e-20, int verbose=0)
Exaustively search for groups of rows which match within a specified tolerance and remove all but one...
Definition: table.h:1384
o2scl::table::line_of_names
void line_of_names(std::string newheads)
Read a new set of names from newheads.
Definition: table.h:1462
o2scl::table::aviter
std::vector< aiter >::iterator aviter
Vector iterator type.
Definition: table.h:3048
o2scl::table::get_ncolumns
size_t get_ncolumns() const
Return the number of columns.
Definition: table.h:452
o2scl::table::operator=
table & operator=(const table &t)
Copy constructor.
Definition: table.h:257
o2scl::table::deriv2_const
double deriv2_const(size_t ix, double x0, size_t iy) const
Compute the second derivative of the function defined by x-values stored in column with index ix and ...
Definition: table.h:2000
o2scl::table::intp_colx
std::string intp_colx
The last x-column interpolated.
Definition: table.h:3107
o2scl::table::deriv_const
double deriv_const(size_t ix, double x0, size_t iy) const
Compute the first derivative of the function defined by x-values stored in column with index ix and y...
Definition: table.h:1879
o2scl::table::get_column
const vec_t & get_column(std::string scol) const
Returns a reference to the column named col. .
Definition: table.h:672
o2scl::itos
std::string itos(int x)
Convert an integer to a string.
o2scl::table::interp
double interp(size_t ix, double x0, size_t iy)
Interpolate value x0 from column with index ix into column with index iy .
Definition: table.h:1752
o2scl_hdf::hdf_input_data
void hdf_input_data(hdf_file &hf, o2scl::table< vec_t > &t)
Internal function for inputting a o2scl::table object.
Definition: hdf_io.h:186
o2scl::matrix_view_table::col_ptrs
std::vector< vec_t * > col_ptrs
Pointers to each column.
Definition: table.h:3226
o2scl::table::table
table(const table &t)
Copy constructor.
Definition: table.h:215
o2scl::table::clear_data
void clear_data()
Remove all of the data by setting the number of lines to zero.
Definition: table.h:2311
o2scl::exc_eindex
@ exc_eindex
Invalid index for array or matrix.
Definition: err_hnd.h:123
o2scl::table::check_synchro
void check_synchro() const
Check if the tree and list are properly synchronized.
Definition: table.h:2632
o2scl::table::lookup
size_t lookup(std::string scol, double val) const
Exhaustively search column col for the value val .
Definition: table.h:1566
o2scl::table::operator[]
const vec_t & operator[](size_t icol) const
Returns the column of index icol (const version). .
Definition: table.h:703
o2scl::table::interp_const
double interp_const(size_t ix, double x0, size_t iy) const
Interpolate value x0 from column with index ix into column with index iy .
Definition: table.h:1759
o2scl::table::intp_set
bool intp_set
True if the interpolation object is up-to-date.
Definition: table.h:3098
o2scl::const_matrix_view_table::operator()
const double & operator()(size_t row, size_t col) const
Return a reference to the element at row row and column col.
Definition: table.h:3181
o2scl::vector_sort_double
void vector_sort_double(size_t n, vec_t &data)
Sort a vector of doubles (in increasing order)
Definition: vector.h:895
o2scl::matrix_swap_table::set
void set(o2scl::table< std::vector< double > > &t, const std::vector< std::string > &col_names)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3473
o2scl::matrix_swap_table::operator()
double & operator()(size_t row, size_t col)
Return a reference to the element at row row and column col.
Definition: table.h:3521
o2scl::table::set_nlines_auto
void set_nlines_auto(size_t il)
Set the number of lines, increasing the size more agressively.
Definition: table.h:562
o2scl_hdf::hdf_file
Store data in an O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$sc...
Definition: hdf_file.h:105
o2scl::table::get_row
void get_row(size_t irow, resize_vec_t &row) const
Returns a copy of row number irow. .
Definition: table.h:534
o2scl::exc_esanity
@ exc_esanity
sanity check failed - shouldn't happen
Definition: err_hnd.h:65
o2scl::table::is_constant
virtual bool is_constant(std::string name) const
Test if name is a constant.
Definition: table.h:2488
o2scl::const_matrix_view_table::col_ptrs
std::vector< const vec_t * > col_ptrs
Pointers to each column.
Definition: table.h:3132
o2scl::search_vec::ordered_lookup
size_t ordered_lookup(const double x0) const
Find the index of x0 in the ordered array x.
Definition: search_vec.h:242
o2scl::table::insert_table
void insert_table(table< vec2_t > &source, std::string src_index, bool allow_extrap=true, std::string dest_index="")
Insert columns from a source table into the new table by interpolation (or extrapolation)
Definition: table.h:1099
o2scl::matrix_view_table::matrix_view_table
matrix_view_table()
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3233
o2scl::table::set_interp_type
void set_interp_type(size_t interp_type)
Set the base interpolation objects.
Definition: table.h:1672
o2scl::matrix_view_table_transpose::operator()
double & operator()(size_t row, size_t col)
Return a reference to the element at row row and column col.
Definition: table.h:3409
O2SCL_ERR
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
o2scl::itp_cspline
@ itp_cspline
Cubic spline for natural boundary conditions.
Definition: interp.h:73
o2scl::matrix_swap_table
Swap part of a o2scl::table object into a matrix.
Definition: table.h:3441
o2scl::table::is_column
bool is_column(std::string scol) const
Return true if scol is a column in the current table table .
Definition: table.h:962
o2scl::table::init_column
void init_column(std::string scol, double val)
Initialize all values of column named scol to val .
Definition: table.h:931
o2scl::table::deriv2_const
double deriv2_const(std::string sx, double x0, std::string sy) const
The Compute the second derivative of the function defined by x-values stored in column named sx and y...
Definition: table.h:1963
o2scl::calculator::eval
double eval(std::map< std::string, double > *vars=0)
Evalate the previously compiled expression using variables specified in vars.
o2scl::table::function_vector
int function_vector(std::string function, resize_vec_t &vec, bool throw_on_err=true)
Compute a column from a function specified in a string.
Definition: table.h:2823
o2scl::matrix_swap_table::nlines
size_t nlines
The number of lines in the table.
Definition: table.h:3448
o2scl::matrix_view_table::size1
size_t size1()
Return the number of rows.
Definition: table.h:3261
o2scl::table::ordered_lookup
size_t ordered_lookup(std::string scol, double val) const
Look for a value in an ordered column .
Definition: table.h:1542
o2scl::table::delete_rows_func
void delete_rows_func(std::string func)
Delete all rows where func evaluates to a number greater than 0.5 .
Definition: table.h:1234
o2scl::matrix_swap_table::cols
std::vector< std::vector< double > > cols
Array of columns.
Definition: table.h:3450
o2scl::const_matrix_view
A simple matrix view object.
Definition: vector.h:2888
o2scl::table::max
double max(std::string scol) const
Return column maximum. Makes no assumptions about ordering, .
Definition: table.h:2137
o2scl::table::integ_const
double integ_const(size_t ix, double x1, double x2, size_t iy) const
Compute the integral of the function defined by x-values stored in column with index ix and y-values ...
Definition: table.h:2090
o2scl::const_matrix_view_table::size1
size_t size1()
Return the number of rows.
Definition: table.h:3167
o2scl::table::atree
std::map< std::string, col, std::greater< std::string > > atree
The tree of columns.
Definition: table.h:3058
o2scl::interp_vec::deriv2
virtual double deriv2(const double x0) const
Give the value of the second derivative .
Definition: interp.h:1949
o2scl::table::type
virtual const char * type()
Return the type, "table".
Definition: table.h:2691
o2scl::matrix_view_table::matrix_view_table
matrix_view_table(o2scl::table< vec_t > &t, std::vector< std::string > cols)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3241
o2scl::table::~table
virtual ~table()
Table destructor.
Definition: table.h:208
o2scl::table::get
double get(std::string scol, size_t row) const
Get value from row row of column named col. .
Definition: table.h:408
o2scl::table::rename_column
virtual void rename_column(std::string src, std::string dest)
Rename column named src to dest .
Definition: table.h:857
o2scl::interp_vec::deriv
virtual double deriv(const double x0) const
Give the value of the derivative .
Definition: interp.h:1938
o2scl::table::get_interp_type
size_t get_interp_type() const
Get the interpolation type.
Definition: table.h:1683
o2scl::table::copy_column
virtual void copy_column(std::string src, std::string dest)
Copy data from column named src to column named dest, creating a new column if necessary .
Definition: table.h:987
o2scl::table::deriv
double deriv(size_t ix, double x0, size_t iy)
Compute the first derivative of the function defined by x-values stored in column with index ix and y...
Definition: table.h:1868
o2scl::table::get
double get(size_t icol, size_t row) const
Get value from row row of column number icol. .
Definition: table.h:436
o2scl::table::clear_table
virtual void clear_table()
Clear the table and the column names (but leave constants)
Definition: table.h:2294
o2scl::szttos
std::string szttos(size_t x)
Convert a size_t to a string.
o2scl::matrix_swap_table::matrix_swap_table
matrix_swap_table(o2scl::table< std::vector< double > > &t, const std::vector< std::string > &col_names)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3465
o2scl::matrix_view_table_transpose::matrix_view_table_transpose
matrix_view_table_transpose(o2scl::table< vec_t > &t, std::vector< std::string > rows)
Create a matrix view object from the specified table and list of columns.
Definition: table.h:3355
o2scl::table::clear_constants
void clear_constants()
CLear all constants.
Definition: table.h:2321
o2scl::table::add_col_from_table
void add_col_from_table(table< vec2_t > &source, std::string src_index, std::string src_col, std::string dest_index, std::string dest_col="")
Insert a column from a separate table, interpolating it into a new column.
Definition: table.h:1047
o2scl::table::deriv_const
double deriv_const(std::string sx, double x0, std::string sy) const
Compute the first derivative of the function defined by x-values stored in column named sx and y-valu...
Definition: table.h:1842
o2scl::table::zero_table
void zero_table()
Zero the data entries but keep the column names and nlines fixed.
Definition: table.h:2268
o2scl::const_matrix_view_table::nc
size_t nc
The number of columns.
Definition: table.h:3128
o2scl::table::get_column_name
std::string get_column_name(size_t icol) const
Returns the name of column col .
Definition: table.h:819
o2scl::table::empty_col
vec_t empty_col
An empty vector for get_column()
Definition: table.h:3093
o2scl::table::delete_rows_ends
void delete_rows_ends(size_t row_start, size_t row_end)
Delete all rows between row_start and row_end .
Definition: table.h:1310

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).