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_TABLE_H 00024 #define O2SCL_TABLE_H 00025 00026 #include <iostream> 00027 #include <fstream> 00028 #include <string> 00029 #include <cmath> 00030 #include <sstream> 00031 #include <o2scl/misc.h> 00032 #include <o2scl/err_hnd.h> 00033 #include <o2scl/multi_funct.h> 00034 #include <o2scl/collection.h> 00035 #include <o2scl/search_vec.h> 00036 #include <o2scl/ovector_tlate.h> 00037 #include <o2scl/smart_interp.h> 00038 00039 #ifndef DOXYGENP 00040 namespace o2scl { 00041 #endif 00042 00043 /** 00044 \brief Data \table class 00045 00046 \b Summary \n 00047 00048 A class to contain and manipulate several equally-sized columns 00049 of data. The purpose of this class is to provide a structure 00050 which allows one to refer to the columns using a name 00051 represented by a string. Thus for a table object named \c t with 00052 3 columns (named "colx", "coly" and "colz") and three rows, one 00053 could do the following: 00054 \include table_doc1.cpp 00055 Note that the rows are numbered starting with 0 instead of 00056 starting with 1. 00057 To output all the rows of entire column, one can use 00058 \include table_doc2.cpp 00059 To output all the columns of an entire row (in the following 00060 example it is the second row), labeled by their column name, one 00061 can use: 00062 \include table_doc3.cpp 00063 00064 Methods are provided for interpolating columns, sorting 00065 columns, finding data points, and several other manipulations 00066 of the data. 00067 00068 \b Column \b size \n 00069 00070 The columns grow automatically (similar to the STL <vector>) 00071 in reponse to an attempt to call set() for a row that does not 00072 presently exist or in a call to line_of_data() when the table is 00073 already full. However, this forces memory rearrangments that are 00074 O(R*C). If the user has a good estimate of the number of rows 00075 beforehand, it is best to either specify this in the 00076 constructor, or in an explicit call to inc_maxlines(). 00077 00078 <B> Lookup, differentiation, integration, and interpolation </b> \n 00079 00080 Lookup, differentiation, integration, and interpolation are 00081 automatically implemented using splines from the class \ref 00082 smart_interp_vec. A caching mechanism is implemented so that 00083 successive interpolations, derivative evaluations or 00084 integrations over the same two columns are fast. 00085 00086 <B> Sorting </b>\n 00087 00088 The columns are automatically sorted by name for speed, the 00089 results can be accessed by table::get_sorted_name(i). Individual 00090 columns can be sorted (\ref sort_column() ), or the entire table 00091 can be sorted by one column (\ref sort_table() ). 00092 00093 <B> Allowable column names</b> \n 00094 00095 In general, column names may be of any form as long as they 00096 don't contain whitespace, e.g. \c 123".#@$%xy~ is a legitmate 00097 column name. The \o2x extension to this class named 00098 <tt>table_fp</tt>, however requires that the column name contain 00099 only letters, numbers, and underscores and also that the column 00100 name not begin with a digit. 00101 00102 \comment 00103 <B> User-owned columns </b> \n 00104 \endcomment 00105 00106 <B> Data representation </b> \n 00107 00108 Each individual column is just an ovector_view (or any 00109 descendant of an ovector_view) The columns can be referred to in 00110 one of two ways: 00111 - A numerical index from 0 to C-1 (where C is the number of 00112 columns). For example, data can be accessed through \ref 00113 table::get() and \ref table::set(size_t c, size_t r, 00114 double val), or the overloaded [] operator, table[c][r]. 00115 - A name of the column which is a string with no whitespace. 00116 For example, data can be accessed with table::get(string cname, 00117 int r) and table::set(string cname, int r, double val). 00118 00119 The columns are organized in a both a <map> and a <vector> 00120 structure so that finding a column by its index ( string 00121 table::get_column_name(int index), and double 00122 *table::get_column(int index) ) takes only constant time, and 00123 finding a column by its name ( int \ref lookup_column() and 00124 double * \ref table::get_column() ) is O(log(C)). Insertion of a 00125 column ( \ref new_column() ) is O(log(C)), but deletion ( \ref 00126 delete_column() ) is O(C). Adding a row of data can be either 00127 O(1) or O(C), but row insertion and deletion is slow, since the 00128 all of the columns must be shifted accordingly. 00129 00130 \comment 00131 Ownership of any column may be changed at any time, but care 00132 must be taken to ensure that memory allocation errors do not 00133 occur. These errors should not occur when no columns are 00134 owned by the user. 00135 \endcomment 00136 00137 Because of the structure, this class is not suitable for the 00138 matrix manipulation. The classes \ref omatrix and \ref umatrix 00139 are better used for that purpose. 00140 00141 <B> Thread-safety </b> \n 00142 00143 Generally, the member functions are thread-safe in the sense 00144 that one would expect: it is always permitted to have many 00145 threads accessing many tables, but care must be taken if many 00146 threads are accessing only one table. Simple get() and set() 00147 functions are thread-safe (unless a set() function forces memory 00148 rearrangement), while insertion and deletion operations are not. 00149 Only the <tt>const</tt> version of the interpolation routines 00150 are thread-safe 00151 00152 \b I/O \b and \b command-line \b manipulation \n 00153 00154 When data from an object of type \ref table is output to 00155 a file through the \ref collection class, the table 00156 can be manipulated on the command-line through 00157 the acol utility. 00158 00159 There is an example for the usage of this class given 00160 in <tt>examples/ex_table.cpp</tt>. 00161 00162 \future Rewrite the \ref table::create_array() and 00163 \ref table::insert_data() 00164 functions for generic vector type 00165 00166 \future Be more restrictive about allowable column names? 00167 00168 \future Re-implement user-owned columns, and handle automatic 00169 resizing appropriately. 00170 00171 \comment 00172 00173 10/16/07: This issue may be unimportant, as it might 00174 be better to just move to a template based approach with 00175 a user-specified vector type. The interpolation is now flexible 00176 enough to handle different types. Might check to ensure sorting 00177 works with other types. 00178 00179 10/9/08: Actually, the native vector 00180 types are very useful here, and I'm thinking now that the 00181 vector types should not be templated. If there is a user-owned 00182 column, then no lines should ever be added beyond the length 00183 of the user-owned column. For adding user-owned columns 00184 into a table which already contains data, it should fail 00185 if the user-owned column is smaller than nlines and succeed 00186 otherwise. If after adding a user-owned column maxlines is 00187 greater than the user-owned column size, then maxlines should 00188 be decreases accordingly. 00189 00190 1/30/08: User-owned columns have been removed for now, 00191 which avoids a lot of complications 00192 00193 \endcomment 00194 00195 \future Return the empty column in the operator[] functions 00196 as is done for the get_column() functions. 00197 00198 \future A "delete rows" method to delete a range of several rows 00199 00200 \future The present structure, \c 00201 std::map<std::string,col,string_comp> atree and \c 00202 std::vector<aiter> alist; could be replaced with \c 00203 std::vector<col> list and \c std::map<std::string,int> tree 00204 where the map just stores the index of the the column in the 00205 list 00206 */ 00207 class table { 00208 public: 00209 00210 /** \brief Create a new table with space for nlines<=cmaxlines. 00211 */ 00212 table(int cmaxlines=0); 00213 00214 virtual ~table(); 00215 00216 /// Copy constructor 00217 table(const table &t); 00218 00219 /// Copy constructor 00220 table &operator=(const table &t); 00221 00222 // -------------------------------------------------------- 00223 /** \name Basic get and set methods */ 00224 //@{ 00225 /** \brief Set row \c row of column named \c col to value \c val - 00226 O(log(C)). 00227 00228 This function adds the column \c col if it does not 00229 already exist and adds rows using inc_maxlines() and 00230 set_nlines() to create at least \c (row+1) rows if they do not 00231 already exist. 00232 */ 00233 int set(std::string col, size_t row, double val); 00234 00235 /** \brief Set row \c row of column number \c icol to value \c val - O(1). 00236 */ 00237 int set(size_t icol, size_t row, double val); 00238 00239 /** \brief Get value from row \c row of column named \c col - O(log(C)). 00240 */ 00241 double get(std::string col, size_t row) const; 00242 00243 /** \brief Get value from row \c row of column number \c icol - O(1). 00244 */ 00245 double get(size_t icol, size_t row) const; 00246 00247 /** \brief Return the number of columns 00248 */ 00249 size_t get_ncolumns() const {return atree.size();}; 00250 00251 /** \brief Return the number of lines 00252 */ 00253 size_t get_nlines() const {return nlines;}; 00254 00255 /** 00256 \brief Set the number of lines 00257 00258 This function is stingy about increasing the table memory space 00259 and will only increase it enough to fit \c il lines, which 00260 is useful if you have columns not owned by the table. 00261 */ 00262 int set_nlines(size_t il); 00263 00264 /** 00265 \brief Set the number of lines, increasing the size more 00266 agressively 00267 00268 This function is like set_nlines(), but doubles the maximum 00269 column size if an increase in the maximum size is required 00270 instead of simply making enough room for the current number of 00271 lines. This function is used internally by \ref set() to 00272 ensure that the cost of setting lines in sequence is linear 00273 and not quadratic. 00274 */ 00275 int set_nlines_auto(size_t il); 00276 00277 /** \brief Return the maximum number of lines 00278 */ 00279 int get_maxlines() {return maxlines;}; 00280 00281 /** \brief Returns a reference to the column named \c col - O(log(C)) 00282 */ 00283 ovector_base &get_column(std::string col); 00284 00285 /** \brief Returns a reference to the column named \c col - O(log(C)) 00286 */ 00287 const ovector_base &get_column(std::string col) const; 00288 00289 /** 00290 \brief Returns the column of index \c icol - O(1) (const version) 00291 00292 This does not do any sort of bounds checking and is quite 00293 fast. 00294 00295 Note that several of the methods require reallocation of 00296 memory and refereces previously returned by this function will 00297 be incorrect. 00298 */ 00299 const ovector_base &operator[] (size_t icol) const { 00300 return (*alist[icol]->second.dat); 00301 } 00302 00303 /** 00304 \brief Returns the column of index \c icol - O(1). 00305 00306 This does not do any sort of bounds checking and is 00307 quite fast. 00308 00309 Note that several of the methods require reallocation of 00310 memory and refereces previously returned by this function will 00311 be incorrect. 00312 */ 00313 ovector_base &operator[] (size_t icol) { 00314 return (*alist[icol]->second.dat); 00315 } 00316 00317 /** 00318 \brief Returns the column named \c scol - O(log(C)) (const version) 00319 00320 No error checking is performed. 00321 00322 Note that several of the methods require reallocation of 00323 memory and refereces previously returned by this function will 00324 be incorrect. 00325 */ 00326 const ovector_base &operator[](std::string scol) const { 00327 aciter it=atree.find(scol); 00328 return *(it->second.dat); 00329 } 00330 00331 /** 00332 \brief Returns the column named \c scol - O(log(C)) 00333 00334 No error checking is performed. 00335 00336 Note that several of the methods require reallocation of 00337 memory and refereces previously returned by this function will 00338 be incorrect. 00339 */ 00340 ovector_base &operator[](std::string scol) { 00341 aiter it=atree.find(scol); 00342 return *(it->second.dat); 00343 } 00344 00345 /** \brief Returns a copy of the row with value \c val 00346 in column \c col - O(R*C) */ 00347 int get_row(std::string col, double val, ovector &row) const; 00348 00349 /** \brief Returns a copy of row number \c irow - O(C) 00350 */ 00351 int get_row(size_t irow, ovector &row) const; 00352 //@} 00353 00354 // -------------------------------------------------------- 00355 /** \name Column manipulation */ 00356 //@{ 00357 00358 /** \brief Returns the name of column \c col - O(1). 00359 */ 00360 std::string get_column_name(size_t col) const; 00361 00362 /** \brief Returns the name of column \c col in sorted order - O(1). 00363 */ 00364 std::string get_sorted_name(size_t col); 00365 00366 /** \brief Add a new column owned by the table - O(log(C)). 00367 */ 00368 int new_column(std::string name); 00369 00370 #ifdef O2SCL_NEVER_DEFINED 00371 /** \brief Add a new column owned by the user - O(log(C)). 00372 00373 This function does not modify the number of lines of data in 00374 the table. 00375 00376 \todo We've got to figure out what to do if ldat is too small. 00377 If it's smaller than nlines, obviously we should just 00378 fail, but what if it's size is between nlines and maxlines? 00379 */ 00380 int new_column(std::string name, ovector_view *ldat); 00381 #endif 00382 00383 /** \brief Return true if \c scol is a column in the current table 00384 00385 This function does not call the error handler if the 00386 column is not found, but just silently returns false. 00387 */ 00388 bool is_column(std::string scol); 00389 00390 /** 00391 \brief Find the index for column named \c name - O(log(C)). 00392 00393 If the column is not present, this does not call the error 00394 handler, but quietly sets \c ix to zero and returns \ref 00395 gsl_enotfound. 00396 */ 00397 int lookup_column(std::string name, int &ix) const; 00398 00399 #ifdef O2SCL_NEVER_DEFINED 00400 /** 00401 \brief Rename column named \c olds to \c news - O(C). 00402 00403 This is slow since we have to delete the column and re-insert 00404 it. This process in turn mangles all of the 00405 iterators in the list. 00406 */ 00407 int rename_column(std::string olds, std::string news); 00408 #endif 00409 00410 /** \brief Make a new column named \c dest equal to \c src - O(log(C)*R). 00411 */ 00412 int copy_column(std::string src, std::string dest); 00413 00414 /// Create (using \c new) a generic array from column \c col 00415 double *create_array(std::string col) const; 00416 00417 /** \brief Initialize all values of column named \c scol to \c val - 00418 O(log(C)*R). 00419 00420 Note that this does not initialize elements beyond 00421 nlines so that if the number of rows is increased afterwards, the 00422 new rows will have uninitialized values. 00423 */ 00424 int init_column(std::string scol, double val); 00425 00426 #ifdef O2SCL_NEVER_DEFINED 00427 /** 00428 \brief Modify ownership - O(log(C)). 00429 00430 \warning columns allocated using malloc() should never be 00431 owned by the table object since it uses delete instead of 00432 free(). 00433 */ 00434 int ch_owner(std::string name, bool ow); 00435 #endif 00436 00437 /** 00438 \brief Get a gsl_vector from column \c name - O(log(C)). 00439 */ 00440 const gsl_vector *get_gsl_vector(std::string name) const; 00441 00442 /** 00443 \brief Insert a column from a separate table, interpolating 00444 it into a new column 00445 00446 Given a pair of columns ( \c src_index, \c src_col ) in a 00447 separate table (\c source), this creates a new column in the 00448 present table named \c src_col which interpolates \c loc_index 00449 into \c src_index. The interpolation objects from the \c 00450 source table will be used. If there is already a column in the 00451 present table named \c src_col, then this will fail. 00452 00453 If there is an error in the interpolation for any particular 00454 row, then the value of \c src_col in that row will be set to 00455 zero. 00456 */ 00457 int add_col_from_table(std::string loc_index, table &source, 00458 std::string src_index, std::string src_col, 00459 std::string dest_col=""); 00460 //@} 00461 00462 // -------------------------------------------------------- 00463 /** \name Row maninpulation and data input */ 00464 //@{ 00465 00466 /** \brief Insert a row before row \c n 00467 00468 Acceptable values for \c n are between 0 and 00469 <tt>get_nlines()</tt> inclusive, with the maximum value 00470 denoting the addition of a row after the last row presently in 00471 the table. 00472 */ 00473 int new_row(size_t n); 00474 00475 /** \brief Copy the data in row \c src to row \c dest 00476 */ 00477 int copy_row(size_t src, size_t dest); 00478 00479 /** \brief Insert a row of data before row \c n 00480 */ 00481 int insert_data(size_t n, size_t nv, double *v); 00482 00483 /** \brief Insert a row of data before row \c n 00484 */ 00485 int insert_data(size_t n, size_t nv, double **v); 00486 00487 /** 00488 \brief Read a new set of names from \c newheads 00489 */ 00490 int line_of_names(std::string newheads); 00491 00492 /** \brief Read a line of data from an array 00493 */ 00494 template<class vec_t> int line_of_data(size_t nv, const vec_t &v) { 00495 if (maxlines==0) inc_maxlines(5); 00496 if (nlines>=maxlines) inc_maxlines(maxlines); 00497 00498 if (intp_set) { 00499 intp_set=false; 00500 delete si; 00501 } 00502 00503 if (nlines<maxlines && nv<=(atree.size())) { 00504 00505 for(size_t i=0;i<nv;i++) { 00506 (*this)[i][nlines]=v[i]; 00507 } 00508 nlines++; 00509 00510 return 0; 00511 } 00512 00513 O2SCL_ERR("Not enough lines or columns in line_of_data().",gsl_einval); 00514 return gsl_einval; 00515 } 00516 //@} 00517 00518 // -------------------------------------------------------- 00519 /** \name Lookup and search methods */ 00520 //@{ 00521 00522 /** 00523 \brief Look for a value in an ordered column 00524 00525 O(log(C)*log(R)) 00526 00527 This uses the function search_vec::ordered_lookup(), which 00528 offers caching and assumes the vector is monotonic. If you 00529 don't have monotonic data, you can still use the 00530 table::lookup() function, which is more general. 00531 */ 00532 size_t ordered_lookup(std::string col, double val); 00533 00534 /// Exhaustively search column \c col for the value \c val - O(log(C)*R). 00535 size_t lookup(std::string col, double val) const; 00536 00537 /// Search column \c col for the value \c val and return value in \c col2 00538 double lookup_val(std::string col, double val, std::string col2) const; 00539 00540 /// Exhaustively search column \c col for the value \c val - O(log(C)*R). 00541 size_t lookup(int col, double val) const; 00542 00543 /** \brief Exhaustively search column \c col for many occurences 00544 of \c val - O(log(C)*R). 00545 */ 00546 size_t mlookup(std::string col, double val, std::vector<double> &results, 00547 double threshold=0.0) const; 00548 //@} 00549 00550 // -------------------------------------------------------- 00551 /** \name Interpolation, differentiation, and integration, max, and min */ 00552 //@{ 00553 00554 /// Set the base interpolation objects 00555 int set_interp(base_interp_mgr<ovector_const_view> &bi1, 00556 base_interp_mgr<ovector_const_subvector> &bi2) { 00557 bim1=&bi1; 00558 bim2=&bi2; 00559 return 0; 00560 } 00561 00562 /** 00563 \brief Interpolate \c x0 from \c sx into \c sy 00564 00565 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00566 the relevant columns are not well ordered. 00567 */ 00568 double interp(std::string sx, double x0, std::string sy); 00569 00570 /** 00571 \brief Interpolate \c x0 from \c sx into \c sy 00572 00573 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00574 the relevant columns are not well ordered. 00575 */ 00576 double interp_const(std::string sx, double x0, std::string sy) const; 00577 00578 /** 00579 \brief Interpolate \c x0 from \c ix into \c iy 00580 00581 O(log(R)) but can be as bad as O(R) if 00582 the relevant columns are not well ordered. 00583 */ 00584 double interp(size_t ix, double x0, size_t iy); 00585 00586 /** 00587 \brief Interpolate \c x0 from \c ix into \c iy 00588 00589 O(log(R)) but can be as bad as O(R) if 00590 the relevant columns are not well ordered. 00591 */ 00592 double interp_const(size_t ix, double x0, size_t iy) const; 00593 00594 /** \brief Make a new column \c yp which is the derivative y'(x) - 00595 O(log(C)*R). 00596 */ 00597 int deriv(std::string x, std::string y, std::string yp); 00598 00599 /** 00600 \brief The first derivative of the function sy(sx) at sx=x0. 00601 00602 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00603 the relevant columns are not well ordered. 00604 */ 00605 double deriv(std::string sx, double x0, std::string sy); 00606 00607 /** 00608 \brief The first derivative of the function sy(sx) at sx=x0. 00609 00610 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00611 the relevant columns are not well ordered. 00612 */ 00613 double deriv_const(std::string sx, double x0, std::string sy) const; 00614 00615 /** 00616 \brief The first derivative of the function iy(ix) at ix=x0. 00617 00618 O(log(R)) but can be as bad as O(R) if 00619 the relevant columns are not well ordered. 00620 */ 00621 double deriv(size_t ix, double x0, size_t iy); 00622 00623 /** 00624 \brief The first derivative of the function iy(ix) at ix=x0. 00625 00626 O(log(R)) but can be as bad as O(R) if 00627 the relevant columns are not well ordered. 00628 */ 00629 double deriv_const(size_t ix, double x0, size_t iy) const; 00630 00631 /** 00632 \brief Make a new column \c yp which is 00633 \f$ y^{\prime \prime}(x) \f$ - O(log(C)*R). 00634 */ 00635 int deriv2(std::string x, std::string y, std::string yp); 00636 00637 /** 00638 \brief The second derivative of the function sy(sx) at sx=x0. 00639 00640 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00641 the relevant columns are not well ordered. 00642 */ 00643 double deriv2(std::string sx, double x0, std::string sy); 00644 00645 /** 00646 \brief The second derivative of the function sy(sx) at sx=x0. 00647 00648 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00649 the relevant columns are not well ordered. 00650 */ 00651 double deriv2_const(std::string sx, double x0, std::string sy) const; 00652 00653 /** 00654 \brief The second derivative of the function iy(ix) at ix=x0. 00655 00656 O(log(R)) but can be as bad as O(R) if 00657 the relevant columns are not well ordered. 00658 */ 00659 double deriv2(size_t ix, double x0, size_t iy); 00660 00661 /** 00662 \brief The second derivative of the function iy(ix) at ix=x0. 00663 00664 O(log(R)) but can be as bad as O(R) if 00665 the relevant columns are not well ordered. 00666 */ 00667 double deriv2_const(size_t ix, double x0, size_t iy) const; 00668 00669 /** 00670 \brief The integral of the function sy(sx) from sx=x1 to sx=x2. 00671 00672 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00673 the relevant columns are not well ordered. 00674 */ 00675 double integ(std::string sx, double x1, double x2, std::string sy); 00676 00677 /** 00678 \brief The integral of the function sy(sx) from sx=x1 to sx=x2. 00679 00680 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00681 the relevant columns are not well ordered. 00682 */ 00683 double integ_const(std::string sx, double x1, double x2, 00684 std::string sy) const; 00685 00686 /** 00687 \brief The integral of the function iy(ix) from ix=x1 to ix=x2. 00688 00689 O(log(R)) but can be as bad as O(R) if 00690 the relevant columns are not well ordered. 00691 */ 00692 double integ(size_t ix, double x1, double x2, size_t iy); 00693 00694 /** 00695 \brief The integral of the function iy(ix) from ix=x1 to ix=x2. 00696 00697 O(log(R)) but can be as bad as O(R) if 00698 the relevant columns are not well ordered. 00699 */ 00700 double integ_const(size_t ix, double x1, double x2, size_t iy) const; 00701 00702 /** 00703 \brief The integral of the function iy(ix) 00704 00705 O(log(R)) but can be as bad as O(R) if the relevant columns 00706 are not well ordered. 00707 */ 00708 int integ(std::string x, std::string y, std::string ynew); 00709 00710 /** \brief Return column maximum. Makes no assumptions about 00711 ordering - O(R). 00712 */ 00713 double max(std::string col) const; 00714 00715 /** \brief Return column minimum. Makes no assumptions about 00716 ordering - O(R). 00717 */ 00718 double min(std::string col) const; 00719 //@} 00720 00721 // -------------------------------------------------------- 00722 /** \name Subtable method */ 00723 //@{ 00724 00725 /** 00726 \brief Make a subtable 00727 00728 Uses the columns specified in \c list from the row \c top 00729 to the row of index \c bottom to generate a new table 00730 which is a copy of part of the original. 00731 00732 \comment 00733 The 'linked' variable was taken out since we're removing 00734 user-owned columns for now 00735 00736 If \c linked is false 00737 the the data will be independent from the original table. 00738 \endcomment 00739 */ 00740 table *subtable(std::string list, size_t top, size_t bottom) const; 00741 //@} 00742 00743 // -------------------------------------------------------- 00744 /** \name Add space */ 00745 //@{ 00746 00747 /** \brief Manually increase the maximum number of lines 00748 */ 00749 int inc_maxlines(size_t llines); 00750 //@} 00751 00752 // -------------------------------------------------------- 00753 /** \name Delete methods */ 00754 //@{ 00755 00756 /** \brief Delete column named \c scol - O(C). 00757 00758 This is slow because the iterators in \ref alist are mangled 00759 and we have to call \ref reset_list() to get them back. 00760 */ 00761 virtual int delete_column(std::string scol); 00762 00763 /** \brief Delete the row with the entry closest to 00764 the value \c val in column \c scol - O(R*C) 00765 */ 00766 int delete_row(std::string scol, double val); 00767 00768 /** \brief Delete the row of index \c irow - O(R*C) 00769 */ 00770 int delete_row(size_t irow); 00771 //@} 00772 00773 // -------------------------------------------------------- 00774 /** \name Clear methods */ 00775 //@{ 00776 00777 /** \brief Zero the data entries but keep the column names 00778 and nlines fixed 00779 */ 00780 void zero_table(); 00781 00782 /** \brief Clear the table and the column names 00783 */ 00784 void clear_table(); 00785 00786 /** \brief Remove all of the data by setting the number 00787 of lines to zero 00788 00789 This leaves the column names intact and does not remove 00790 the constants. 00791 */ 00792 void clear_data() { 00793 nlines=0; 00794 if (intp_set==true) { 00795 delete si; 00796 intp_set=false; 00797 } 00798 return; 00799 }; 00800 //@} 00801 00802 // -------------------------------------------------------- 00803 /** \name Sorting methods */ 00804 //@{ 00805 00806 /** \brief Sort the entire table by the column \c scol 00807 */ 00808 int sort_table(std::string scol); 00809 00810 /** \brief Individually sort the column \c scol 00811 */ 00812 int sort_column(std::string scol); 00813 //@} 00814 00815 // -------------------------------------------------------- 00816 /** \name Summary method */ 00817 //@{ 00818 /** \brief Output a summary of the information stored 00819 00820 Outputs the number of constants, the number of columns, 00821 a list of the column names, and the number of lines of 00822 data. 00823 */ 00824 virtual int summary(std::ostream *out, int ncol=79) const; 00825 //@} 00826 00827 /// \name Constant manipulation 00828 //@{ 00829 /// Add a constant, or if the constant already exists, change its value 00830 virtual int add_constant(std::string name, double val) { 00831 if (constants.find(name)!=constants.end()) { 00832 constants.find(name)->second=val; 00833 return 0; 00834 } 00835 constants.insert(make_pair(name,val)); 00836 return 0; 00837 } 00838 00839 /// Add a constant 00840 virtual int set_constant(std::string name, double val, 00841 bool err_on_notfound=true) { 00842 if (constants.find(name)!=constants.end()) { 00843 constants.find(name)->second=val; 00844 return 0; 00845 } 00846 if (err_on_notfound) { 00847 O2SCL_ERR_RET("No constant with specified name in set_constant().", 00848 gsl_einval); 00849 } 00850 return gsl_enotfound; 00851 } 00852 00853 /// Get a constant 00854 virtual double get_constant(std::string name) const { 00855 return constants.find(name)->second; 00856 } 00857 00858 /// Get the number of constants 00859 virtual size_t get_nconsts() const { 00860 return constants.size(); 00861 } 00862 00863 /// Get a constant by index 00864 virtual int get_constant(size_t ix, std::string &name, double &val) const { 00865 if (ix<constants.size()) { 00866 std::map<std::string,double>::const_iterator cit=constants.begin(); 00867 for(size_t i=0;i<ix;i++) cit++; 00868 name=cit->first; 00869 val=cit->second; 00870 return 0; 00871 } 00872 O2SCL_ERR_RET("Index too large in table::get_constant().",gsl_eindex); 00873 } 00874 00875 /// Remove a constant 00876 virtual int remove_constant(std::string name) { 00877 constants.erase(name); 00878 return 0; 00879 } 00880 //@} 00881 00882 /// \name Miscellaneous methods 00883 //@{ 00884 /// Clear the current table and read from a generic data file 00885 int read_generic(std::istream &fin); 00886 00887 /** \brief Return 0 if the tree and list are properly synchronized 00888 */ 00889 int check_synchro() const; 00890 00891 /** \brief Get ownership - O(log(C)). 00892 */ 00893 bool get_owner(std::string name) const; 00894 00895 //@} 00896 00897 /// Default interpolation manager 00898 def_interp_mgr<ovector_const_view,cspline_interp> dim1; 00899 00900 /// Default interpolation manager 00901 def_interp_mgr<ovector_const_subvector,cspline_interp> dim2; 00902 00903 /// Return the type, \c "table". 00904 virtual const char *type() { return "table"; } 00905 00906 /// True if the interpolation type has been set 00907 bool intp_set; 00908 00909 protected: 00910 00911 #ifndef DOXYGEN_INTERNAL 00912 00913 friend class io_tlate<table>; 00914 00915 /** \brief The list of constants 00916 */ 00917 std::map<std::string,double> constants; 00918 00919 /** \brief Set the elements of alist with the appropriate 00920 iterators from atree - O(C). 00921 00922 Generally, the end-user shouldn't need this method. It is 00923 only used in delete_column() to rearrange the list when 00924 a column is deleted from the tree. 00925 */ 00926 int reset_list(); 00927 00928 /** 00929 \brief Ensure a variable name does not match a function or contain 00930 non-alphanumeric characters 00931 */ 00932 int make_fp_varname(std::string &s); 00933 00934 /// Make sure a name is unique 00935 int make_unique_name(std::string &col, std::vector<std::string> &cnames); 00936 00937 /// Column structure for \ref table [protected] 00938 typedef struct col_s { 00939 /// Pointer to column 00940 ovector_base *dat; 00941 /// Owner of column 00942 bool owner; 00943 /// Column index 00944 int index; 00945 } col; 00946 00947 /// \name Iterator types 00948 //@{ 00949 typedef std::map<std::string,col,string_comp>::iterator aiter; 00950 typedef std::map<std::string,col,string_comp>::const_iterator aciter; 00951 typedef std::vector<aiter>::iterator aviter; 00952 //@} 00953 00954 /// \name Actual data 00955 //@{ 00956 /// The size of allocated memory 00957 size_t maxlines; 00958 /// The size of presently used memory 00959 size_t nlines; 00960 /// The tree of columns 00961 std::map<std::string,col,string_comp> atree; 00962 /// The list of tree iterators 00963 std::vector<aiter> alist; 00964 //@} 00965 00966 /// \name Column manipulation methods 00967 //@{ 00968 /// Return the iterator for a column 00969 aiter get_iterator(std::string lname); 00970 /// Return the column structure for a column 00971 col *get_col_struct(std::string lname); 00972 /// Return the beginning of the column tree 00973 aiter begin() {return atree.begin();}; 00974 /// Return the end of the column tree 00975 aiter end() {return atree.end();}; 00976 //@} 00977 00978 /// An empty vector for get_column() 00979 ovector empty_col; 00980 00981 /// The sorting function 00982 static int sortd_comp(const void *a, const void *b); 00983 00984 /// A structure for sorting in \ref table [protected] 00985 typedef struct sortd_s { 00986 /// Value to sort 00987 double val; 00988 /// Sorted index 00989 int indx; 00990 } sortd; 00991 00992 /// \name Interpolation 00993 //@{ 00994 /// The interpolation object 00995 sm_interp_vec *si; 00996 00997 /// A pointer to the interpolation manager 00998 base_interp_mgr<ovector_const_view> *bim1; 00999 /// A pointer to the subvector interpolation manager 01000 base_interp_mgr<ovector_const_subvector> *bim2; 01001 01002 /// The vector-searching object 01003 search_vec<ovector> se; 01004 01005 /// The last x-column interpolated 01006 std::string intp_colx; 01007 01008 /// The last y-column interpolated 01009 std::string intp_coly; 01010 01011 //@} 01012 01013 #endif 01014 01015 }; 01016 01017 /// Input specialization 01018 template<> int io_tlate<table>::input 01019 (cinput *co, o2scl::in_file_format *ins, table *ta); 01020 /// Output specialization 01021 template<> int io_tlate<table>::output 01022 (coutput *co, o2scl::out_file_format *outs, 01023 table *at); 01024 /// \fn Type specialization 01025 template<> const char *io_tlate<table>::type(); 01026 01027 typedef io_tlate<table> table_io_type; 01028 01029 #ifndef DOXYGENP 01030 } 01031 #endif 01032 01033 #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