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