![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_MAPS_H 00021 #define MECHSYS_MAPS_H 00022 00023 // Std lib 00024 #include <cstring> // for strcmp 00025 #include <iostream> // for cout 00026 #include <sstream> // for istringstream, ostringstream 00027 #include <cstdarg> // for va_list, va_start, va_end 00028 #include <cmath> // for fabs 00029 #include <fstream> 00030 #include <map> 00031 00032 // MechSys 00033 #include <mechsys/util/array.h> 00034 #include <mechsys/util/string.h> 00035 #include <mechsys/util/numstreams.h> 00036 00037 00039 00040 00041 typedef std::map<String,double> StrDbl_t; 00042 00044 class SDPair : public StrDbl_t 00045 { 00046 public: 00047 // Constructors 00048 SDPair () {} 00049 SDPair (SDPair const & R) { (*this) = R; } 00050 00051 // Set methods 00052 void Set (const char * Str, ...); 00053 void SetZero (Array<String> const & keys); 00054 00055 // Operators 00056 double & operator() (char const * Key); 00057 double const & operator() (char const * Key) const; 00058 double & operator() (String const & Key) { return operator()(Key.CStr()); } 00059 double const & operator() (String const & Key) const { return operator()(Key.CStr()); } 00060 void operator= (SDPair const & R); 00061 void operator+= (SDPair const & R); 00062 00063 // Methods 00064 void Del (const char * Key); 00065 size_t ReSet (const char * Key, double Val); 00066 size_t AddVal (const char * Key, double Val); 00067 void SetValues (double Val); 00068 double ValOrZero (char const * Key) const; 00069 double ValOrZero (String const & Key) const { return ValOrZero(Key.CStr()); } 00070 bool HasKey (char const * Key) const; 00071 bool HasKey (String const & Key) const; 00072 long IdxKey (String const & Key) const { return Keys.Find(Key); } 00073 void Val2Key (double Val, String & Key, double Tol=1.0e-15) const; 00074 void clear () { Keys.Clear(); StrDbl_t::clear(); } 00075 00076 // Data 00077 Array<String> Keys; 00078 00079 #ifdef USE_BOOST_PYTHON 00080 void PySet (BPy::dict const & Pairs); 00081 #endif 00082 }; 00083 00084 00086 00087 00088 typedef std::map<String,int> StrInt_t; 00089 00091 class SIPair : public StrInt_t 00092 { 00093 public: 00094 // Set methods 00095 void Set (const char * Str, ...); 00096 00097 // Operators 00098 int & operator() (char const * Key); 00099 int const & operator() (char const * Key) const; 00100 int & operator() (String const & Key) { return operator()(Key.CStr()); } 00101 int const & operator() (String const & Key) const { return operator()(Key.CStr()); } 00102 00103 // Methods 00104 void Del (const char * Key); 00105 bool HasKey (char const * Key) const; 00106 bool HasKey (String const & Key) const; 00107 void clear () { Keys.Clear(); StrInt_t::clear(); } 00108 00109 // Data 00110 Array<String> Keys; 00111 }; 00112 00113 00115 00116 00117 typedef std::map<int, SDPair> Dict_t; 00118 00120 class Dict : public Dict_t 00121 { 00122 public: 00123 // Constructors 00124 Dict () {} 00125 Dict (Dict const & R) { (*this) = R; } 00126 00127 // Methods 00128 void Set (int Key, const char * Str, ...); 00129 void Set (int Key, SDPair const & P); 00130 void SetZero (int Key, Array<String> const & keys); 00131 void Del (int Key); 00132 00133 // Operators 00134 SDPair const & operator() (int Key) const; 00135 SDPair & operator() (int Key); 00136 void operator= (Dict const & R); 00137 void operator+= (Dict const & R); 00138 00139 // Methods 00140 bool HasKey (int Key) const; 00141 void clear () { Keys.Clear(); Dict_t::clear(); } 00142 00143 // Data 00144 Array<int> Keys; 00145 00146 #ifdef USE_BOOST_PYTHON 00147 void PySet (int Key, BPy::dict const & Pairs); 00148 void PyGet (int Key, BPy::dict & Pairs); 00149 #endif 00150 }; 00151 00152 00154 00155 00156 typedef std::map<String,Array<double> > Table_t; 00157 00158 class Table : public Table_t 00159 { 00160 public: 00161 // Constructor 00162 Table () : NRows(0) {} 00163 00164 // Methods 00167 void Set (const char * StrKeys, size_t NumRows, ...); 00168 void SetZero (const char * StrKeys, size_t NumRows); 00169 void Read (const char * FileName); 00170 void Write (const char * FileName, char const * NF="%15.8e"); 00171 00172 // Operators 00173 Array<double> & operator() (String const & Key); 00174 Array<double> const & operator() (String const & Key) const; 00175 double & operator() (String const & Key, size_t iRow); 00176 double const & operator() (String const & Key, size_t iRow) const; 00177 00178 // Data 00179 size_t NRows; 00180 Array<String> Keys; 00181 00182 #ifdef USE_BOOST_PYTHON 00183 void PySet (BPy::list const & StrKeys, BPy::list const & Values); 00184 #endif 00185 }; 00186 00187 00189 00190 00191 std::ostream & operator<< (std::ostream & os, SDPair const & P) 00192 { 00193 int nkeys = P.size(); 00194 int k = 0; 00195 /* 00196 os << "{"; 00197 for (size_t i=0; i<P.Keys.Size(); ++i) 00198 { 00199 String key = P.Keys[i]; 00200 String val; val.Printf("%g",P(key)); 00201 os << "'" << key << "':" << val; 00202 if (k<nkeys-1) os << ", "; 00203 k++; 00204 } 00205 os << "}"; 00206 */ 00207 for (size_t i=0; i<P.Keys.Size(); ++i) 00208 { 00209 String key = P.Keys[i]; 00210 String val; val.Printf("%g",P(key)); 00211 os << key << "=" << val; 00212 if (k<nkeys-1) os << " "; 00213 k++; 00214 } 00215 return os; 00216 } 00217 00218 std::ostream & operator<< (std::ostream & os, SIPair const & P) 00219 { 00220 int nkeys = P.size(); 00221 int k = 0; 00222 os << "{"; 00223 for (size_t i=0; i<P.Keys.Size(); ++i) 00224 { 00225 String key = P.Keys[i]; 00226 String val; val.Printf("%d",P(key)); 00227 os << "'" << key << "':" << val; 00228 if (k<nkeys-1) os << ", "; 00229 k++; 00230 } 00231 os << "}"; 00232 return os; 00233 } 00234 00235 std::ostream & operator<< (std::ostream & os, Dict const & D) 00236 { 00237 int nkeys = D.size(); 00238 int k = 0; 00239 os << "{"; 00240 for (size_t i=0; i<D.Keys.Size(); ++i) 00241 { 00242 int key = D.Keys[i]; 00243 os << key << ":" << D(key); 00244 if (k<nkeys-1) os << ",\n "; 00245 k++; 00246 } 00247 os << "}"; 00248 return os; 00249 } 00250 00251 std::ostream & operator<< (std::ostream & os, Table const & T) 00252 { 00253 // keys 00254 for (size_t i=0; i<T.Keys.Size(); ++i) os << Util::_8s << T.Keys[i]; 00255 os << "\n"; 00256 00257 // values 00258 for (size_t i=0; i<T.NRows; ++i) 00259 { 00260 for (size_t j=0; j<T.Keys.Size(); ++j) os << Util::_8s << T(T.Keys[j],i); 00261 os << "\n"; 00262 } 00263 00264 return os; 00265 } 00266 00267 00269 00270 00271 inline void SDPair::Set(const char * Str, ...) 00272 { 00273 std::istringstream iss(Str); 00274 String key; 00275 va_list arg_list; 00276 va_start (arg_list, Str); 00277 while (iss>>key) 00278 { 00279 Keys.XPush (key); 00280 (*this)[key] = va_arg(arg_list,double); 00281 } 00282 va_end (arg_list); 00283 } 00284 00285 inline void SDPair::SetZero (Array<String> const & keys) 00286 { 00287 for (size_t i=0; i<keys.Size(); ++i) 00288 { 00289 Keys.XPush (keys[i]); 00290 (*this)[keys[i]] = 0.0; 00291 } 00292 } 00293 00294 inline double & SDPair::operator() (char const * Key) 00295 { 00296 StrDbl_t::iterator p = this->find(Key); 00297 if (p==this->end()) 00298 { 00299 std::ostringstream oss; 00300 oss << (*this); 00301 throw new Fatal("SDPair::operator(): String-Double pair: %s does not have a key = '%s'",oss.str().c_str(),Key); 00302 } 00303 return p->second; 00304 } 00305 00306 inline double const & SDPair::operator() (char const * Key) const 00307 { 00308 StrDbl_t::const_iterator p = this->find(Key); 00309 if (p==this->end()) 00310 { 00311 std::ostringstream oss; 00312 oss << (*this); 00313 throw new Fatal("SDPair::operator(): String-Double pair: %s does not have a key = '%s'",oss.str().c_str(),Key); 00314 } 00315 return p->second; 00316 } 00317 00318 inline void SDPair::operator= (SDPair const & R) 00319 { 00320 this->clear(); 00321 Keys.Resize (R.Keys.Size()); 00322 for (size_t i=0; i<R.Keys.Size(); ++i) 00323 { 00324 Keys[i] = R.Keys[i]; 00325 (*this)[Keys[i]] = R(Keys[i]); 00326 } 00327 } 00328 00329 inline void SDPair::operator+= (SDPair const & R) 00330 { 00331 for (size_t i=0; i<R.Keys.Size(); ++i) 00332 { 00333 if (this->HasKey(R.Keys[i])) 00334 { 00335 std::ostringstream oss; 00336 oss << (*this); 00337 throw new Fatal("SDPair::operator+= : SDPair [%s]\n already contain key %s (values cannot be summed up).",oss.str().c_str(),R.Keys[i].CStr()); 00338 } 00339 // This is fine though (if addition is permitted): (*this)(R.Keys[i]) += R(R.Keys[i]); 00340 else this->Set(R.Keys[i].CStr(), R(R.Keys[i])); 00341 } 00342 } 00343 00344 inline void SDPair::Del (const char * Key) 00345 { 00346 StrDbl_t::iterator p = this->find(Key); 00347 if (p==this->end()) 00348 { 00349 std::ostringstream oss; 00350 oss << (*this); 00351 throw new Fatal("SDPair::Del: String-Double pair: %s does not have a key = '%s'",oss.str().c_str(),Key); 00352 } 00353 else 00354 { 00355 Keys.DelVal (Key); 00356 this->erase (p); 00357 } 00358 } 00359 00360 inline size_t SDPair::ReSet (const char * Key, double Val) 00361 { 00362 StrDbl_t::iterator p = this->find(Key); 00363 if (p==this->end()) 00364 { 00365 (*this)[Key] = Val; 00366 Keys.Push (Key); 00367 return Keys.Size()-1; 00368 } 00369 else 00370 { 00371 p->second = Val; 00372 long pos = Keys.Find(Key); 00373 return static_cast<size_t>(pos); 00374 } 00375 } 00376 00377 inline size_t SDPair::AddVal (const char * Key, double Val) 00378 { 00379 StrDbl_t::iterator p = this->find(Key); 00380 if (p==this->end()) 00381 { 00382 (*this)[Key] = Val; 00383 Keys.Push (Key); 00384 return Keys.Size()-1; 00385 } 00386 else 00387 { 00388 p->second += Val; 00389 long pos = Keys.Find(Key); 00390 return static_cast<size_t>(pos); 00391 } 00392 } 00393 00394 inline void SDPair::SetValues (double Val) 00395 { 00396 for (StrDbl_t::iterator p=this->begin(); p!=this->end(); ++p) 00397 p->second = Val; 00398 } 00399 00400 inline double SDPair::ValOrZero (char const * Key) const 00401 { 00402 StrDbl_t::const_iterator p = this->find(Key); 00403 if (p==this->end()) return 0.0; 00404 else return p->second; 00405 } 00406 00407 inline bool SDPair::HasKey (char const * Key) const 00408 { 00409 StrDbl_t::const_iterator p = this->find(Key); 00410 return (p!=this->end()); 00411 } 00412 00413 inline bool SDPair::HasKey (String const & Key) const 00414 { 00415 StrDbl_t::const_iterator p = this->find(Key); 00416 return (p!=this->end()); 00417 } 00418 00419 inline void SDPair::Val2Key (double Val, String & Key, double Tol) const 00420 { 00421 bool found = false; 00422 for (StrDbl_t::const_iterator p=this->begin(); p!=this->end(); ++p) 00423 { 00424 if (fabs(Val-p->second)<Tol) 00425 { 00426 Key = p->first; 00427 found = true; 00428 break; 00429 } 00430 } 00431 if (!found) 00432 { 00433 std::ostringstream oss; 00434 oss << (*this); 00435 throw new Fatal("SDPair::Val2Key: Could not find Val=%g in map: %s",Val,oss.str().c_str()); 00436 } 00437 } 00438 00439 #ifdef USE_BOOST_PYTHON 00440 inline void SDPair::PySet (BPy::dict const & Pairs) 00441 { 00442 BPy::object const & keys = Pairs.iterkeys(); 00443 BPy::object const & vals = Pairs.itervalues(); 00444 for (int i=0; i<BPy::len(Pairs); ++i) 00445 { 00446 char const * key = BPy::extract<char const *>(keys.attr("next")()); 00447 double val = BPy::extract<double >(vals.attr("next")()); 00448 Set (key, val); 00449 } 00450 } 00451 #endif 00452 00453 00455 00456 00457 inline void SIPair::Set(const char * Str, ...) 00458 { 00459 std::istringstream iss(Str); 00460 String key; 00461 va_list arg_list; 00462 va_start (arg_list, Str); 00463 while (iss>>key) 00464 { 00465 Keys.XPush (key); 00466 (*this)[key] = va_arg(arg_list,int); 00467 } 00468 va_end (arg_list); 00469 } 00470 00471 inline int & SIPair::operator() (char const * Key) 00472 { 00473 StrInt_t::iterator p = this->find(Key); 00474 if (p==this->end()) 00475 { 00476 std::ostringstream oss; 00477 oss << (*this); 00478 throw new Fatal("SIPair::operator(): String-Int pair: %s does not have a key = '%s'",oss.str().c_str(),Key); 00479 } 00480 return p->second; 00481 } 00482 00483 inline int const & SIPair::operator() (char const * Key) const 00484 { 00485 StrInt_t::const_iterator p = this->find(Key); 00486 if (p==this->end()) 00487 { 00488 std::ostringstream oss; 00489 oss << (*this); 00490 throw new Fatal("SIPair::operator(): String-Int pair: %s does not have a key = '%s'",oss.str().c_str(),Key); 00491 } 00492 return p->second; 00493 } 00494 00495 inline void SIPair::Del (const char * Key) 00496 { 00497 StrInt_t::iterator p = this->find(Key); 00498 if (p==this->end()) 00499 { 00500 std::ostringstream oss; 00501 oss << (*this); 00502 throw new Fatal("SIPair::Del: String-Int pair: %s does not have a key = '%s'",oss.str().c_str(),Key); 00503 } 00504 else 00505 { 00506 Keys.DelVal (Key); 00507 this->erase (p); 00508 } 00509 } 00510 00511 inline bool SIPair::HasKey (char const * Key) const 00512 { 00513 StrInt_t::const_iterator p = this->find(Key); 00514 return (p!=this->end()); 00515 } 00516 00517 inline bool SIPair::HasKey (String const & Key) const 00518 { 00519 StrInt_t::const_iterator p = this->find(Key); 00520 return (p!=this->end()); 00521 } 00522 00523 00525 00526 00527 inline void Dict::Set (int Key, const char * Str, ...) 00528 { 00529 bool has_key = HasKey(Key); 00530 SDPair & pair = (has_key ? (*this)(Key) : (*this)[Key]); 00531 std::istringstream iss(Str); 00532 String skey; 00533 va_list arg_list; 00534 va_start (arg_list, Str); 00535 while (iss>>skey) pair.Set (skey.CStr(), va_arg(arg_list,double)); 00536 va_end (arg_list); 00537 if (!has_key) Keys.Push (Key); 00538 } 00539 00540 inline void Dict::Set (int Key, SDPair const & P) 00541 { 00542 for (size_t i=0; i<P.Keys.Size(); ++i) 00543 this->Set (Key, P.Keys[i].CStr(), P(P.Keys[i])); 00544 if (P.Keys.Size()==0) 00545 { 00546 if (!HasKey(Key)) 00547 { 00548 (*this)[Key] = P; 00549 Keys.Push (Key); 00550 } 00551 } 00552 } 00553 00554 inline void Dict::SetZero (int Key, Array<String> const & keys) 00555 { 00556 SDPair pair; 00557 pair.SetZero (keys); 00558 this->Set (Key, pair); 00559 } 00560 00561 inline void Dict::Del (int Key) 00562 { 00563 Dict_t::iterator p = this->find(Key); 00564 if (p==this->end()) 00565 { 00566 std::ostringstream oss; 00567 oss << (*this); 00568 throw new Fatal("Dict::Del: Dictionary: %s does not have a key = %d",oss.str().c_str(),Key); 00569 } 00570 erase (p); 00571 Keys.DelVal (Key); 00572 } 00573 00574 inline SDPair const & Dict::operator() (int Key) const 00575 { 00576 Dict_t::const_iterator p = this->find(Key); 00577 if (p==this->end()) 00578 { 00579 std::ostringstream oss; 00580 oss << (*this); 00581 throw new Fatal("Dict::operator(): Dictionary: %s does not have a key = %d",oss.str().c_str(),Key); 00582 } 00583 return p->second; 00584 } 00585 00586 inline SDPair & Dict::operator() (int Key) 00587 { 00588 Dict_t::iterator p = this->find(Key); 00589 if (p==this->end()) 00590 { 00591 std::ostringstream oss; 00592 oss << (*this); 00593 throw new Fatal("Dict::operator(): Dictionary: %s does not have a key = %d",oss.str().c_str(),Key); 00594 } 00595 return p->second; 00596 } 00597 00598 inline void Dict::operator= (Dict const & R) 00599 { 00600 this->clear(); 00601 Keys.Resize (R.Keys.Size()); 00602 for (size_t i=0; i<R.Keys.Size(); ++i) 00603 { 00604 Keys[i] = R.Keys[i]; 00605 (*this)[Keys[i]] = R(Keys[i]); 00606 } 00607 } 00608 00609 inline void Dict::operator+= (Dict const & R) 00610 { 00611 for (size_t i=0; i<R.Keys.Size(); ++i) 00612 { 00613 if (this->HasKey(R.Keys[i])) (*this)(R.Keys[i]) += R(R.Keys[i]); // merge 00614 else this->Set(R.Keys[i], R(R.Keys[i])); 00615 } 00616 } 00617 00618 inline bool Dict::HasKey (int Key) const 00619 { 00620 if (Keys.Find(Key)<0) return false; 00621 else return true; 00622 } 00623 00624 #ifdef USE_BOOST_PYTHON 00625 inline void Dict::PySet (int Key, BPy::dict const & Pairs) 00626 { 00627 BPy::object const & keys = Pairs.iterkeys(); 00628 BPy::object const & vals = Pairs.itervalues(); 00629 for (int i=0; i<BPy::len(Pairs); ++i) 00630 { 00631 char const * key = BPy::extract<char const *>(keys.attr("next")()); 00632 double val = BPy::extract<double >(vals.attr("next")()); 00633 Set (Key, key, val); 00634 } 00635 } 00636 00637 inline void Dict::PyGet (int Key, BPy::dict & Pairs) 00638 { 00639 SDPair const & pairs = (*this)(Key); 00640 for (size_t i=0; i<pairs.Keys.Size(); ++i) Pairs[pairs.Keys[i].CStr()] = pairs(pairs.Keys[i]); 00641 } 00642 #endif 00643 00644 00646 00647 00648 inline void Table::Set (const char * StrKeys, size_t NumRows, ...) 00649 { 00650 NRows = NumRows; 00651 Keys.Resize(0); 00652 00653 // retrieve keys and initialize table 00654 String key; 00655 std::istringstream iss(StrKeys); 00656 while (iss>>key) 00657 { 00658 if (Keys.Find(key)<0) Keys.Push(key); 00659 (*this)[key].Resize (NRows); 00660 } 00661 00662 // read values 00663 va_list arg_list; 00664 va_start (arg_list, NumRows); 00665 for (size_t i=0; i<NumRows; ++i) 00666 { 00667 for (size_t j=0; j<Keys.Size(); ++j) 00668 { 00669 (*this)[Keys[j]][i] = va_arg(arg_list,double); 00670 } 00671 } 00672 va_end (arg_list); 00673 } 00674 00675 inline void Table::SetZero (const char * StrKeys, size_t NumRows) 00676 { 00677 NRows = NumRows; 00678 Keys.Resize(0); 00679 00680 // retrieve keys and initialize table 00681 String key; 00682 std::istringstream iss(StrKeys); 00683 while (iss>>key) 00684 { 00685 if (Keys.Find(key)<0) Keys.Push(key); 00686 (*this)[key].Resize (NRows); 00687 (*this)[key].SetValues (0.0); 00688 } 00689 } 00690 00691 inline void Table::Read (const char * FileName) 00692 { 00693 // open file 00694 std::fstream fil(FileName, std::ios::in); 00695 if (!fil.is_open()) throw new Fatal("Table::Read Could not open file < %s >",FileName); 00696 00697 // erase data 00698 Table_t::clear(); 00699 NRows = 0; 00700 00701 // parse 00702 bool header = true; 00703 String line, str; 00704 double val; 00705 while (!fil.eof()) 00706 { 00707 // read line 00708 std::getline (fil,line); 00709 std::istringstream iss(line); 00710 00711 // header 00712 if (header) 00713 { 00714 while (iss>>str) 00715 { 00716 Keys.Push (str); 00717 (*this)[str].Resize (0); 00718 } 00719 header = false; 00720 } 00721 else 00722 { 00723 for (size_t i=0; i<Keys.Size(); ++i) 00724 { 00725 if (iss>>val) 00726 { 00727 (*this)[Keys[i]].Push (val); 00728 if (i==0) NRows++; 00729 } 00730 } 00731 } 00732 } 00733 } 00734 00735 inline void Table::Write (const char * FileName, char const * NF) 00736 { 00737 // keys 00738 String fmt, buf; 00739 fmt.TextFmt (NF); 00740 std::ostringstream oss; 00741 for (size_t i=0; i<Keys.Size(); ++i) 00742 { 00743 buf.Printf (fmt.CStr(), Keys[i].CStr()); 00744 oss << buf << " "; 00745 } 00746 oss << "\n"; 00747 00748 // values 00749 for (size_t i=0; i<NRows; ++i) 00750 { 00751 for (size_t j=0; j<Keys.Size(); ++j) 00752 { 00753 buf.Printf (NF, operator()(Keys[j],i)); 00754 oss << buf << " "; 00755 } 00756 oss << "\n"; 00757 } 00758 00759 // open file and save data 00760 std::ofstream of(FileName, std::ios::out); 00761 of << oss.str(); 00762 of.close(); 00763 } 00764 00765 inline Array<double> & Table::operator() (String const & Key) 00766 { 00767 Table_t::iterator p = this->find(Key); 00768 if (p==this->end()) 00769 { 00770 std::ostringstream oss; 00771 oss << Keys; 00772 throw new Fatal("Table::operator(): Table with Keys=[%s] does not have a key = '%s'",oss.str().c_str(),Key.CStr()); 00773 } 00774 return p->second; 00775 } 00776 00777 inline Array<double> const & Table::operator() (String const & Key) const 00778 { 00779 Table_t::const_iterator p = this->find(Key); 00780 if (p==this->end()) 00781 { 00782 std::ostringstream oss; 00783 oss << Keys; 00784 throw new Fatal("Table::operator(): Table with Keys=[%s] does not have a key = '%s'",oss.str().c_str(),Key.CStr()); 00785 } 00786 return p->second; 00787 } 00788 00789 inline double & Table::operator() (String const & Key, size_t iRow) 00790 { 00791 Table_t::iterator p = this->find(Key); 00792 if (p==this->end()) 00793 { 00794 std::ostringstream oss; 00795 oss << Keys; 00796 throw new Fatal("Table::operator(): Table with Keys=[%s] does not have a key = '%s'",oss.str().c_str(),Key.CStr()); 00797 } 00798 return p->second[iRow]; 00799 } 00800 00801 inline double const & Table::operator() (String const & Key, size_t iRow) const 00802 { 00803 Table_t::const_iterator p = this->find(Key); 00804 if (p==this->end()) 00805 { 00806 std::ostringstream oss; 00807 oss << Keys; 00808 throw new Fatal("Table::operator(): Table with Keys=[%s] does not have a key = '%s'",oss.str().c_str(),Key.CStr()); 00809 } 00810 return p->second[iRow]; 00811 } 00812 00813 #ifdef USE_BOOST_PYTHON 00814 inline void Table::PySet (BPy::list const & StrKeys, BPy::list const & Values) 00815 { 00816 NRows = BPy::len(Values); 00817 00818 // retrieve keys and initialize table 00819 size_t nkeys = BPy::len(StrKeys); 00820 for (size_t i=0; i<nkeys; ++i) 00821 { 00822 char const * key = BPy::extract<char const *>(StrKeys[i])(); 00823 if (Keys.Find(key)<0) Keys.Push(key); 00824 (*this)[key].Resize (NRows); 00825 } 00826 00827 // read values 00828 for (size_t i=0; i<NRows; ++i) 00829 { 00830 BPy::list const & line = BPy::extract<BPy::list>(Values[i])(); 00831 for (size_t j=0; j<Keys.Size(); ++j) 00832 { 00833 (*this)[Keys[j]][i] = BPy::extract<double>(line[j])(); 00834 } 00835 } 00836 } 00837 #endif 00838 00839 00840 #endif // MECHSYS_MAPS_H