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