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 // -------------------------------------------------------- 00217 /** \name Basic get and set methods */ 00218 //@{ 00219 /** \brief Set row \c row of column named \c col to value \c val - 00220 O(log(C)). 00221 00222 This function adds the column \c col if it does not 00223 already exist and adds rows using inc_maxlines() and 00224 set_nlines() to create at least \c (row+1) rows if they do not 00225 already exist. 00226 */ 00227 int set(std::string col, size_t row, double val); 00228 00229 /** \brief Set row \c row of column number \c icol to value \c val - O(1). 00230 */ 00231 int set(size_t icol, size_t row, double val); 00232 00233 /** \brief Get value from row \c row of column named \c col - O(log(C)). 00234 */ 00235 double get(std::string col, size_t row) const; 00236 00237 /** \brief Get value from row \c row of column number \c icol - O(1). 00238 */ 00239 double get(size_t icol, size_t row) const; 00240 00241 /** \brief Return the number of columns 00242 */ 00243 size_t get_ncolumns() const {return atree.size();}; 00244 00245 /** \brief Return the number of lines 00246 */ 00247 size_t get_nlines() const {return nlines;}; 00248 00249 /** 00250 \brief Set the number of lines 00251 00252 This function is stingy about increasing the table memory space 00253 and will only increase it enough to fit \c il lines, which 00254 is useful if you have columns not owned by the table. 00255 */ 00256 int set_nlines(size_t il); 00257 00258 /** 00259 \brief Set the number of lines, increasing the size more 00260 agressively 00261 00262 This function is like set_nlines(), but doubles the maximum 00263 column size if an increase in the maximum size is required 00264 instead of simply making enough room for the current number of 00265 lines. This function is used internally by \ref set() to 00266 ensure that the cost of setting lines in sequence is linear 00267 and not quadratic. 00268 */ 00269 int set_nlines_auto(size_t il); 00270 00271 /** \brief Return the maximum number of lines 00272 */ 00273 int get_maxlines() {return maxlines;}; 00274 00275 /** \brief Returns a pointer to the column named \c col - O(log(C)) 00276 */ 00277 ovector_base &get_column(std::string col); 00278 00279 /** \brief Returns a pointer to the column named \c col - O(log(C)) 00280 */ 00281 const ovector_base &get_column(std::string col) const; 00282 00283 /** 00284 \brief Returns the column of index \c icol - O(1) (const version) 00285 00286 This does not do any sort of bounds checking and is quite 00287 fast. 00288 00289 Note that several of the methods require reallocation of 00290 memory and refereces previously returned by this function will 00291 be incorrect. 00292 */ 00293 const ovector_base &operator[] (size_t icol) const { 00294 return (*alist[icol]->second.dat); 00295 } 00296 00297 /** 00298 \brief Returns the column of index \c icol - O(1). 00299 00300 This does not do any sort of bounds checking and is 00301 quite fast. 00302 00303 Note that several of the methods require reallocation of 00304 memory and refereces previously returned by this function will 00305 be incorrect. 00306 */ 00307 ovector_base &operator[] (size_t icol) { 00308 return (*alist[icol]->second.dat); 00309 } 00310 00311 /** 00312 \brief Returns the column named \c scol - O(log(C)) (const version) 00313 00314 No error checking is performed. 00315 00316 Note that several of the methods require reallocation of 00317 memory and refereces previously returned by this function will 00318 be incorrect. 00319 */ 00320 const ovector_base &operator[](std::string scol) const { 00321 aciter it=atree.find(scol); 00322 return *(it->second.dat); 00323 } 00324 00325 /** 00326 \brief Returns the column named \c scol - O(log(C)) 00327 00328 No error checking is performed. 00329 00330 Note that several of the methods require reallocation of 00331 memory and refereces previously returned by this function will 00332 be incorrect. 00333 */ 00334 ovector_base &operator[](std::string scol) { 00335 aiter it=atree.find(scol); 00336 return *(it->second.dat); 00337 } 00338 00339 /** \brief Returns a copy of the row with value \c val 00340 in column \c col - O(R*C) */ 00341 int get_row(std::string col, double val, ovector &row) const; 00342 00343 /** \brief Returns a copy of row number \c irow - O(C) 00344 */ 00345 int get_row(size_t irow, ovector &row) const; 00346 //@} 00347 00348 // -------------------------------------------------------- 00349 /** \name Column manipulation */ 00350 //@{ 00351 00352 /** \brief Returns the name of column \c col - O(1). 00353 */ 00354 std::string get_column_name(size_t col) const; 00355 00356 /** \brief Returns the name of column \c col in sorted order - O(1). 00357 */ 00358 std::string get_sorted_name(size_t col); 00359 00360 /** \brief Add a new column owned by the table - O(log(C)). 00361 */ 00362 int new_column(std::string name); 00363 00364 #ifdef O2SCL_NEVER_DEFINED 00365 /** \brief Add a new column owned by the user - O(log(C)). 00366 00367 This function does not modify the number of lines of data in 00368 the table. 00369 00370 \todo We've got to figure out what to do if ldat is too small. 00371 If it's smaller than nlines, obviously we should just 00372 fail, but what if it's size is between nlines and maxlines? 00373 */ 00374 int new_column(std::string name, ovector_view *ldat); 00375 #endif 00376 00377 /** 00378 \brief Find the index for column named \c name - O(log(C)). 00379 00380 If the column is not present, this does not call the error 00381 handler, but quietly sets \c ix to zero and returns \ref 00382 gsl_enotfound. 00383 */ 00384 int lookup_column(std::string name, int &ix) const; 00385 00386 #ifdef O2SCL_NEVER_DEFINED 00387 /** 00388 \brief Rename column named \c olds to \c news - O(C). 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 00392 iterators in the list. 00393 */ 00394 int rename_column(std::string olds, std::string news); 00395 #endif 00396 00397 /** \brief Make a new column named \c dest equal to \c src - O(log(C)*R). 00398 */ 00399 int copy_column(std::string src, std::string dest); 00400 00401 /// Create (using \c new) a generic array from column \c col 00402 double *create_array(std::string col) const; 00403 00404 /** \brief Initialize all values of column named \c scol to \c val - 00405 O(log(C)*R). 00406 00407 Note that this does not initialize elements beyond 00408 nlines so that if the number of rows is increased afterwards, the 00409 new rows will have uninitialized values. 00410 */ 00411 int init_column(std::string scol, double val); 00412 00413 #ifdef O2SCL_NEVER_DEFINED 00414 /** 00415 \brief Modify ownership - O(log(C)). 00416 00417 \warning columns allocated using malloc() should never be 00418 owned by the table object since it uses delete instead of 00419 free(). 00420 */ 00421 int ch_owner(std::string name, bool ow); 00422 #endif 00423 00424 /** 00425 \brief Get a gsl_vector from column \c name - O(log(C)). 00426 */ 00427 const gsl_vector *get_gsl_vector(std::string name) const; 00428 00429 /** 00430 \brief Insert a column from a separate table, interpolating 00431 it into a new column 00432 00433 Given a pair of columns ( \c src_index, \c src_col ) in a 00434 separate table (\c source), this creates a new column in the 00435 present table named \c src_col which interpolates \c loc_index 00436 into \c src_index. The interpolation objects from the \c 00437 source table will be used. If there is already a column in the 00438 present table named \c src_col, then this will fail. 00439 00440 If there is an error in the interpolation for any particular 00441 row, then the value of \c src_col in that row will be set to 00442 zero. 00443 */ 00444 int add_col_from_table(std::string loc_index, table &source, 00445 std::string src_index, std::string src_col, 00446 std::string dest_col=""); 00447 //@} 00448 00449 // -------------------------------------------------------- 00450 /** \name Row maninpulation and data input */ 00451 //@{ 00452 00453 /** \brief Insert a row before row \c n 00454 00455 Acceptable values for \c n are between 0 and 00456 <tt>get_nlines()</tt> inclusive, with the maximum value 00457 denoting the addition of a row after the last row presently in 00458 the table. 00459 */ 00460 int new_row(size_t n); 00461 00462 /** \brief Copy the data in row \c src to row \c dest 00463 */ 00464 int copy_row(size_t src, size_t dest); 00465 00466 /** \brief Insert a row of data before row \c n 00467 */ 00468 int insert_data(size_t n, size_t nv, double *v); 00469 00470 /** \brief Insert a row of data before row \c n 00471 */ 00472 int insert_data(size_t n, size_t nv, double **v); 00473 00474 /** 00475 \brief Read a new set of names from \c newheads 00476 */ 00477 int line_of_names(std::string newheads); 00478 00479 /** \brief Read a line of data from an array 00480 */ 00481 template<class vec_t> int line_of_data(size_t nv, const vec_t &v) { 00482 if (maxlines==0) inc_maxlines(5); 00483 if (nlines>=maxlines) inc_maxlines(maxlines); 00484 00485 if (intp_set) { 00486 intp_set=false; 00487 delete si; 00488 } 00489 00490 if (nlines<maxlines && nv<=(atree.size())) { 00491 00492 for(size_t i=0;i<nv;i++) { 00493 (*this)[i][nlines]=v[i]; 00494 } 00495 nlines++; 00496 00497 return 0; 00498 } 00499 00500 O2SCL_ERR("Not enough lines or columns in line_of_data().",gsl_einval); 00501 return gsl_einval; 00502 } 00503 //@} 00504 00505 // -------------------------------------------------------- 00506 /** \name Lookup and search methods */ 00507 //@{ 00508 00509 /** 00510 \brief Look for a value in an ordered column 00511 00512 O(log(C)*log(R)) 00513 00514 This uses the function search_vec::ordered_lookup(), which 00515 offers caching and assumes the vector is monotonic. If you 00516 don't have monotonic data, you can still use the 00517 table::lookup() function, which is more general. 00518 */ 00519 size_t ordered_lookup(std::string col, double val); 00520 00521 /// Exhaustively search column \c col for the value \c val - O(log(C)*R). 00522 size_t lookup(std::string col, double val) const; 00523 00524 /// Search column \c col for the value \c val and return value in \c col2 00525 double lookup_val(std::string col, double val, std::string col2) const; 00526 00527 /// Exhaustively search column \c col for the value \c val - O(log(C)*R). 00528 size_t lookup(int col, double val) const; 00529 00530 /** \brief Exhaustively search column \c col for many occurences 00531 of \c val - O(log(C)*R). 00532 */ 00533 size_t mlookup(std::string col, double val, std::vector<double> &results, 00534 double threshold=0.0) const; 00535 //@} 00536 00537 // -------------------------------------------------------- 00538 /** \name Interpolation, differentiation, and integration, max, and min */ 00539 //@{ 00540 00541 /// Set the base interpolation objects 00542 int set_interp(base_interp_mgr<ovector_const_view> &bi1, 00543 base_interp_mgr<ovector_const_subvector> &bi2) { 00544 bim1=&bi1; 00545 bim2=&bi2; 00546 return 0; 00547 } 00548 00549 /** 00550 \brief Interpolate \c x0 from \c sx into \c sy 00551 00552 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00553 the relevant columns are not well ordered. 00554 */ 00555 double interp(std::string sx, double x0, std::string sy); 00556 00557 /** 00558 \brief Interpolate \c x0 from \c sx into \c sy 00559 00560 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00561 the relevant columns are not well ordered. 00562 */ 00563 double interp_const(std::string sx, double x0, std::string sy) const; 00564 00565 /** 00566 \brief Interpolate \c x0 from \c ix into \c iy 00567 00568 O(log(R)) but can be as bad as O(R) if 00569 the relevant columns are not well ordered. 00570 */ 00571 double interp(size_t ix, double x0, size_t iy); 00572 00573 /** 00574 \brief Interpolate \c x0 from \c ix into \c iy 00575 00576 O(log(R)) but can be as bad as O(R) if 00577 the relevant columns are not well ordered. 00578 */ 00579 double interp_const(size_t ix, double x0, size_t iy) const; 00580 00581 /** \brief Make a new column \c yp which is the derivative y'(x) - 00582 O(log(C)*R). 00583 */ 00584 int deriv(std::string x, std::string y, std::string yp); 00585 00586 /** 00587 \brief The first derivative of the function sy(sx) at sx=x0. 00588 00589 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00590 the relevant columns are not well ordered. 00591 */ 00592 double deriv(std::string sx, double x0, std::string sy); 00593 00594 /** 00595 \brief The first derivative of the function sy(sx) at sx=x0. 00596 00597 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00598 the relevant columns are not well ordered. 00599 */ 00600 double deriv_const(std::string sx, double x0, std::string sy) const; 00601 00602 /** 00603 \brief The first derivative of the function iy(ix) at ix=x0. 00604 00605 O(log(R)) but can be as bad as O(R) if 00606 the relevant columns are not well ordered. 00607 */ 00608 double deriv(size_t ix, double x0, size_t iy); 00609 00610 /** 00611 \brief The first derivative of the function iy(ix) at ix=x0. 00612 00613 O(log(R)) but can be as bad as O(R) if 00614 the relevant columns are not well ordered. 00615 */ 00616 double deriv_const(size_t ix, double x0, size_t iy) const; 00617 00618 /** 00619 \brief Make a new column \c yp which is 00620 \f$ y^{\prime \prime}(x) \f$ - O(log(C)*R). 00621 */ 00622 int deriv2(std::string x, std::string y, std::string yp); 00623 00624 /** 00625 \brief The second derivative of the function sy(sx) at sx=x0. 00626 00627 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00628 the relevant columns are not well ordered. 00629 */ 00630 double deriv2(std::string sx, double x0, std::string sy); 00631 00632 /** 00633 \brief The second derivative of the function sy(sx) at sx=x0. 00634 00635 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00636 the relevant columns are not well ordered. 00637 */ 00638 double deriv2_const(std::string sx, double x0, std::string sy) const; 00639 00640 /** 00641 \brief The second derivative of the function iy(ix) at ix=x0. 00642 00643 O(log(R)) but can be as bad as O(R) if 00644 the relevant columns are not well ordered. 00645 */ 00646 double deriv2(size_t ix, double x0, size_t iy); 00647 00648 /** 00649 \brief The second derivative of the function iy(ix) at ix=x0. 00650 00651 O(log(R)) but can be as bad as O(R) if 00652 the relevant columns are not well ordered. 00653 */ 00654 double deriv2_const(size_t ix, double x0, size_t iy) const; 00655 00656 /** 00657 \brief The integral of the function sy(sx) from sx=x1 to sx=x2. 00658 00659 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00660 the relevant columns are not well ordered. 00661 */ 00662 double integ(std::string sx, double x1, double x2, std::string sy); 00663 00664 /** 00665 \brief The integral of the function sy(sx) from sx=x1 to sx=x2. 00666 00667 O(log(C)*log(R)) but can be as bad as O(log(C)*R) if 00668 the relevant columns are not well ordered. 00669 */ 00670 double integ_const(std::string sx, double x1, double x2, 00671 std::string sy) const; 00672 00673 /** 00674 \brief The integral of the function iy(ix) from ix=x1 to ix=x2. 00675 00676 O(log(R)) but can be as bad as O(R) if 00677 the relevant columns are not well ordered. 00678 */ 00679 double integ(size_t ix, double x1, double x2, size_t iy); 00680 00681 /** 00682 \brief The integral of the function iy(ix) from ix=x1 to ix=x2. 00683 00684 O(log(R)) but can be as bad as O(R) if 00685 the relevant columns are not well ordered. 00686 */ 00687 double integ_const(size_t ix, double x1, double x2, size_t iy) const; 00688 00689 /** 00690 \brief The integral of the function iy(ix) 00691 00692 O(log(R)) but can be as bad as O(R) if the relevant columns 00693 are not well ordered. 00694 */ 00695 int integ(std::string x, std::string y, std::string ynew); 00696 00697 /** \brief Return column maximum. Makes no assumptions about 00698 ordering - O(R). 00699 */ 00700 double max(std::string col) const; 00701 00702 /** \brief Return column minimum. Makes no assumptions about 00703 ordering - O(R). 00704 */ 00705 double min(std::string col) const; 00706 //@} 00707 00708 // -------------------------------------------------------- 00709 /** \name Subtable method */ 00710 //@{ 00711 00712 /** 00713 \brief Make a subtable 00714 00715 Uses the columns specified in \c list from the row \c top 00716 to the row of index \c bottom to generate a new table 00717 which is a copy of part of the original. 00718 00719 \comment 00720 The 'linked' variable was taken out since we're removing 00721 user-owned columns for now 00722 00723 If \c linked is false 00724 the the data will be independent from the original table. 00725 \endcomment 00726 */ 00727 table *subtable(std::string list, size_t top, size_t bottom) const; 00728 //@} 00729 00730 // -------------------------------------------------------- 00731 /** \name Add space */ 00732 //@{ 00733 00734 /** \brief Manually increase the maximum number of lines 00735 */ 00736 int inc_maxlines(size_t llines); 00737 //@} 00738 00739 // -------------------------------------------------------- 00740 /** \name Delete methods */ 00741 //@{ 00742 00743 /** \brief Delete column named \c scol - O(C). 00744 00745 This is slow because the iterators in \ref alist are mangled 00746 and we have to call \ref reset_list() to get them back. 00747 */ 00748 00749 int delete_column(std::string scol); 00750 00751 /** \brief Delete the row with the entry closest to 00752 the value \c val in column \c scol - O(R*C) 00753 */ 00754 int delete_row(std::string scol, double val); 00755 00756 /** \brief Delete the row of index \c irow - O(R*C) 00757 */ 00758 int delete_row(size_t irow); 00759 //@} 00760 00761 // -------------------------------------------------------- 00762 /** \name Clear methods */ 00763 //@{ 00764 00765 /** \brief Zero the data entries but keep the column names 00766 and nlines fixed 00767 */ 00768 void zero_table(); 00769 00770 /** \brief Clear the table and the column names 00771 */ 00772 void clear_table(); 00773 00774 /** \brief Remove all of the data by setting the number 00775 of lines to zero 00776 00777 This leaves the column names intact and does not remove 00778 the constants. 00779 */ 00780 void clear_data() { 00781 nlines=0; 00782 if (intp_set==true) { 00783 delete si; 00784 intp_set=false; 00785 } 00786 return; 00787 }; 00788 //@} 00789 00790 // -------------------------------------------------------- 00791 /** \name Sorting methods */ 00792 //@{ 00793 00794 /** \brief Sort the entire table by the column \c scol 00795 */ 00796 int sort_table(std::string scol); 00797 00798 /** \brief Individually sort the column \c scol 00799 */ 00800 int sort_column(std::string scol); 00801 //@} 00802 00803 // -------------------------------------------------------- 00804 /** \name Summary method */ 00805 //@{ 00806 /** \brief Output a summary of the information stored 00807 00808 Outputs the number of constants, the number of columns, 00809 a list of the column names, and the number of lines of 00810 data. 00811 */ 00812 int summary(std::ostream *out, int ncol=79) const; 00813 //@} 00814 00815 /// \name Constant manipulation 00816 //@{ 00817 /// Add a constant, or if the constant already exists, change its value 00818 virtual int add_constant(std::string name, double val) { 00819 if (constants.find(name)!=constants.end()) { 00820 constants.find(name)->second=val; 00821 return 0; 00822 } 00823 constants.insert(make_pair(name,val)); 00824 return 0; 00825 } 00826 00827 /// Add a constant 00828 virtual int set_constant(std::string name, double val) { 00829 if (constants.find(name)!=constants.end()) { 00830 constants.find(name)->second=val; 00831 return 0; 00832 } 00833 O2SCL_ERR_RET("No constant with specified name in set_constant().", 00834 gsl_einval); 00835 } 00836 00837 /// Get a constant 00838 virtual double get_constant(std::string name) const { 00839 return constants.find(name)->second; 00840 } 00841 00842 /// Get the number of constants 00843 virtual size_t get_nconsts() const { 00844 return constants.size(); 00845 } 00846 00847 /// Get a constant by index 00848 virtual int get_constant(size_t ix, std::string &name, double &val) const { 00849 if (ix<constants.size()) { 00850 std::map<std::string,double>::const_iterator cit=constants.begin(); 00851 for(size_t i=0;i<ix;i++) cit++; 00852 name=cit->first; 00853 val=cit->second; 00854 return 0; 00855 } 00856 O2SCL_ERR_RET("Index too large in table::get_constant().",gsl_eindex); 00857 } 00858 00859 /// Remove a constant 00860 virtual int remove_constant(std::string name) { 00861 constants.erase(name); 00862 return 0; 00863 } 00864 //@} 00865 00866 /// \name Miscellaneous methods 00867 //@{ 00868 /// Clear the current table and read from a generic data file 00869 int read_generic(std::istream &fin); 00870 00871 /** \brief Return 0 if the tree and list are properly synchronized 00872 */ 00873 int check_synchro() const; 00874 00875 /** \brief Get ownership - O(log(C)). 00876 */ 00877 bool get_owner(std::string name) const; 00878 00879 //@} 00880 00881 /// Default interpolation manager 00882 def_interp_mgr<ovector_const_view,cspline_interp> dim1; 00883 00884 /// Default interpolation manager 00885 def_interp_mgr<ovector_const_subvector,cspline_interp> dim2; 00886 00887 /// Return the type, \c "table". 00888 virtual const char *type() { return "table"; } 00889 00890 /// True if the interpolation type has been set 00891 bool intp_set; 00892 00893 protected: 00894 00895 #ifndef DOXYGEN_INTERNAL 00896 00897 friend class io_tlate<table>; 00898 00899 /** \brief The list of constants 00900 */ 00901 std::map<std::string,double> constants; 00902 00903 /** \brief Set the elements of alist with the appropriate 00904 iterators from atree - O(C). 00905 00906 Generally, the end-user shouldn't need this method. It is 00907 only used in delete_column() to rearrange the list when 00908 a column is deleted from the tree. 00909 */ 00910 int reset_list(); 00911 00912 /** 00913 \brief Ensure a variable name does not match a function or contain 00914 non-alphanumeric characters 00915 */ 00916 int make_fp_varname(std::string &s); 00917 00918 /// Make sure a name is unique 00919 int make_unique_name(std::string &col, std::vector<std::string> &cnames); 00920 00921 /// Column structure for \ref table [protected] 00922 typedef struct col_s { 00923 /// Pointer to column 00924 ovector_base *dat; 00925 /// Owner of column 00926 bool owner; 00927 /// Column index 00928 int index; 00929 } col; 00930 00931 /// \name Iterator types 00932 //@{ 00933 typedef std::map<std::string,col,string_comp>::iterator aiter; 00934 typedef std::map<std::string,col,string_comp>::const_iterator aciter; 00935 typedef std::vector<aiter>::iterator aviter; 00936 //@} 00937 00938 /// \name Actual data 00939 //@{ 00940 /// The size of allocated memory 00941 size_t maxlines; 00942 /// The size of presently used memory 00943 size_t nlines; 00944 /// The tree of columns 00945 std::map<std::string,col,string_comp> atree; 00946 /// The list of tree iterators 00947 std::vector<aiter> alist; 00948 //@} 00949 00950 /// \name Column manipulation methods 00951 //@{ 00952 /// Return the iterator for a column 00953 aiter get_iterator(std::string lname); 00954 /// Return the column structure for a column 00955 col *get_col_struct(std::string lname); 00956 /// Return the beginning of the column tree 00957 aiter begin() {return atree.begin();}; 00958 /// Return the end of the column tree 00959 aiter end() {return atree.end();}; 00960 //@} 00961 00962 /// An empty vector for get_column() 00963 ovector empty_col; 00964 00965 /// The sorting function 00966 static int sortd_comp(const void *a, const void *b); 00967 00968 /// A structure for sorting in \ref table [protected] 00969 typedef struct sortd_s { 00970 /// Value to sort 00971 double val; 00972 /// Sorted index 00973 int indx; 00974 } sortd; 00975 00976 /// \name Interpolation 00977 //@{ 00978 /// The interpolation object 00979 sm_interp_vec *si; 00980 00981 /// A pointer to the interpolation manager 00982 base_interp_mgr<ovector_const_view> *bim1; 00983 /// A pointer to the subvector interpolation manager 00984 base_interp_mgr<ovector_const_subvector> *bim2; 00985 00986 /// The vector-searching object 00987 search_vec<ovector> se; 00988 00989 /// The last x-column interpolated 00990 std::string intp_colx; 00991 00992 /// The last y-column interpolated 00993 std::string intp_coly; 00994 00995 //@} 00996 00997 #endif 00998 00999 }; 01000 01001 /// Input specialization 01002 template<> int io_tlate<table>::input 01003 (cinput *co, o2scl::in_file_format *ins, table *ta); 01004 /// Output specialization 01005 template<> int io_tlate<table>::output 01006 (coutput *co, o2scl::out_file_format *outs, 01007 table *at); 01008 /// \fn Type specialization 01009 template<> const char *io_tlate<table>::type(); 01010 01011 typedef io_tlate<table> table_io_type; 01012 01013 #ifndef DOXYGENP 01014 } 01015 #endif 01016 01017 #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