table3d.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2018, 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_TABLE3D_H
24 #define O2SCL_TABLE3D_H
25 
26 /** \file table3d.h
27  \brief File defining \ref o2scl::table3d
28 */
29 
30 #include <iostream>
31 #include <fstream>
32 #include <vector>
33 #include <string>
34 #include <cmath>
35 #include <sstream>
36 
37 #include <boost/numeric/ublas/vector.hpp>
38 #include <boost/numeric/ublas/vector_proxy.hpp>
39 #include <boost/numeric/ublas/matrix.hpp>
40 #include <boost/numeric/ublas/matrix_proxy.hpp>
41 
42 #include <o2scl/misc.h>
43 #include <o2scl/err_hnd.h>
44 #include <o2scl/search_vec.h>
45 #include <o2scl/uniform_grid.h>
46 #include <o2scl/interp.h>
47 #include <o2scl/table_units.h>
48 #include <o2scl/contour.h>
49 
50 #include <o2scl/shunting_yard.h>
51 
52 // Forward definition of the table3d class for HDF I/O
53 namespace o2scl {
54  class table3d;
55 }
56 
57 // Forward definition of HDF I/O to extend friendship
58 namespace o2scl_hdf {
59  class hdf_file;
60  void hdf_input(hdf_file &hf, o2scl::table3d &t, std::string name);
61  void hdf_output(hdf_file &hf, o2scl::table3d &t, std::string name);
62 }
63 
64 #ifndef DOXYGEN_NO_O2NS
65 namespace o2scl {
66 #endif
67 
68  /** \brief A data structure containing many slices of two-dimensional
69  data points defined on a grid
70 
71  \future Improve interpolation and derivative caching, possibly
72  through non-const versions of the interpolation functions.
73  \future Should there be a clear_grid() function separate from
74  clear_data() and clear_table()?
75  \future Allow the user to more clearly probe 'size_set' vs.
76  'xy_set'?
77  */
78  class table3d {
79 
80  public:
81 
84 
85  // This is used for the interpolation classes
86  typedef boost::numeric::ublas::matrix_row<const ubmatrix> ubmatrix_row;
87  typedef boost::numeric::ublas::matrix_column<const ubmatrix>
88  ubmatrix_column;
89 
90  /** \brief Create a new 3D \table
91  */
92  table3d();
93 
94  virtual ~table3d();
95 
96  /** \brief Create a table3d object from a table, assuming \c scolx
97  and \c scoly store the x- and y-grid data, respectively.
98  */
99  table3d(o2scl::table_units<> &t, std::string colx, std::string coly);
100 
101  /** \brief Read a generic table3d object specified as a
102  text file
103 
104  This function reads a set of columns of numerical values,
105  presuming that the first column is the x-grid value, the
106  second column is the y-grid value, and the remaining columns
107  are slices to be added.
108 
109  \todo A bit more documentation needs to be added here.
110 
111  \future It would be great to add a function which generates
112  a text file in this format as well.
113  */
114  int read_gen3_list(std::istream &fin, int verbose=0);
115 
116  /// \name Initialization
117  //@{
118  /** \brief Initialize the x-y grid
119 
120  This function will not allow you to redefine the grid when
121  there is data in the \table if a grid of a different size was
122  already set from a previous call to either set_xy() or
123  set_size(). However, you may freely redefine the grid after a
124  call to clear_data() or clear_table(). You may change
125  individual grid points at any time with set_grid_x() and
126  set_grid_y().
127  */
128  template<class vec_t, class vec2_t>
129  void set_xy(std::string x_name, size_t nx, const vec_t &x,
130  std::string y_name, size_t ny, const vec2_t &y) {
131 
132  if (has_slice && (size_set || xy_set) && (nx!=numx || ny!=numy)) {
133  O2SCL_ERR("Size cannot be reset in table3d::set_xy().",
135  return;
136  }
137  if (xy_set) {
138  xval.clear();
139  yval.clear();
140  }
141  numx=nx;
142  numy=ny;
143  xname=x_name;
144  yname=y_name;
145  xval.resize(nx);
146  yval.resize(ny);
147  for(size_t i=0;i<nx;i++) (xval)[i]=x[i];
148  for(size_t i=0;i<ny;i++) (yval)[i]=y[i];
149  size_set=true;
150  xy_set=true;
151  return;
152  }
153 
154  /** \brief Initialize the x-y grid with \ref uniform_grid objects
155 
156  This function will not allow you to redefine the grid when
157  there is data in the \table if a grid of a different size was
158  already set from a previous call to either set_xy() or
159  set_size(). However, you may freely redefine the grid after a
160  call to clear_data() or clear_table(). You may change
161  individual grid points at any time with set_grid_x() and
162  set_grid_y().
163  */
164  void set_xy(std::string x_name, uniform_grid<double> gx,
165  std::string y_name, uniform_grid<double> gy) {
166 
167  if (has_slice && (size_set || xy_set) &&
168  (gx.get_npoints()!=numx || gy.get_npoints()!=numy)) {
169  O2SCL_ERR("Size cannot be reset in table3d::set_xy().",
171  return;
172  }
173 
174  if (xy_set) {
175  xval.clear();
176  yval.clear();
177  }
178  numx=gx.get_npoints();
179  numy=gy.get_npoints();
180  xname=x_name;
181  yname=y_name;
182  xval.resize(numx);
183  yval.resize(numy);
184  gx.vector(xval);
185  gy.vector(yval);
186  size_set=true;
187  xy_set=true;
188  }
189 
190  /** \brief Initialize \table size
191 
192  This function will not allow you to resize the \table if it
193  already has data or if the size has already been set with the
194  set_xy() function, unless you clear the data with clear_data()
195  or the \table with clear_table() first.
196  */
197  void set_size(size_t nx, size_t ny);
198  //@}
199 
200  // --------------------------------------------------------
201  /// \name On-grid get and set methods
202  //@{
203 
204  /** \brief Set element in slice \c name at location <tt>ix,iy</tt>
205  to value \c val
206  */
207  void set(size_t ix, size_t iy, std::string name, double val);
208 
209  /** \brief Set element in slice of index \c z at location
210  <tt>ix,iy</tt> to value \c val .
211  */
212  void set(size_t ix, size_t iy, size_t z, double val);
213 
214  /** \brief Get element in slice \c name at location
215  <tt>ix,iy</tt>
216  */
217  double &get(size_t ix, size_t iy, std::string name);
218 
219  /** \brief Get element in slice \c name at location
220  <tt>ix,iy</tt> (const version)
221  */
222  const double &get(size_t ix, size_t iy, std::string name) const;
223 
224  /** \brief Get element in slice of index \c z at location
225  <tt>ix,iy</tt>
226  */
227  double &get(size_t ix, size_t iy, size_t z);
228 
229  /** \brief Get element in slice of index \c z at location
230  <tt>ix,iy</tt> (const version)
231  */
232  const double &get(size_t ix, size_t iy, size_t z) const;
233  //@}
234 
235  // --------------------------------------------------------
236  /** \name Off-grid get and set methods
237 
238  These methods return the value of a slice on the grid
239  point nearest to a user-specified location. For
240  interpolation into a point off the grid, use
241  \ref table3d::interp().
242  */
243  //@{
244 
245  /** \brief Set element in slice \c name at the nearest location to
246  <tt>x,y</tt> to value \c val
247  */
248  void set_val(double x, double y, std::string name, double val);
249 
250  /** \brief Set element in slice of index \c z at the nearest
251  location to <tt>x,y</tt> to value \c val
252  */
253  void set_val(double x, double y, size_t z, double val);
254 
255  /** \brief Get element in slice \c name at location closest to
256  <tt>x,y</tt>
257  */
258  double &get_val(double x, double y, std::string name);
259 
260  /** \brief Get element in slice \c name at location closest to
261  <tt>x,y</tt>
262  */
263  const double &get_val(double x, double y, std::string name) const;
264 
265  /** \brief Get element in slice of index \c z at location closest
266  to <tt>x,y</tt>
267  */
268  double &get_val(double x, double y, size_t z);
269 
270  /** \brief Get element in slice of index \c z at location closest
271  to <tt>x,y</tt>
272  */
273  const double &get_val(double x, double y, size_t z) const;
274 
275  /** \brief Set elements in the first <tt>nv</tt> slices at the
276  nearest location to <tt>x,y</tt> to value \c val
277  */
278  template<class vec_t>
279  void set_slices(double x, double y, size_t nv, vec_t &vals) {
280  size_t ix, iy;
281  lookup_x(x,ix);
282  lookup_y(y,iy);
283 
284  for(size_t i=0;i<nv && i<list.size();i++) {
285  list[i](ix,iy)=vals[i];
286  }
287  return;
288  }
289 
290  /** \brief Get the data for every slice at the nearest location to
291  <tt>x,y</tt>
292  */
293  template<class vec_t>
294  void get_slices(double x, double y, size_t nv, vec_t &v) {
295 
296  size_t ix, iy;
297 
298  lookup_x(x,ix);
299  lookup_y(y,iy);
300 
301  for(size_t i=0;i<nv && i<list.size();i++) {
302  v[i]=list[i](ix,iy);
303  }
304 
305  return;
306  }
307  //@}
308 
309  // --------------------------------------------------------
310  /// \name Off-grid get and set methods returning nearest point
311  //@{
312 
313  /** \brief Set element in slice \c name at the nearest location to
314  <tt>x,y</tt> to value \c val
315  */
316  void set_val_ret(double &x, double &y, std::string name, double val);
317 
318  /** \brief Set element in slice of index \c z at the nearest
319  location to <tt>x,y</tt> to value \c val
320  */
321  void set_val_ret(double &x, double &y, size_t z, double val);
322 
323  /** \brief Get element in slice \c name at location closest to
324  <tt>x,y</tt>, and also return the corresponding values of \c x
325  and \c y
326  */
327  double &get_val_ret(double &x, double &y, std::string name);
328 
329  /** \brief Get element in slice \c name at location closest to
330  <tt>x,y</tt>, and also return the corresponding values of \c x
331  and \c y
332  */
333  const double &get_val_ret(double &x, double &y, std::string name) const;
334 
335  /** \brief Get element in slice of index \c z at location closest
336  to <tt>x,y</tt>, and also return the corresponding values of
337  \c x and \c y
338  */
339  double &get_val_ret(double &x, double &y, size_t z);
340 
341  /** \brief Get element in slice of index \c z at location closest
342  to <tt>x,y</tt>, and also return the corresponding values of
343  \c x and \c y
344  */
345  const double &get_val_ret(double &x, double &y, size_t z) const;
346 
347  /** \brief This function adds a slice from a different table3d
348  object, interpolating the results into the current
349  table3d object
350  */
351  void add_slice_from_table(table3d &source, std::string slice,
352  std::string dest_slice="") {
353 
354  if (dest_slice.length()==0) dest_slice=slice;
355 
356  if (xy_set==false) {
357  set_xy(source.get_x_name(),source.get_nx(),source.get_x_data(),
358  source.get_y_name(),source.get_ny(),source.get_y_data());
359  new_slice(dest_slice);
360  for(size_t i=0;i<numx;i++) {
361  for(size_t j=0;j<numx;j++) {
362  set(i,j,dest_slice,source.get(i,j,slice));
363  }
364  }
365  return;
366  }
367 
368  size_t szt_tmp;
369  if (!is_slice(dest_slice,szt_tmp)) new_slice(dest_slice);
370  for(size_t i=0;i<numx;i++) {
371  for(size_t j=0;j<numx;j++) {
372  set(i,j,dest_slice,source.interp(get_grid_x(i),get_grid_y(j),
373  slice));
374  }
375  }
376  return;
377  }
378 
379  /** \brief Set elements in the first <tt>nv</tt> slices at the
380  nearest location to <tt>x,y</tt> to values \c vals
381  */
382  template<class vec_t>
383  void set_slices_ret(double &x, double &y, size_t nv, vec_t &vals) {
384  size_t ix, iy;
385  lookup_x(x,ix);
386  lookup_y(y,iy);
387  x=xval[ix];
388  y=yval[iy];
389 
390  for(size_t i=0;i<nv && i<list.size();i++) {
391  list[i](ix,iy)=vals[i];
392  }
393  return;
394  }
395 
396  /** \brief Get elements in the first <tt>nv</tt> slices at the
397  nearest location to <tt>x,y</tt> to value \c val
398  */
399  template<class vec_t>
400  void get_slices_ret(double &x, double &y, size_t nv, vec_t &vals) {
401 
402  size_t ix, iy;
403  lookup_x(x,ix);
404  lookup_y(y,iy);
405  x=xval[ix];
406  y=yval[iy];
407 
408  for(size_t i=0;i<nv && i<list.size();i++) {
409  vals[i]=list[i](ix,iy);
410  }
411  return;
412  }
413 
414  //@}
415 
416  // --------------------------------------------------------
417  /// \name Grid information get and set methods
418  //@{
419 
420  /// Set x grid point at index \c ix
421  void set_grid_x(size_t ix, double val);
422 
423  /// Set y grid point at index \c iy
424  void set_grid_y(size_t iy, double val);
425 
426  /// Get x grid point at index \c ix
427  double get_grid_x(size_t ix);
428 
429  /// Get y grid point at index \c iy
430  double get_grid_y(size_t iy);
431 
432  /// Get the name of the x grid variable
433  std::string get_x_name() const {
434  return xname;
435  }
436 
437  /// Get the name of the y grid variable
438  std::string get_y_name() const {
439  return yname;
440  }
441 
442  /// Set the name of the x grid variable
443  void set_x_name(std::string name) {
444  xname=name;
445  return;
446  }
447 
448  /// Set the name of the y grid variable
449  void set_y_name(std::string name) {
450  yname=name;
451  return;
452  }
453 
454  /// Get a const reference to the full x grid
455  const ubvector &get_x_data() const { return xval; }
456 
457  /// Get a const reference to the full y grid
458  const ubvector &get_y_data() const { return yval; }
459 
460  //@}
461 
462  // --------------------------------------------------------
463  /// \name Size get methods
464  //@{
465 
466  /// Get the size of the slices
467  void get_size(size_t &nx, size_t &ny) const;
468 
469  /// Get the x size
470  size_t get_nx() const {
471  return numx;
472  }
473 
474  /// Get the y size
475  size_t get_ny() const {
476  return numy;
477  }
478 
479  /// Get the number of slices
480  size_t get_nslices() const;
481  //@}
482 
483  // --------------------------------------------------------
484  /// \name Slice manipulation
485  //@{
486 
487  /// Create a set of new slices specified in the string \c names
488  void line_of_names(std::string names);
489 
490  /** \brief Returns the name of slice with index \c z
491  */
492  std::string get_slice_name(size_t z) const;
493 
494  /** \brief Add a new slice
495  */
496  void new_slice(std::string name);
497 
498  /** \brief Set all of the values in slice \c name to \c val
499  */
500  void set_slice_all(std::string name, double val);
501 
502  /** \brief Find the index for column named \c name
503  */
504  size_t lookup_slice(std::string name) const;
505 
506  /** \brief Return true if slice is already present
507  */
508  bool is_slice(std::string name, size_t &ix) const;
509 
510  /** \brief Rename slice named \c olds to \c news
511 
512  This is slow since we have to delete the column and re-insert
513  it. This process in turn mangles all of the iterators in the
514  list.
515  */
516  void rename_slice(std::string olds, std::string news);
517 
518  /** \brief Make a new slice named \c dest which is a copy
519  of the slice with name given in \c src.
520  */
521  void copy_slice(std::string src, std::string dest);
522 
523  /** \brief Initialize all values of slice named \c scol to \c val
524 
525  \note This will call the error handler if the value \c val is
526  not finite (i.e. either <tt>Inf</tt> or <tt>NaN</tt>).
527  */
528  void init_slice(std::string scol, double val);
529 
530  /// Return a constant reference to a slice
531  const ubmatrix &get_slice(std::string scol) const;
532 
533  /// Return a constant reference to a slice
534  const ubmatrix &get_slice(size_t iz) const;
535 
536  /// Return a constant reference to a slice
537  ubmatrix &get_slice(std::string scol);
538 
539  /// Return a constant reference to a slice
540  ubmatrix &get_slice(size_t iz);
541 
542  /** \brief Return a constant reference to all the slice data
543 
544  \comment
545  This isn't designated const, i.e. as
546  const std::vector<ubmatrix> &get_data() const;
547  because it would then have to be
548  const std::vector<const ubmatrix> &get_data() const;
549  \endcomment
550  */
551  const std::vector<ubmatrix> &get_data();
552 
553  /** \brief Copy to a slice from a generic matrix object
554 
555  The type <tt>mat_t</tt> can be any type with an
556  <tt>operator(,)</tt> method.
557  */
558  template<class mat_t>
559  void copy_to_slice(mat_t &m, std::string scol) {
560  for(size_t i=0;i<numx;i++) {
561  for(size_t j=0;j<numy;j++) {
562  this->set(i,j,scol,m(i,j));
563  }
564  }
565  return;
566  }
567  //@}
568 
569  // --------------------------------------------------------
570  /// \name Lookup and search methods
571  //@{
572  /** \brief Look for a value in the x grid
573  */
574  void lookup_x(double val, size_t &ix) const;
575 
576  /** \brief Look for a value in the y grid
577  */
578  void lookup_y(double val, size_t &iy) const;
579 
580  /** \brief Look for a value in a specified slice
581  */
582  void lookup(double val, std::string slice, size_t &ix, size_t &iy) const;
583  //@}
584 
585  // --------------------------------------------------------
586  /// \name Interpolation, differentiation, and integration
587  //@{
588 
589  /** \brief Specify the interpolation type
590  */
591  void set_interp_type(size_t interp_type);
592 
593  /** \brief Get the interpolation type
594  */
595  size_t get_interp_type() const;
596 
597  /** \brief Interpolate \c x and \c y in slice named \c name
598  */
599  double interp(double x, double y, std::string name) const;
600 
601  /** \brief Interpolate the derivative of the data with respect to
602  the x grid at point \c x and \c y in slice named \c name
603  */
604  double deriv_x(double x, double y, std::string name) const;
605 
606  /** \brief Interpolate the derivative of the data with respect to
607  the y grid at point \c x and \c y in slice named \c name
608  */
609  double deriv_y(double x, double y, std::string name) const;
610 
611  /** \brief Interpolate the mixed second derivative of the data at
612  point \c x and \c y in slice named \c name
613  */
614  double deriv_xy(double x, double y, std::string name) const;
615 
616  /** \brief Interpolate the integral of the data
617  respect to the x grid
618  */
619  double integ_x(double x1, double x2, double y, std::string name) const;
620 
621  /** \brief Interpolate the integral of the data
622  respect to the y grid
623  */
624  double integ_y(double x, double y1, double y2, std::string name) const;
625 
626  /** \brief Fill a vector of interpolated values from each slice at the
627  point <tt>x,y</tt>
628  */
629  template<class vec_t>
630  void interp_slices(double x, double y, size_t nv, vec_t &v) {
631 
632  for (size_t i=0;i<list.size();i++) {
633  std::string name=get_slice_name(i);
634  v[i]=interp(x,y,name);
635  }
636 
637  return;
638  }
639 
640  /** \brief Create a new slice, named \c fpname, containing the
641  derivative of \c fname with respect to the x coordinate
642  */
643  void deriv_x(std::string fname, std::string fpname);
644 
645  /** \brief Create a new slice, named \c fpname, containing the
646  derivative of \c fname with respect to the y coordinate
647  */
648  void deriv_y(std::string fname, std::string fpname);
649 
650  //@}
651 
652  // --------------------------------------------------------
653  /// \name Extract 2-dimensional tables
654  //@{
655  /** \brief Extract a table at a fixed x grid point
656 
657  \note All of the information previously stored in \c t will
658  be lost.
659  */
660  void extract_x(double x, table<> &t);
661 
662  /** \brief Extract a table at a fixed y grid point
663 
664  \note All of the information previously stored in \c t will
665  be lost.
666  */
667  void extract_y(double y, table<> &t);
668  //@}
669 
670  // --------------------------------------------------------
671  /// \name Clear methods
672  //@{
673  /** \brief Zero the data entries but keep the slice names
674  and grid
675  */
676  void zero_table();
677 
678  /** \brief Clear everything
679  */
680  void clear();
681 
682  /** \brief Remove all of the data by setting the number
683  of lines to zero
684 
685  This leaves the column names intact and does not remove
686  the constants.
687  */
688  void clear_data();
689  //@}
690 
691  // --------------------------------------------------------
692  /// \name Summary method
693  //@{
694  /** \brief Output a summary of the information stored
695 
696  Outputs the number of constants, the grid information,
697  and a list of the slice names
698  */
699  void summary(std::ostream *out, int ncol=79) const;
700  //@}
701 
702  /// True if the size of the table has been set
703  bool is_size_set() const {
704  return size_set;
705  }
706 
707  /// True if the grid has been set
708  bool is_xy_set() const {
709  return xy_set;
710  }
711 
712  // ---------
713  // Allow HDF I/O functions to access table3d data
714 
715  friend void o2scl_hdf::hdf_output(o2scl_hdf::hdf_file &hf, table3d &t,
716  std::string name);
717 
718  friend void o2scl_hdf::hdf_input(o2scl_hdf::hdf_file &hf, table3d &t,
719  std::string name);
720 
721  // --------------------------------------------------------
722  /// \name Contour lines method
723  //@{
724 
725  /** \brief Create contour lines from the slice named \c name
726 
727  This uses \ref contour to compute contour lines (stored in \c
728  clines) from slice \c name given \c nlev contour levels in \c
729  levs .
730  */
731  template<class vec_t>
732  void slice_contours(std::string name, size_t nlev, vec_t &levs,
733  std::vector<contour_line> &clines) {
734 
735  size_t z=lookup_slice(name);
736 
737  contour co;
738  co.set_data(numx,numy,xval,yval,list[z]);
739  co.set_levels(nlev,levs);
740  co.calc_contours(clines);
741 
742  return;
743  }
744  //@}
745 
746  // --------------------------------------------------------
747  /// \name Manipulating constants
748  //@{
749  /** \brief Add a constant, or if the constant already exists, change
750  its value
751  */
752  virtual void add_constant(std::string name, double val);
753 
754  /// Remove a constant
755  virtual void remove_constant(std::string name);
756 
757  /** \brief Set a constant equal to a value, but don't add it if
758  not already present
759 
760  If \c err_on_notfound is <tt>true</tt> (the default), then
761  this function throws an exception if a constant with
762  name \c name is not found. If \c err_on_notfound is
763  <tt>false</tt>, then if a constant with name \c name
764  is not found this function just silently returns
765  \ref o2scl::exc_enotfound.
766  */
767  virtual int set_constant(std::string name, double val,
768  bool err_on_notfound=true);
769 
770  /// Test if \c name is a constant
771  virtual bool is_constant(std::string name) const;
772 
773  /// Get a constant
774  virtual double get_constant(std::string name);
775 
776  /// Get a constant by index
777  virtual void get_constant(size_t ix, std::string &name, double &val) const;
778 
779  /// Get the number of constants
780  virtual size_t get_nconsts() const {
781  return constants.size();
782  }
783  //@}
784 
785  /// Return the type, \c "table3d".
786  virtual const char *type() { return "table3d"; }
787 
788  /** \name Parsing mathematical functions specified as strings
789 
790  \comment
791  Note that doxygen doesn't format the documentation propertly
792  if the \name specification covers more than one line
793  \endcomment
794  */
795  //@{
796  /** \brief Fill a matrix from the function specified in \c function
797 
798  \comment
799  This function must return an int rather than void because
800  of the presence of the 'throw_on_err' mechanism
801  \endcomment
802  */
803  template<class resize_mat_t>
804  int function_matrix(std::string function, resize_mat_t &mat,
805  bool throw_on_err=true) {
806 
807  calculator calc;
808  std::map<std::string,double> vars;
809 
810  std::map<std::string,double>::const_iterator mit;
811  for(mit=constants.begin();mit!=constants.end();mit++) {
812  vars[mit->first]=mit->second;
813  }
814 
815  calc.compile(function.c_str(),&vars);
816 
817  if (mat.size1()!=numx || mat.size2()!=numy) {
818  mat.resize(numx,numy);
819  }
820 
821  for(size_t i=0;i<numx;i++) {
822  for(size_t j=0;j<numy;j++) {
823  vars[xname]=xval[i];
824  vars[yname]=yval[j];
825 
826  for(size_t k=0;k<list.size();k++) {
827  vars[get_slice_name(k)]=list[k](i,j);
828  }
829 
830  mat(i,j)=calc.eval(&vars);
831  }
832  }
833 
834 
835  return 0;
836  }
837 
838  /** \brief Make a column from <tt>function</tt> and add it to the table.
839 
840  If the column already exists, the data already present is
841  overwritten with the result.
842  */
843  void function_slice(std::string function, std::string col);
844  //@}
845 
846  protected:
847 
848 #ifndef DOXYGEN_INTERNAL
849 
850  /// \name Iterator types
851  //@{
852  typedef std::map<std::string,size_t,
853  std::greater<std::string> >::iterator map_iter;
854  typedef std::map<std::string,size_t,
855  std::greater<std::string> >::const_iterator map_const_iter;
856  //@}
857 
858  /// \name Data storage
859  //@{
860  /// The list of constants
861  std::map<std::string,double> constants;
862 
863  /// The size of the x grid
864  size_t numx;
865 
866  /// The size of the y grid
867  size_t numy;
868 
869  /// A tree connecting column names to list indexes
870  std::map<std::string,size_t,std::greater<std::string> > tree;
871 
872  /// The name for the x grid
873  std::string xname;
874 
875  /// The name for the y grid
876  std::string yname;
877 
878  /// The pointers to the matrices
879  std::vector<ubmatrix> list;
880 
881  /// The x grid
882  ubvector xval;
883 
884  /// The y grid
885  ubvector yval;
886 
887  /// True if the grid has been set
888  bool xy_set;
889 
890  /// True if the size of the grid has been set
891  bool size_set;
892 
893  /// True if the table has at least one slice
894  bool has_slice;
895  //@}
896 
897  /// \name Tree iterator boundaries
898  //@{
899  /// Return the beginning of the slice tree
900  map_iter begin() {return tree.begin();};
901  /// Return the end of the slice tree
902  map_iter end() {return tree.end();};
903  /// Return the beginning of the slice tree
904  map_const_iter const_begin() const {return tree.begin();};
905  /// Return the end of the slice tree
906  map_const_iter const_end() const {return tree.end();};
907  //@}
908 
909  size_t itype;
910 
911 #endif
912 
913  };
914 
915 #ifndef DOXYGEN_NO_O2NS
916 }
917 #endif
918 
919 #endif
bool size_set
True if the size of the grid has been set.
Definition: table3d.h:891
void set_xy(std::string x_name, uniform_grid< double > gx, std::string y_name, uniform_grid< double > gy)
Initialize the x-y grid with uniform_grid objects.
Definition: table3d.h:164
map_const_iter const_begin() const
Return the beginning of the slice tree.
Definition: table3d.h:904
int function_matrix(std::string function, resize_mat_t &mat, bool throw_on_err=true)
Fill a matrix from the function specified in function.
Definition: table3d.h:804
void slice_contours(std::string name, size_t nlev, vec_t &levs, std::vector< contour_line > &clines)
Create contour lines from the slice named name.
Definition: table3d.h:732
The main O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$scl names...
Definition: anneal.h:42
const ubvector & get_x_data() const
Get a const reference to the full x grid.
Definition: table3d.h:455
size_t numy
The size of the y grid.
Definition: table3d.h:867
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.
void set_slices(double x, double y, size_t nv, vec_t &vals)
Set elements in the first nv slices at the nearest location to x,y to value val.
Definition: table3d.h:279
Data table table class.
Definition: table.h:49
size_t get_nx() const
Get the x size.
Definition: table3d.h:470
double & get(size_t ix, size_t iy, std::string name)
Get element in slice name at location ix,iy
std::string xname
The name for the x grid.
Definition: table3d.h:873
invalid argument supplied by user
Definition: err_hnd.h:59
void set_slices_ret(double &x, double &y, size_t nv, vec_t &vals)
Set elements in the first nv slices at the nearest location to x,y to values vals.
Definition: table3d.h:383
map_iter begin()
Return the beginning of the slice tree.
Definition: table3d.h:900
void hdf_output(hdf_file &hf, o2scl::table3d &t, std::string name)
Output a o2scl::table3d object to a hdf_file.
void set_data(size_t sizex, size_t sizey, const vec_t &x_fun, const vec_t &y_fun, const mat_t &udata)
Set the data.
Definition: contour.h:266
void copy_to_slice(mat_t &m, std::string scol)
Copy to a slice from a generic matrix object.
Definition: table3d.h:559
size_t get_npoints() const
Get the number of points in the grid (always get_nbins()+1)
Definition: uniform_grid.h:201
size_t numx
The size of the x grid.
Definition: table3d.h:864
double interp(double x, double y, std::string name) const
Interpolate x and y in slice named name.
bool has_slice
True if the table has at least one slice.
Definition: table3d.h:894
void set_y_name(std::string name)
Set the name of the y grid variable.
Definition: table3d.h:449
bool is_xy_set() const
True if the grid has been set.
Definition: table3d.h:708
ubvector yval
The y grid.
Definition: table3d.h:885
Calculate contour lines from a two-dimensional data set.
Definition: contour.h:240
size_t get_ny() const
Get the y size.
Definition: table3d.h:475
std::vector< ubmatrix > list
The pointers to the matrices.
Definition: table3d.h:879
virtual const char * type()
Return the type, "table3d".
Definition: table3d.h:786
void set_x_name(std::string name)
Set the name of the x grid variable.
Definition: table3d.h:443
The O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$scl namespace ...
Definition: table.h:53
double eval(std::map< std::string, double > *vars=0)
Evalate the previously compiled expression using variables specified in vars.
map_const_iter const_end() const
Return the end of the slice tree.
Definition: table3d.h:906
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
Evaluate a mathematical expression in a string.
map_iter end()
Return the end of the slice tree.
Definition: table3d.h:902
Data table table class with units.
Definition: table_units.h:42
void get_slices_ret(double &x, double &y, size_t nv, vec_t &vals)
Get elements in the first nv slices at the nearest location to x,y to value val.
Definition: table3d.h:400
bool xy_set
True if the grid has been set.
Definition: table3d.h:888
A data structure containing many slices of two-dimensional data points defined on a grid...
Definition: table3d.h:78
void vector(resize_vec_t &v) const
Fill a vector with the specified grid.
Definition: uniform_grid.h:246
Store data in an O<span style=&#39;position: relative; top: 0.3em; font-size: 0.8em&#39;>2</span>scl O$_2$sc...
Definition: hdf_file.h:100
std::string yname
The name for the y grid.
Definition: table3d.h:876
virtual size_t get_nconsts() const
Get the number of constants.
Definition: table3d.h:780
ubvector xval
The x grid.
Definition: table3d.h:882
std::map< std::string, double > constants
The list of constants.
Definition: table3d.h:861
void interp_slices(double x, double y, size_t nv, vec_t &v)
Fill a vector of interpolated values from each slice at the point x,y
Definition: table3d.h:630
void add_slice_from_table(table3d &source, std::string slice, std::string dest_slice="")
This function adds a slice from a different table3d object, interpolating the results into the curren...
Definition: table3d.h:351
void get_slices(double x, double y, size_t nv, vec_t &v)
Get the data for every slice at the nearest location to x,y
Definition: table3d.h:294
void set_levels(size_t nlevels, vec_t &ulevels)
Set the contour levels.
Definition: contour.h:337
const ubvector & get_y_data() const
Get a const reference to the full y grid.
Definition: table3d.h:458
void calc_contours(std::vector< contour_line > &clines)
Calculate the contours.
void hdf_input(hdf_file &hf, o2scl::table3d &t, std::string name)
Input a o2scl::table3d object from a hdf_file.
std::map< std::string, size_t, std::greater< std::string > > tree
A tree connecting column names to list indexes.
Definition: table3d.h:870
static const double x2[5]
Definition: inte_qng_gsl.h:66
void set_xy(std::string x_name, size_t nx, const vec_t &x, std::string y_name, size_t ny, const vec2_t &y)
Initialize the x-y grid.
Definition: table3d.h:129
static const double x1[5]
Definition: inte_qng_gsl.h:48
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:59
std::string get_x_name() const
Get the name of the x grid variable.
Definition: table3d.h:433
std::string get_y_name() const
Get the name of the y grid variable.
Definition: table3d.h:438
bool is_size_set() const
True if the size of the table has been set.
Definition: table3d.h:703
Interpolation class for general vectors.
Definition: interp.h:1577

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