![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_TABLE3D_H 00024 #define O2SCL_TABLE3D_H 00025 00026 #include <iostream> 00027 #include <fstream> 00028 #include <vector> 00029 #include <string> 00030 #include <cmath> 00031 #include <sstream> 00032 #include <o2scl/misc.h> 00033 #include <o2scl/err_hnd.h> 00034 #include <o2scl/multi_funct.h> 00035 #include <o2scl/search_vec.h> 00036 #include <o2scl/ovector_tlate.h> 00037 #include <o2scl/interp.h> 00038 #include <o2scl/smart_interp.h> 00039 #include <o2scl/table.h> 00040 00041 #ifndef DOXYGENP 00042 namespace o2scl { 00043 #endif 00044 00045 /** \brief A data structure containing many slices of two-dimensional 00046 data points defined on a grid 00047 00048 \future Improve interpolation and derivative caching 00049 \future Make a 'const' version of the interpolation functions 00050 \future Should there be a clear_grid() function separate from 00051 clear_data() and clear_table()? 00052 */ 00053 class table3d { 00054 00055 public: 00056 00057 /** \brief Create a new 3D \table 00058 */ 00059 table3d(); 00060 00061 virtual ~table3d(); 00062 00063 /// \name Initialization 00064 //@{ 00065 /** \brief Initialize the x-y grid 00066 00067 This function will not allow you to redefine the grid when 00068 there is data in the \table if a grid of a different size was 00069 already set from a previous call to either set_xy() or 00070 set_size(). However, you may freely redefine the grid after a 00071 call to clear_data() or clear_table(). You may change 00072 individual grid points at any time with set_grid_x() and 00073 set_grid_y(). 00074 00075 */ 00076 template<class vec2_t> int set_xy(std::string x_name, size_t nx, 00077 const vec2_t &x, std::string y_name, 00078 size_t ny, const vec2_t &y) { 00079 if (has_slice && (size_set || xy_set) && (nx!=numx || ny!=numy)) { 00080 O2SCL_ERR_RET("Size cannot be reset in table3d::set_xy().", 00081 o2scl::gsl_einval); 00082 } 00083 if (xy_set) { 00084 xval.free(); 00085 yval.free(); 00086 } 00087 numx=nx; 00088 numy=ny; 00089 xname=x_name; 00090 yname=y_name; 00091 xval.allocate(nx); 00092 yval.allocate(ny); 00093 for(size_t i=0;i<nx;i++) (xval)[i]=x[i]; 00094 for(size_t i=0;i<ny;i++) (yval)[i]=y[i]; 00095 size_set=true; 00096 xy_set=true; 00097 return 0; 00098 } 00099 00100 /** \brief Initialize \table size 00101 00102 This function will not allow you to resize the \table if it 00103 already has data or if the size has already been set with the 00104 set_xy() function, unless you clear the data with clear_data() 00105 or the \table with clear_table() first. 00106 */ 00107 int set_size(size_t nx, size_t ny); 00108 //@} 00109 00110 // -------------------------------------------------------- 00111 /// \name On-grid get and set methods 00112 //@{ 00113 00114 /** \brief Set element in slice \c name at location <tt>ix,iy</tt> 00115 to value \c val 00116 */ 00117 int set(size_t ix, size_t iy, std::string name, double val); 00118 00119 /** \brief Set element in slice of index \c z at location 00120 <tt>ix,iy</tt> to value \c val . 00121 */ 00122 int set(size_t ix, size_t iy, size_t z, double val); 00123 00124 /** \brief Get element in slice \c name at location 00125 <tt>ix,iy</tt> 00126 */ 00127 double &get(size_t ix, size_t iy, std::string name); 00128 00129 /** \brief Get element in slice \c name at location 00130 <tt>ix,iy</tt> (const version) 00131 */ 00132 const double &get(size_t ix, size_t iy, std::string name) const; 00133 00134 /** \brief Get element in slice of index \c z at location 00135 <tt>ix,iy</tt> 00136 */ 00137 double &get(size_t ix, size_t iy, size_t z); 00138 00139 /** \brief Get element in slice of index \c z at location 00140 <tt>ix,iy</tt> (const version) 00141 */ 00142 const double &get(size_t ix, size_t iy, size_t z) const; 00143 //@} 00144 00145 // -------------------------------------------------------- 00146 /** \name Off-grid get and set methods 00147 00148 These methods return the value of a slice on the grid 00149 point nearest to a user-specified location. For 00150 interpolation into a point off the grid, use 00151 \ref table3d::interp(). 00152 */ 00153 //@{ 00154 00155 /** \brief Set element in slice \c name at the nearest location to 00156 <tt>x,y</tt> to value \c val 00157 */ 00158 int set_val(double x, double y, std::string name, double val); 00159 00160 /** \brief Set element in slice of index \c z at the nearest 00161 location to <tt>x,y</tt> to value \c val 00162 */ 00163 int set_val(double x, double y, size_t z, double val); 00164 00165 /** \brief Get element in slice \c name at location closest to 00166 <tt>x,y</tt> 00167 */ 00168 double &get_val(double x, double y, std::string name); 00169 00170 /** \brief Get element in slice \c name at location closest to 00171 <tt>x,y</tt> 00172 */ 00173 const double &get_val(double x, double y, std::string name) const; 00174 00175 /** \brief Get element in slice of index \c z at location closest 00176 to <tt>x,y</tt> 00177 */ 00178 double &get_val(double x, double y, size_t z); 00179 00180 /** \brief Get element in slice of index \c z at location closest 00181 to <tt>x,y</tt> 00182 */ 00183 const double &get_val(double x, double y, size_t z) const; 00184 00185 /** \brief Set elements in the first <tt>nv</tt> slices at the 00186 nearest location to <tt>x,y</tt> to value \c val 00187 */ 00188 template<class vec_t> 00189 int set_slices(double x, double y, size_t nv, vec_t &vals) { 00190 size_t ix, iy; 00191 lookup_x(x,ix); 00192 lookup_y(y,iy); 00193 00194 for(size_t i=0;i<nv && i<list.size();i++) { 00195 list[i][ix][iy]=vals[i]; 00196 } 00197 return 0; 00198 } 00199 00200 /** \brief Get the data for every slice at the nearest location to 00201 <tt>x,y</tt> 00202 */ 00203 template<class vec_t> 00204 int get_slices(double x, double y, size_t nv, vec_t &v) { 00205 00206 size_t ix, iy; 00207 00208 lookup_x(x,ix); 00209 lookup_y(y,iy); 00210 00211 for(size_t i=0;i<nv && i<list.size();i++) { 00212 v[i]=list[i][ix][iy]; 00213 } 00214 00215 return 0; 00216 } 00217 00218 //@} 00219 00220 // -------------------------------------------------------- 00221 /// \name Off-grid get and set methods returning nearest point 00222 //@{ 00223 00224 /** \brief Set element in slice \c name at the nearest location to 00225 <tt>x,y</tt> to value \c val 00226 */ 00227 int set_val_ret(double &x, double &y, std::string name, double val); 00228 00229 /** \brief Set element in slice of index \c z at the nearest 00230 location to <tt>x,y</tt> to value \c val 00231 */ 00232 int set_val_ret(double &x, double &y, size_t z, double val); 00233 00234 /** \brief Get element in slice \c name at location closest to 00235 <tt>x,y</tt>, and also return the corresponding values of \c x 00236 and \c y 00237 */ 00238 double &get_val_ret(double &x, double &y, std::string name); 00239 00240 /** \brief Get element in slice \c name at location closest to 00241 <tt>x,y</tt>, and also return the corresponding values of \c x 00242 and \c y 00243 */ 00244 const double &get_val_ret(double &x, double &y, std::string name) const; 00245 00246 /** \brief Get element in slice of index \c z at location closest 00247 to <tt>x,y</tt>, and also return the corresponding values of 00248 \c x and \c y 00249 */ 00250 double &get_val_ret(double &x, double &y, size_t z); 00251 00252 /** \brief Get element in slice of index \c z at location closest 00253 to <tt>x,y</tt>, and also return the corresponding values of 00254 \c x and \c y 00255 */ 00256 const double &get_val_ret(double &x, double &y, size_t z) const; 00257 00258 /** \brief Set elements in the first <tt>nv</tt> slices at the 00259 nearest location to <tt>x,y</tt> to values \c vals 00260 */ 00261 template<class vec_t> 00262 int set_slices_ret(double &x, double &y, size_t nv, vec_t &vals) { 00263 size_t ix, iy; 00264 lookup_x(x,ix); 00265 lookup_y(y,iy); 00266 x=xval[ix]; 00267 y=yval[iy]; 00268 00269 for(size_t i=0;i<nv && i<list.size();i++) { 00270 list[i][ix][iy]=vals[i]; 00271 } 00272 return 0; 00273 } 00274 00275 /** \brief Get elements in the first <tt>nv</tt> slices at the 00276 nearest location to <tt>x,y</tt> to value \c val 00277 */ 00278 template<class vec_t> 00279 int get_slices_ret(double &x, double &y, size_t nv, vec_t &vals) { 00280 size_t ix, iy; 00281 lookup_x(x,ix); 00282 lookup_y(y,iy); 00283 x=xval[ix]; 00284 y=yval[iy]; 00285 00286 for(size_t i=0;i<nv && i<list.size();i++) { 00287 vals[i]=list[i][ix][iy]; 00288 } 00289 return 0; 00290 } 00291 00292 //@} 00293 00294 // -------------------------------------------------------- 00295 /// \name Grid information get and set methods 00296 //@{ 00297 00298 /// Set x grid point at index \c ix 00299 int set_grid_x(size_t ix, double val); 00300 00301 /// Set y grid point at index \c iy 00302 int set_grid_y(size_t iy, double val); 00303 00304 /// Get x grid point at index \c ix 00305 double get_grid_x(size_t ix); 00306 00307 /// Get y grid point at index \c iy 00308 double get_grid_y(size_t iy); 00309 00310 /// Get the name of the x grid variable 00311 std::string get_x_name() const { 00312 return xname; 00313 } 00314 00315 /// Get the name of the y grid variable 00316 std::string get_y_name() const { 00317 return yname; 00318 } 00319 00320 /// Set the name of the x grid variable 00321 int set_x_name(std::string name) { 00322 xname=name; 00323 return 0; 00324 } 00325 00326 /// Set the name of the y grid variable 00327 int set_y_name(std::string name) { 00328 yname=name; 00329 return 0; 00330 } 00331 00332 /// Get a const reference to the full x grid 00333 const ovector &get_x_data() const { return xval; } 00334 00335 /// Get a const reference to the full y grid 00336 const ovector &get_y_data() const { return yval; } 00337 00338 //@} 00339 00340 // -------------------------------------------------------- 00341 /// \name Size get methods 00342 //@{ 00343 00344 /// Get the size of the slices 00345 int get_size(size_t &nx, size_t &ny) const; 00346 00347 /// Get the x size 00348 int get_nx() const { 00349 return numx; 00350 } 00351 00352 /// Get the y size 00353 int get_ny() const { 00354 return numy; 00355 } 00356 00357 /// Get the number of slices 00358 int get_nslices() const; 00359 //@} 00360 00361 // -------------------------------------------------------- 00362 /// \name Slice manipulation 00363 //@{ 00364 00365 /// Create a set of new slices specified in the string \c names 00366 int line_of_names(std::string names); 00367 00368 /** \brief Returns the name of slice with index \c z 00369 */ 00370 std::string get_slice_name(size_t z) const; 00371 00372 /** \brief Add a new slice 00373 */ 00374 int new_slice(std::string name); 00375 00376 /** \brief Set all of the values in slice \c name to \c val 00377 */ 00378 int set_slice_all(std::string name, double val); 00379 00380 /** \brief Find the index for column named \c name 00381 */ 00382 int lookup_slice(std::string name, size_t &ix) const; 00383 00384 /** \brief Return true if slice is already present 00385 */ 00386 bool is_slice(std::string name, int &ix); 00387 00388 /** \brief Rename slice named \c olds to \c news 00389 00390 This is slow since we have to delete the column and re-insert 00391 it. This process in turn mangles all of the iterators in the 00392 list. 00393 */ 00394 int rename_slice(std::string olds, std::string news); 00395 00396 /** \brief Make a new slice named \c dest which is a copy 00397 of the slice with name given in \c src. 00398 */ 00399 int copy_slice(std::string src, std::string dest); 00400 00401 /** \brief Initialize all values of slice named \c scol to \c val 00402 */ 00403 int init_slice(std::string scol, double val); 00404 00405 /// Return a constant reference to a slice 00406 const omatrix &get_slice(std::string scol) const; 00407 00408 /// Return a constant reference to a slice 00409 const omatrix &get_slice(size_t iz) const; 00410 00411 /// Return a constant reference to a slice 00412 omatrix &get_slice(std::string scol); 00413 00414 /// Return a constant reference to a slice 00415 omatrix &get_slice(size_t iz); 00416 00417 /** \brief Return a constant reference to all the slice data 00418 00419 \comment 00420 This isn't designated const, i.e. as 00421 const std::vector<omatrix> &get_data() const; 00422 because it would then have to be 00423 const std::vector<const omatrix> &get_data() const; 00424 \endcomment 00425 */ 00426 const std::vector<omatrix> &get_data(); 00427 //@} 00428 00429 // -------------------------------------------------------- 00430 /// \name Lookup and search methods 00431 //@{ 00432 00433 /** \brief Look for a value in the x grid 00434 */ 00435 int lookup_x(double val, size_t &ix) const; 00436 00437 /** \brief Look for a value in the y grid 00438 */ 00439 int lookup_y(double val, size_t &iy) const; 00440 00441 /** \brief Look for a value in a specified slice 00442 */ 00443 int lookup(double val, std::string slice, size_t &ix, size_t &iy) const; 00444 //@} 00445 00446 // -------------------------------------------------------- 00447 /// \name Interpolation, differentiation, and integration 00448 //@{ 00449 00450 /** \brief Specify the base interpolation objects to use 00451 */ 00452 int set_interp(base_interp_mgr<ovector_const_view> &b1, 00453 base_interp_mgr<ovector_const_subvector> &b2); 00454 00455 /** \brief Interpolate \c x and \c y in slice named \c name 00456 */ 00457 double interp(double x, double y, std::string name); 00458 00459 /** \brief Interpolate the derivative of the data with respect to 00460 the x grid at point \c x and \c y in slice named \c name 00461 */ 00462 double deriv_x(double x, double y, std::string name); 00463 00464 /** \brief Interpolate the derivative of the data with respect to 00465 the y grid at point \c x and \c y in slice named \c name 00466 */ 00467 double deriv_y(double x, double y, std::string name); 00468 00469 /** \brief Interpolate the mixed second derivative of the data at 00470 point \c x and \c y in slice named \c name 00471 */ 00472 double deriv_xy(double x, double y, std::string name); 00473 00474 /** \brief Interpolate the integral of the data 00475 respect to the x grid 00476 */ 00477 double integ_x(double x1, double x2, double y, std::string name); 00478 00479 /** \brief Interpolate the integral of the data 00480 respect to the y grid 00481 */ 00482 double integ_y(double x, double y1, double y2, std::string name); 00483 00484 /** \brief Fill a vector of interpolated values from each slice at the 00485 point <tt>x,y</tt> 00486 */ 00487 template<class vec_t> 00488 int interp_slices(double x, double y, size_t nv, vec_t &v) { 00489 00490 for (size_t i=0;i<list.size();i++) { 00491 std::string name=get_slice_name(i); 00492 v[i]=interp(x,y,name); 00493 } 00494 00495 return 0; 00496 } 00497 00498 //@} 00499 00500 // -------------------------------------------------------- 00501 /// \name Extract 2-dimensional tables 00502 //@{ 00503 /** \brief Extract a table at a fixed x grid point 00504 00505 \note All of the information previously stored in \c t will 00506 be lost. 00507 */ 00508 int extract_x(double x, table &t); 00509 00510 /** \brief Extract a table at a fixed y grid point 00511 00512 \note All of the information previously stored in \c t will 00513 be lost. 00514 */ 00515 int extract_y(double y, table &t); 00516 //@} 00517 00518 // -------------------------------------------------------- 00519 /// \name Clear methods 00520 //@{ 00521 /** \brief Zero the data entries but keep the slice names 00522 and grid 00523 */ 00524 int zero_table(); 00525 00526 /** \brief Clear the table and the slice names 00527 */ 00528 void clear_table(); 00529 00530 /** \brief Remove all of the data by setting the number 00531 of lines to zero 00532 00533 This leaves the column names intact and does not remove 00534 the constants. 00535 */ 00536 void clear_data(); 00537 //@} 00538 00539 // -------------------------------------------------------- 00540 /// \name Summary method 00541 //@{ 00542 /** \brief Output a summary of the information stored 00543 00544 Outputs the number of constants, the grid information, 00545 and a list of the slice names 00546 */ 00547 int summary(std::ostream *out, int ncol=79) const; 00548 //@} 00549 00550 // -------------------------------------------------------- 00551 /** \name Histogram-like functions 00552 */ 00553 //@{ 00554 /** \brief Update a histogram entry 00555 00556 Assuming that the histogram bins are given in column named \c 00557 ix_col, this updates the histogram found in column \c scol at 00558 index location \c ix by incrementing it by an amount given in 00559 \c inc. 00560 */ 00561 int hist_update(double ix, double iy, std::string scol, double inc=1.0); 00562 00563 /** \brief Get a histogram entry 00564 00565 Assuming that the histogram bins are given in column 00566 named \c ix_col, this returns the histogram entry found 00567 in column \c scol at index location \c ix . 00568 */ 00569 double hist_get(double ix, double iy, std::string scol) const; 00570 00571 /** \brief Set a histogram entry 00572 00573 Assuming that the histogram bins are given in column 00574 named \c ix_col, this sets the histogram entry found 00575 in column \c scol at index location \c ix to the 00576 value given in \c value . 00577 */ 00578 int hist_set(double ix, double iy, std::string scol, double value); 00579 //@} 00580 00581 bool is_size_set() const { 00582 return size_set; 00583 } 00584 00585 bool is_xy_set() const { 00586 return xy_set; 00587 } 00588 00589 #ifdef O2SCL_NEVER_DEFINED 00590 00591 // -------------------------------------------------------- 00592 /// \name Contour lines method 00593 //@{ 00594 00595 /** \brief Create contour lines from the slice named \c name 00596 00597 This uses \ref contour to compute contour lines (stored in \c 00598 clines) from slice \c name given \c nlev contour levels in \c 00599 levs . 00600 */ 00601 template<class vec_t> 00602 int slice_contours(std::string name, size_t nlev, vec_t &levs, 00603 std::vector<contour_line> &clines) { 00604 size_t z=0; 00605 int ret=lookup_slice(name,z); 00606 00607 contour co; 00608 // Note that the contour class stores the matrix data in (y,x) 00609 // order, not (x,y) so the order has to be reversed here. 00610 co.set_data(numy,numx,yval,xval,list[z]); 00611 co.set_levels(nlev,levs); 00612 co.calc_contours(clines); 00613 00614 return 0; 00615 } 00616 //@} 00617 00618 #endif 00619 00620 // -------------------------------------------------------- 00621 /// \name Manipulating constants 00622 //@{ 00623 /// Add a constant 00624 virtual int add_constant(std::string name, double val); 00625 00626 /// Remove a constant 00627 virtual int remove_constant(std::string name); 00628 00629 /// Add a constant 00630 virtual int set_constant(std::string name, double val); 00631 00632 /// Get a constant 00633 virtual double get_constant(std::string name); 00634 00635 /// Get a constant by index 00636 virtual int get_constant(size_t ix, std::string &name, double &val) const; 00637 00638 /// Get the number of constants 00639 virtual size_t get_nconsts() const { 00640 return constants.size(); 00641 } 00642 //@} 00643 00644 /// \name Default interpolation objects 00645 //@{ 00646 def_interp_mgr<ovector_const_view,cspline_interp> dim1; 00647 00648 def_interp_mgr<ovector_const_subvector,cspline_interp> dim2; 00649 //@} 00650 00651 /// Return the type, \c "table3d". 00652 virtual const char *type() { return "table3d"; } 00653 00654 protected: 00655 00656 #ifndef DOXYGEN_INTERNAL 00657 00658 /// \name Interpolation data 00659 //@{ 00660 /// The base interpolation object 00661 base_interp_mgr<ovector_const_view> *bimp1; 00662 00663 /// The subvector base interpolation object 00664 base_interp_mgr<ovector_const_subvector> *bimp2; 00665 00666 /// The array of sm_interp_vec pointers 00667 sm_interp_vec **si; 00668 00669 /// Matrices for interpolation 00670 omatrix_col **aci; 00671 //@} 00672 00673 /// \name Iterator types 00674 //@{ 00675 typedef std::map<std::string,size_t, string_comp>::iterator map_iter; 00676 typedef std::map<std::string,size_t, string_comp>::const_iterator 00677 map_const_iter; 00678 //@} 00679 00680 /// \name Data storage 00681 //@{ 00682 /// The list of constants 00683 std::map<std::string,double> constants; 00684 00685 /// The size of the x grid 00686 size_t numx; 00687 00688 /// The size of the y grid 00689 size_t numy; 00690 00691 /// A tree connecting column names to list indexes 00692 std::map<std::string,size_t,string_comp> tree; 00693 00694 /// The name for the x grid 00695 std::string xname; 00696 00697 /// The name for the y grid 00698 std::string yname; 00699 00700 /// The pointers to the matrices 00701 std::vector<omatrix> list; 00702 00703 /// The x grid 00704 ovector xval; 00705 00706 /// The y grid 00707 ovector yval; 00708 00709 /// True if the grid has been set 00710 bool xy_set; 00711 00712 /// True if the size of the grid has been set 00713 bool size_set; 00714 00715 /// True if the table has at least one slice 00716 bool has_slice; 00717 //@} 00718 00719 /// \name Tree iterator boundaries 00720 //@{ 00721 /// Return the beginning of the slice tree 00722 map_iter begin() {return tree.begin();}; 00723 /// Return the end of the slice tree 00724 map_iter end() {return tree.end();}; 00725 /// Return the beginning of the slice tree 00726 map_const_iter const_begin() const {return tree.begin();}; 00727 /// Return the end of the slice tree 00728 map_const_iter const_end() const {return tree.end();}; 00729 //@} 00730 00731 #endif 00732 00733 }; 00734 00735 #ifndef DOXYGENP 00736 } 00737 #endif 00738 00739 #endif
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).