00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, 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/collection.h> 00036 #include <o2scl/search_vec.h> 00037 #include <o2scl/ovector_tlate.h> 00038 #include <o2scl/interp.h> 00039 #include <o2scl/smart_interp.h> 00040 #include <o2scl/table.h> 00041 00042 #ifndef DOXYGENP 00043 namespace o2scl { 00044 #endif 00045 00046 /** 00047 \brief A data structure containing many slices of two-dimensional 00048 data points defined on a grid 00049 00050 \future Improve interpolation and derivative caching 00051 \future Make a 'const' version of the interpolation functions 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 /** 00066 \brief Initialize the x-y grid 00067 00068 This function will not allow you to redefine the grid when 00069 there is data in the \table if a grid of a different size was 00070 already set from a previous call to either set_xy() or 00071 set_size(). However, you may freely redefine the grid 00072 after a call to clear_data() or clear_table(). You may change 00073 individual grid points at any time with set_grid_x() and 00074 set_grid_y(). 00075 00076 */ 00077 template<class vec2_t> int set_xy(std::string x_name, size_t nx, 00078 const vec2_t &x, std::string y_name, 00079 size_t ny, const vec2_t &y) { 00080 if (has_slice && (size_set || xy_set) && (nx!=numx || ny!=numy)) { 00081 O2SCL_ERR_RET("Size cannot be reset in table3d::set_xy().", 00082 o2scl::gsl_einval); 00083 } 00084 if (xy_set) { 00085 xval.free(); 00086 yval.free(); 00087 } 00088 numx=nx; 00089 numy=ny; 00090 xname=x_name; 00091 yname=y_name; 00092 xval.allocate(nx); 00093 yval.allocate(ny); 00094 for(size_t i=0;i<nx;i++) (xval)[i]=x[i]; 00095 for(size_t i=0;i<ny;i++) (yval)[i]=y[i]; 00096 size_set=true; 00097 xy_set=true; 00098 return 0; 00099 } 00100 00101 /** 00102 \brief Initialize \table size 00103 00104 This function will not allow you to resize the \table if it 00105 already has data or if the size has already been set with the 00106 set_xy() function, unless you clear the data with clear_data() 00107 or the \table with clear_table() first. 00108 */ 00109 int set_size(size_t nx, size_t ny); 00110 //@} 00111 00112 // -------------------------------------------------------- 00113 /// \name On-grid get and set methods 00114 //@{ 00115 00116 /** \brief Set element in slice \c name at location <tt>ix,iy</tt> 00117 to value \c val 00118 */ 00119 int set(size_t ix, size_t iy, std::string name, double val); 00120 00121 /** \brief Set element in slice of index \c z at location 00122 <tt>ix,iy</tt> to value \c val . 00123 */ 00124 int set(size_t ix, size_t iy, size_t z, double val); 00125 00126 /** \brief Get element in slice \c name at location 00127 <tt>ix,iy</tt> 00128 */ 00129 double &get(size_t ix, size_t iy, std::string name); 00130 00131 /** \brief Get element in slice \c name at location 00132 <tt>ix,iy</tt> (const version) 00133 */ 00134 const double &get(size_t ix, size_t iy, std::string name) const; 00135 00136 /** \brief Get element in slice of index \c z at location 00137 <tt>ix,iy</tt> 00138 */ 00139 double &get(size_t ix, size_t iy, size_t z); 00140 00141 /** \brief Get element in slice of index \c z at location 00142 <tt>ix,iy</tt> (const version) 00143 */ 00144 const double &get(size_t ix, size_t iy, size_t z) const; 00145 //@} 00146 00147 // -------------------------------------------------------- 00148 /** \name Off-grid get and set methods 00149 00150 These methods return the value of a slice on the grid 00151 point nearest to a user-specified location. For 00152 interpolation into a point off the grid, use 00153 \ref table3d::interp(). 00154 */ 00155 //@{ 00156 00157 /** \brief Set element in slice \c name at the nearest location to 00158 <tt>x,y</tt> to value \c val 00159 */ 00160 int set_val(double x, double y, std::string name, double val); 00161 00162 /** \brief Set element in slice of index \c z at the nearest 00163 location to <tt>x,y</tt> to value \c val 00164 */ 00165 int set_val(double x, double y, size_t z, double val); 00166 00167 /** \brief Get element in slice \c name at location closest to 00168 <tt>x,y</tt>, and also return the corresponding values of \c x 00169 and \c y 00170 */ 00171 double &get_val(double x, double y, std::string name); 00172 00173 /** \brief Get element in slice \c name at location closest to 00174 <tt>x,y</tt>, and also return the corresponding values of \c x 00175 and \c y 00176 */ 00177 const double &get_val(double x, double y, std::string name) const; 00178 00179 /** \brief Get element in slice of index \c z at location closest 00180 to <tt>x,y</tt>, and also return the corresponding values of 00181 \c x and \c y 00182 */ 00183 double &get_val(double x, double y, size_t z); 00184 00185 /** \brief Get element in slice of index \c z at location closest 00186 to <tt>x,y</tt>, and also return the corresponding values of 00187 \c x and \c y 00188 */ 00189 const double &get_val(double x, double y, size_t z) const; 00190 00191 /** \brief Set elements in the first <tt>nv</tt> slices at the 00192 nearest location to <tt>x,y</tt> to value \c val 00193 */ 00194 template<class vec_t> 00195 int set_slices(double x, double y, size_t nv, vec_t &vals) { 00196 size_t ix, iy; 00197 lookup_x(x,ix); 00198 lookup_y(y,iy); 00199 00200 for(size_t i=0;i<nv && i<list.size();i++) { 00201 list[i][ix][iy]=vals[i]; 00202 } 00203 return 0; 00204 } 00205 00206 /// Get all the slice data from a point 00207 template<class vec_t, class alloc_t> 00208 int get_point(double x, double y, vec_t &v) { 00209 alloc_t ao; 00210 ao.allocate(v,list.size()); 00211 for (size_t i=0;i<list.size();i++) { 00212 v[i]=interp(x,y,get_slice_name(i)); 00213 } 00214 ao.free(v); 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 value \c val 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 //@} 00276 00277 // -------------------------------------------------------- 00278 /// \name Grid information get and set methods 00279 //@{ 00280 00281 /// Set x grid point at index \c ix 00282 int set_grid_x(size_t ix, double val); 00283 00284 /// Set y grid point at index \c iy 00285 int set_grid_y(size_t iy, double val); 00286 00287 /// Get x grid point at index \c ix 00288 double get_grid_x(size_t ix); 00289 00290 /// Get y grid point at index \c iy 00291 double get_grid_y(size_t iy); 00292 00293 /// Get the name of the x grid variable 00294 std::string get_x_name() { 00295 return xname; 00296 } 00297 00298 /// Get the name of the y grid variable 00299 std::string get_y_name() { 00300 return yname; 00301 } 00302 00303 /// Set the name of the x grid variable 00304 int set_x_name(std::string name) { 00305 xname=name; 00306 return 0; 00307 } 00308 00309 /// Set the name of the y grid variable 00310 int set_y_name(std::string name) { 00311 yname=name; 00312 return 0; 00313 } 00314 00315 /// Get a const reference to the full x grid 00316 const ovector &get_x_data() const { return xval; } 00317 00318 /// Get a const reference to the full y grid 00319 const ovector &get_y_data() const { return yval; } 00320 00321 //@} 00322 00323 // -------------------------------------------------------- 00324 /// \name Size get methods 00325 //@{ 00326 00327 /// Get the size of each slice 00328 int get_size(size_t &nx, size_t &ny) const; 00329 00330 /// Get the x size 00331 int get_nx() const { 00332 return numx; 00333 } 00334 00335 /// Get the y size 00336 int get_ny() const { 00337 return numy; 00338 } 00339 00340 /// Get the number of slices 00341 int get_nslices() const; 00342 00343 //@} 00344 00345 // -------------------------------------------------------- 00346 /// \name Slice manipulation 00347 //@{ 00348 00349 /// Create a set of new slices specified in the string \c names 00350 int line_of_names(std::string names); 00351 00352 /** \brief Returns the name of slice with index \c col 00353 */ 00354 std::string get_slice_name(size_t col) const; 00355 00356 /** \brief Add a new column owned by the \table 00357 */ 00358 int new_slice(std::string name); 00359 00360 /** 00361 \brief Find the index for column named \c name 00362 */ 00363 int lookup_slice(std::string name, size_t &ix) const; 00364 00365 /** 00366 \brief Return true if slice is already present 00367 */ 00368 bool is_slice(std::string name, int &ix); 00369 00370 /** \brief Rename slice named \c olds to \c news 00371 00372 This is slow since we have to delete the column and re-insert 00373 it. This process in turn mangles all of the iterators in the 00374 list. 00375 */ 00376 int rename_slice(std::string olds, std::string news); 00377 00378 /** \brief Make a new column named \c dest equal to \c src 00379 */ 00380 int copy_slice(std::string src, std::string dest); 00381 00382 /** \brief Initialize all values of slice named \c scol to \c val 00383 00384 Note that this does not initialize elements beyond 00385 nlines so that if the number of rows is increased afterwards, the 00386 new rows will have uninitialized values. 00387 */ 00388 int init_slice(std::string scol, double val); 00389 00390 /// Return a constant reference to a slice 00391 const omatrix &get_slice(std::string scol) const; 00392 00393 /// Return a constant reference to a slice 00394 const omatrix &get_slice(size_t iz) const; 00395 00396 /// Return a constant reference to all the slice data 00397 const std::vector<omatrix> &get_data() const; 00398 //@} 00399 00400 // -------------------------------------------------------- 00401 /// \name Lookup and search methods 00402 //@{ 00403 00404 /** 00405 \brief Look for a value in the x grid 00406 */ 00407 int lookup_x(double val, size_t &ix) const; 00408 00409 /** 00410 \brief Look for a value in the y grid 00411 */ 00412 int lookup_y(double val, size_t &iy) const; 00413 00414 /** 00415 \brief Look for a value in the grid 00416 */ 00417 int lookup(double val, std::string slice, size_t &ix, size_t &iy) const; 00418 //@} 00419 00420 // -------------------------------------------------------- 00421 /// \name Interpolation, differentiation, and integration 00422 //@{ 00423 00424 /** 00425 \brief Specify the base interpolation objects to use 00426 */ 00427 int set_interp(base_interp_mgr<ovector_const_view> &b1, 00428 base_interp_mgr<ovector_const_subvector> &b2); 00429 00430 /** 00431 \brief Interpolate \c x and \c y in slice named \c name 00432 00433 */ 00434 double interp(double x, double y, std::string name); 00435 00436 /** 00437 \brief Interpolate the derivative of the data with 00438 respect to the x grid at point 00439 \c x and \c y in slice named \c name 00440 */ 00441 double deriv_x(double x, double y, std::string name); 00442 00443 /** 00444 \brief Interpolate the derivative of the data with 00445 respect to the y grid at point 00446 \c x and \c y in slice named \c name 00447 */ 00448 double deriv_y(double x, double y, std::string name); 00449 00450 /** 00451 \brief Interpolate the mixed second 00452 derivative of the data at point 00453 \c x and \c y in slice named \c name 00454 */ 00455 double deriv_xy(double x, double y, std::string name); 00456 00457 /** 00458 \brief Interpolate the integral of the data 00459 respect to the x grid 00460 */ 00461 double integ_x(double x1, double x2, double y, std::string name); 00462 00463 /** 00464 \brief Interpolate the integral of the data 00465 respect to the y grid 00466 */ 00467 double integ_y(double x, double y1, double y2, std::string name); 00468 00469 //@} 00470 00471 // -------------------------------------------------------- 00472 /// \name Extract 2-dimensional tables 00473 //@{ 00474 /// Extract a table at a fixed x grid point 00475 int extract_x(double x, table &t); 00476 00477 /// Extract a table at a fixed y grid point 00478 int extract_y(double y, table &t); 00479 //@} 00480 00481 // -------------------------------------------------------- 00482 /// \name Clear methods 00483 //@{ 00484 /** \brief Zero the data entries but keep the column names 00485 and nlines fixed 00486 */ 00487 int zero_table(); 00488 00489 /** \brief Clear the table and the slice names 00490 */ 00491 void clear_table(); 00492 00493 /** \brief Remove all of the data by setting the number 00494 of lines to zero 00495 00496 This leaves the column names intact and does not remove 00497 the constants. 00498 */ 00499 void clear_data(); 00500 //@} 00501 00502 // -------------------------------------------------------- 00503 /// \name Summary method 00504 //@{ 00505 /** 00506 \brief Output a summary of the information stored 00507 00508 Outputs the number of constants, the grid information, 00509 and a list of the slice names 00510 */ 00511 int summary(std::ostream *out, int ncol=79) const; 00512 //@} 00513 00514 // -------------------------------------------------------- 00515 /// \name Manipulating constants 00516 //@{ 00517 /// Add a constant 00518 virtual int add_constant(std::string name, double val); 00519 00520 /// Remove a constant 00521 virtual int remove_constant(std::string name); 00522 00523 /// Add a constant 00524 virtual int set_constant(std::string name, double val); 00525 00526 /// Get a constant 00527 virtual double get_constant(std::string name); 00528 //@} 00529 00530 /// \name Default interpolation objects 00531 //@{ 00532 def_interp_mgr<ovector_const_view,cspline_interp> dim1; 00533 00534 def_interp_mgr<ovector_const_subvector,cspline_interp> dim2; 00535 //@} 00536 00537 /// Return the type, \c "table3d". 00538 virtual const char *type() { return "table3d"; } 00539 00540 protected: 00541 00542 #ifndef DOXYGEN_INTERNAL 00543 00544 /// \name Interpolation data 00545 //@{ 00546 /// The base interpolation object 00547 base_interp_mgr< ovector_const_view> *bimp1; 00548 00549 /// The subvector base interpolation object 00550 base_interp_mgr< ovector_const_subvector> *bimp2; 00551 00552 /// The array of sm_interp_vec pointers 00553 sm_interp_vec **si; 00554 /// Matrices for interpolation 00555 omatrix_col **aci; 00556 //@} 00557 00558 friend class table3d_io_type; 00559 00560 /// \name Iterator types 00561 //@{ 00562 typedef std::map<std::string,size_t, string_comp>::iterator map_iter; 00563 typedef std::map<std::string,size_t, string_comp>::const_iterator 00564 map_const_iter; 00565 //@} 00566 00567 /// \name Data storage 00568 //@{ 00569 /// The list of constants 00570 std::map<std::string,double> constants; 00571 00572 /// The size of the x grid 00573 size_t numx; 00574 00575 /// The size of the y grid 00576 size_t numy; 00577 00578 /// A tree connecting column names to list indexes 00579 std::map<std::string,size_t, string_comp> tree; 00580 00581 /// The name for the x grid 00582 std::string xname; 00583 00584 /// The name for the y grid 00585 std::string yname; 00586 00587 /// The pointers to the matrices 00588 std::vector<omatrix> list; 00589 00590 /// The x grid 00591 ovector xval; 00592 00593 /// The y grid 00594 ovector yval; 00595 00596 /// True if the grid has been set 00597 bool xy_set; 00598 00599 /// True if the size of the grid has been set 00600 bool size_set; 00601 00602 /// True if the table has at least one slice 00603 bool has_slice; 00604 //@} 00605 00606 /// \name Tree iterator boundaries 00607 //@{ 00608 /// Return the beginning of the slice tree 00609 map_iter begin() {return tree.begin();}; 00610 /// Return the end of the slice tree 00611 map_iter end() {return tree.end();}; 00612 /// Return the beginning of the slice tree 00613 map_const_iter const_begin() const {return tree.begin();}; 00614 /// Return the end of the slice tree 00615 map_const_iter const_end() const {return tree.end();}; 00616 //@} 00617 00618 #endif 00619 00620 }; 00621 00622 class table3d_io_type : public io_tlate<table3d> { 00623 public: 00624 00625 table3d_io_type() : io_tlate<table3d>() {}; 00626 00627 virtual const char *type() { return "table3d"; } 00628 00629 virtual int input( cinput *ci, in_file_format *ins, 00630 table3d *at) { 00631 00632 bool size_set, xy_set; 00633 int nx, ny, nt, ncons, r1; 00634 double dtemp; 00635 std::string name, nmt; 00636 00637 // Constants 00638 ins->int_in(ncons,"const"); 00639 for(int i=0;i<ncons;i++) { 00640 ins->word_in(name); 00641 ins->double_in(dtemp); 00642 r1=at->add_constant(name,dtemp); 00643 if (r1!=0) { 00644 O2SCL_ERR_RET("Failed to add constant in table3d_io_type::input.", 00645 gsl_esanity); 00646 } 00647 } 00648 00649 ins->bool_in(size_set); 00650 if (size_set) { 00651 00652 // Grid 00653 ins->int_in(nx,"nx"); 00654 ins->int_in(ny,"ny"); 00655 ins->bool_in(xy_set); 00656 00657 if (xy_set) { 00658 std::string xname, yname; 00659 ins->word_in(xname); 00660 ins->word_in(yname); 00661 double *xv=new double[nx]; 00662 double *yv=new double[ny]; 00663 for(int i=0;i<nx;i++) ins->double_in(xv[i]); 00664 for(int i=0;i<ny;i++) ins->double_in(yv[i]); 00665 r1=at->set_xy(xname,((size_t)nx),xv,yname,((size_t)ny),yv); 00666 if (r1!=0) { 00667 O2SCL_ERR_RET("Failed to set grid in table3d_io_type::input.", 00668 gsl_esanity); 00669 } 00670 delete[] xv; 00671 delete[] yv; 00672 } 00673 00674 ins->int_in(nt,"nt"); 00675 if (nt>0) { 00676 00677 // Slice names 00678 std::string str="", tmp; 00679 for(int i=0;i<nt;i++) { 00680 ins->word_in(tmp); 00681 str+=tmp; 00682 str+=" "; 00683 } 00684 r1=at->line_of_names(str); 00685 if (r1!=0) { 00686 O2SCL_ERR_RET("Failed to add names in table3d_io_type::input().", 00687 gsl_esanity); 00688 } 00689 00690 // Data 00691 for(int i=0;i<nt;i++) { 00692 for(int j=0;j<nx;j++) { 00693 for(int k=0;k<ny;k++) { 00694 ins->double_in(dtemp); 00695 r1=at->set(j,k,i,dtemp); 00696 if (r1!=0) { 00697 O2SCL_ERR2_RET("Failed to set() in ", 00698 "table3d_io_type::input().",gsl_esanity); 00699 } 00700 } 00701 } 00702 } 00703 } 00704 } 00705 return 0; 00706 } 00707 00708 virtual int output(coutput *co, out_file_format *outs, 00709 table3d *at) { 00710 00711 // Constants 00712 outs->int_out(at->constants.size(),"const"); 00713 std::map<std::string,double>::iterator mit; 00714 for(mit=at->constants.begin();mit!=at->constants.end();mit++) { 00715 outs->word_out(mit->first); 00716 outs->double_out(mit->second); 00717 outs->end_line(); 00718 } 00719 00720 outs->bool_out(at->size_set); 00721 if (at->size_set) { 00722 00723 // Grid 00724 outs->int_out(at->numx,"nx"); 00725 outs->int_out(at->numy,"ny"); 00726 outs->bool_out(at->xy_set); 00727 if (at->xy_set) { 00728 outs->end_line(); 00729 outs->word_out(at->xname); 00730 outs->word_out(at->yname); 00731 for(size_t i=0;i<at->numx;i++) outs->double_out((at->xval)[i]); 00732 for(size_t i=0;i<at->numy;i++) outs->double_out((at->yval)[i]); 00733 } 00734 outs->end_line(); 00735 00736 outs->int_out(at->tree.size(),"nt"); 00737 if (at->tree.size()>0) { 00738 00739 // Slice names 00740 for(size_t i=0;i<at->tree.size();i++) { 00741 outs->word_out(at->get_slice_name(i)); 00742 } 00743 outs->end_line(); 00744 00745 // Data 00746 for(size_t i=0;i<at->tree.size();i++) { 00747 for(size_t j=0;j<at->numx;j++) { 00748 for(size_t k=0;k<at->numy;k++) { 00749 outs->double_out(at->get(j,k,i)); 00750 } 00751 } 00752 outs->end_line(); 00753 } 00754 } 00755 00756 } 00757 return 0; 00758 } 00759 00760 }; 00761 00762 #ifndef DOXYGENP 00763 } 00764 #endif 00765 00766 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page