MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/util/maps.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines