Namelist.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: Namelist.cpp 2293 2010-02-12 18:14:16Z btolman $"
00002 
00003 //============================================================================
00004 //
00005 //  This file is part of GPSTk, the GPS Toolkit.
00006 //
00007 //  The GPSTk is free software; you can redistribute it and/or modify
00008 //  it under the terms of the GNU Lesser General Public License as published
00009 //  by the Free Software Foundation; either version 2.1 of the License, or
00010 //  any later version.
00011 //
00012 //  The GPSTk is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU Lesser General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU Lesser General Public
00018 //  License along with GPSTk; if not, write to the Free Software Foundation,
00019 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //  
00021 //  Copyright 2004, The University of Texas at Austin
00022 //
00023 //============================================================================
00024 
00025 //============================================================================
00026 //
00027 //This software developed by Applied Research Laboratories at the University of
00028 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00029 //Department of Defense. The U.S. Government retains all rights to use,
00030 //duplicate, distribute, disclose, or release this software. 
00031 //
00032 //Pursuant to DoD Directive 523024 
00033 //
00034 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00035 //                           release, distribution is unlimited.
00036 //
00037 //=============================================================================
00038 
00046 //------------------------------------------------------------------------------------
00047 // system includes
00048 #include <string>
00049 #include <vector>
00050 #include <algorithm>
00051 #include <ostream>
00052 #include <fstream> // for copyfmt
00053 // GPSTk
00054 #include "Exception.hpp"
00055 #include "StringUtils.hpp"
00056 #include "Namelist.hpp"
00057 
00058 using namespace std;
00059 
00060 namespace gpstk
00061 {
00062 
00063 using namespace StringUtils;
00064 
00065 //------------------------------------------------------------------------------------
00066 // constructor given dimension - creates default labels
00067 Namelist::Namelist(const unsigned int& n)
00068 {
00069 try {
00070    if(n == 0) return;
00071    string name;
00072    for(unsigned int i=0; i<n; i++) {
00073       ostringstream oss;
00074       oss << "NAME" << setw(3) << setfill('0') << i;
00075       name = oss.str();
00076       labels.push_back(name);
00077    }
00078 }
00079 catch(Exception& e) { GPSTK_RETHROW(e); }
00080 }
00081 
00082 // explicit constructor - only a unique subset of names will be included.
00083 Namelist::Namelist(const vector<string>& names)
00084 {
00085 try {
00086    for(unsigned int i=0; i<names.size(); i++) {
00087       bool unique=true;
00088       for(unsigned int j=i+1; j<names.size(); j++) {
00089          if(names[i] == names[j]) { unique=false; break; }
00090       }
00091       if(unique) labels.push_back(names[i]);
00092    }
00093 }
00094 catch(Exception& e) { GPSTK_RETHROW(e); }
00095 }
00096 
00097 // add a name to the Namelist; do nothing if the name is not unique.
00098 Namelist& Namelist::operator+=(const string& name)
00099 {
00100 try {
00101    if(this->contains(name)) return *this;
00102    labels.push_back(name);
00103    return *this;
00104 }
00105 catch(Exception& e) { GPSTK_RETHROW(e); }
00106 }
00107 
00108 // remove a name from the Namelist; does nothing if the name is not found.
00109 Namelist& Namelist::operator-=(const string& name)
00110 {
00111 try {
00112    vector<string>::iterator it;
00113    it = find(labels.begin(),labels.end(),name);
00114    if(it != labels.end())
00115       labels.erase(it);
00116    return *this;
00117 }
00118 catch(Exception& e) { GPSTK_RETHROW(e); }
00119 }
00120 
00121 // swap two elements, as given by their indexes; no effect if either index
00122 // is out of range.
00123 void Namelist::swap(const unsigned int& i, const unsigned int& j)
00124 {
00125 try {
00126    if(i == j) return;
00127    if(i >= labels.size() || j >= labels.size()) return;
00128    string str = labels[i];
00129    labels[i] = labels[j];
00130    labels[j] = str;
00131 }
00132 catch(Exception& e) { GPSTK_RETHROW(e); }
00133 }
00134 
00135 // reorder the list by sorting
00136 void Namelist::sort(void)
00137 {
00138 try {
00139    // compiler tries Namelist::sort() first...
00140    std::sort(labels.begin(),labels.end());
00141 }
00142 catch(Exception& e) { GPSTK_RETHROW(e); }
00143 }
00144 
00145 // resize the list by either truncation or adding default names.
00146 void Namelist::resize(unsigned int n)
00147 {
00148 try {
00149    if(n == labels.size()) return;
00150    int N=labels.size();
00151    while(labels.size() < n) {
00152       string s;
00153       do {
00154          ostringstream oss;
00155          oss << "NAME" << setw(3) << setfill('0') << N;
00156          s = oss.str();
00157          N++;
00158       } while(this->contains(s));
00159       labels.push_back(s);
00160    }
00161    while(labels.size() > n) {
00162       labels.pop_back();
00163    }
00164 }
00165 catch(Exception& e) { GPSTK_RETHROW(e); }
00166 }
00167 
00168 // randomize the list
00169 void Namelist::randomize(long seed)
00170 {
00171 try {
00172    if(labels.size() <= 1) return;
00173    random_shuffle(labels.begin(), labels.end());
00174 }
00175 catch(Exception& e) { GPSTK_RETHROW(e); }
00176 }
00177 
00178 // is the Namelist valid? checks for repeated names
00179 bool Namelist::valid(void) const
00180 {
00181 try {
00182    for(unsigned int i=0; i<labels.size(); i++)
00183       for(unsigned int j=i+1; j<labels.size(); j++)
00184          if(labels[i] == labels[j]) return false;
00185    return true;
00186 }
00187 catch(Exception& e) { GPSTK_RETHROW(e); }
00188 }
00189 
00190 // does the Namelist contain the input name?
00191 bool Namelist::contains(const string& name) const
00192 {
00193 try {
00194    for(unsigned int i=0; i<labels.size(); i++)
00195       if(labels[i] == name) return true;
00196    return false;
00197 }
00198 catch(Exception& e) { GPSTK_RETHROW(e); }
00199 }
00200 
00201 // are two Namelists identical, ignoring a permutation?
00202 bool operator==(const Namelist& N1, const Namelist& N2)
00203 {
00204 try {
00205    if(N1.size() != N2.size()) return false;
00206    if(N1.size() == 0) return true;
00207    for(unsigned int i=0; i<N1.size(); i++) {
00208       unsigned int match=0;
00209       for(unsigned int j=0; j<N2.size(); j++)
00210          if(N1.labels[i] == N2.labels[j]) match++;
00211       if(match != 1) return false;     // if > 1, N2 is invalid
00212    }
00213    return true;
00214 }
00215 catch(Exception& e) { GPSTK_RETHROW(e); }
00216 }
00217 
00218 // are two Namelists different, ignoring a permutation?
00219 bool operator!=(const Namelist& N1, const Namelist& N2)
00220 {
00221 try {
00222    return !(N1==N2);
00223 }
00224 catch(Exception& e) { GPSTK_RETHROW(e); }
00225 }
00226 
00227 // are two Namelists exactly identical, even considering permutations?
00228 bool identical(const Namelist& N1, const Namelist& N2)
00229 {
00230 try {
00231    if(N1.size() != N2.size()) return false;
00232    if(N1.size() == 0) return true;
00233    for(unsigned int i=0; i<N1.size(); i++) {
00234       if(N1.labels[i] != N2.labels[i]) return false;
00235    }
00236    return true;
00237 }
00238 catch(Exception& e) { GPSTK_RETHROW(e); }
00239 }
00240 
00241 // construct the subset Namelist which is common to the two input (AND)
00242 Namelist operator&(const Namelist& N1, const Namelist& N2)
00243 {
00244 try {
00245    Namelist N(N1);
00246    N &= N2;
00247    return N;
00248 }
00249 catch(Exception& e) { GPSTK_RETHROW(e); }
00250 }
00251 
00252 // merge two Namelists, i.e. construct a non-redundant combination (OR)
00253 Namelist operator|(const Namelist& N1, const Namelist& N2)
00254 {
00255 try {
00256    Namelist N(N1);
00257    N |= N2;
00258    return N;
00259 }
00260 catch(Exception& e) { GPSTK_RETHROW(e); }
00261 }
00262 
00263 // construct the subset Namelist which is NOT common to two others (XOR)
00264 Namelist operator^(const Namelist& N1, const Namelist& N2)
00265 {
00266 try {
00267    Namelist N(N1);
00268    N ^= N2;
00269    return N;
00270 }
00271 catch(Exception& e) { GPSTK_RETHROW(e); }
00272 }
00273 
00274 // replace this with (this & input) (AND - common to both)
00275 Namelist& Namelist::operator&=(const Namelist& N)
00276 {
00277 try {
00278    Namelist NAND;
00279    for(unsigned int i=0; i<labels.size(); i++)
00280       if(N.contains(labels[i])) NAND += labels[i];
00281    *this = NAND;
00282    return *this;
00283 }
00284 catch(Exception& e) { GPSTK_RETHROW(e); }
00285 }
00286 
00287 // replace this with (this | input) (OR - merge - superset)
00288 // NB new elements must be added at the end (for class SRI).
00289 Namelist& Namelist::operator|=(const Namelist& N)
00290 {
00291 try {
00292    Namelist NOR(*this);
00293    for(unsigned int i=0; i<N.labels.size(); i++)
00294       if(!(this->contains(N.labels[i]))) NOR += N.labels[i];
00295    *this = NOR;
00296    return *this;
00297 }
00298 catch(Exception& e) { GPSTK_RETHROW(e); }
00299 }
00300 
00301 // replace this with (this ^ input) (XOR - not common)
00302 Namelist& Namelist::operator^=(const Namelist& N)
00303 {
00304 try {
00305    unsigned int i;
00306    Namelist NXOR;
00307    for(i=0; i<labels.size(); i++)
00308       if(!(N.contains(labels[i]))) NXOR += labels[i];
00309    for(i=0; i<N.labels.size(); i++)
00310       if(!(this->contains(N.labels[i]))) NXOR += N.labels[i];
00311    *this = NXOR;
00312    return *this;
00313 }
00314 catch(Exception& e) { GPSTK_RETHROW(e); }
00315 }
00316 
00317 
00318 // access to a specific name, given its index; may be used as lvalue.
00319 //string& Namelist::operator[](const unsigned int in)
00320 //{
00321 //   if(in >= labels.size()) throw ...
00322 //   return labels[in];
00323 //}
00324 
00325 // access to a specific name, given its index.
00326 // returns 'out-of-range' if the index is out of range.
00327 string Namelist::getName(const unsigned int in) const
00328 {
00329 try {
00330    if(in >= labels.size()) return string("out-of-range");
00331    return labels[in];
00332 }
00333 catch(Exception& e) { GPSTK_RETHROW(e); }
00334 }
00335 
00336 // assign a specific name, given its index;
00337 // no effect if the index is out of range or the name is not unique.
00338 // return true if successful
00339 bool Namelist::setName(const unsigned int in, const string& name)
00340 {
00341 try {
00342    if(in >= labels.size()) return false;
00343    if(labels[in] == name) return true;    // NB b/c contains(name) would be true..
00344    if(contains(name)) return false;
00345    labels[in] = name;
00346    return true;
00347 }
00348 catch(Exception& e) { GPSTK_RETHROW(e); }
00349 }
00350 
00351 // return the index of the name in the list that matches the input, -1 if not found.
00352 int Namelist::index(const string& name) const
00353 {
00354 try {
00355    for(unsigned int i=0; i<labels.size(); i++)
00356       if(labels[i] == name) return i;
00357    return -1;
00358 }
00359 catch(Exception& e) { GPSTK_RETHROW(e); }
00360 }
00361 
00362 // output operator
00363 ostream& operator<<(ostream& os, const Namelist& N)
00364 {
00365 try {
00366    if(N.labels.size() > 0) {
00367       for(unsigned int i=0; i<N.labels.size(); i++)
00368          os << " / " << N.labels[i];
00369       os << " / ";
00370    }
00371    return os;
00372 }
00373 catch(Exception& e) { GPSTK_RETHROW(e); }
00374 }
00375 
00376 ostream& operator<<(ostream& os, const LabelledVector& nlp)
00377 {
00378 try {
00379    int i;
00380    string s;
00381    //ofstream savefmt; 
00382    //savefmt.copyfmt(os);
00383    //int wid=os.width(),prec=os.precision();
00384 
00385    // print message or blanks
00386    os << nlp.tag << " ";
00387    if(nlp.msg.size() > 0)
00388       s = nlp.msg; //s = leftJustify(nlp.msg,nlp.wid);
00389    else
00390       s = rightJustify(string(""),nlp.msg.size()); //nlp.wid);
00391    os << s << " ";
00392 
00393    // print each label
00394    for(i=0; i<nlp.NL.size(); i++) {
00395       if(nlp.NL.getName(i).size() > nlp.wid)
00396          s = leftJustify(nlp.NL.getName(i),nlp.wid);
00397       else
00398          s = rightJustify(nlp.NL.getName(i),nlp.wid);
00399       os << s;
00400       if(i-nlp.NL.size()+1) os << " ";
00401    }
00402    os << endl;       // next line
00403 
00404    // print same space as with labels
00405    s = rightJustify(string(""),nlp.msg.size()); //nlp.wid);
00406    os << nlp.tag << " " << s << " ";
00407    if(nlp.form == 1) os << fixed;
00408    if(nlp.form == 2) os << scientific;
00409    for(i=0; i<nlp.V.size(); i++) {
00410       //os.copyfmt(savefmt);
00411       //os << nlp.V(i);
00412       os << setw(nlp.wid) << setprecision(nlp.prec) << nlp.V(i);
00413       if(i-nlp.V.size()+1) os << " ";
00414    }
00415 
00416    return os;
00417 }
00418 catch(Exception& e) { GPSTK_RETHROW(e); }
00419 }
00420 
00421 ostream& operator<<(ostream& os, const LabelledMatrix& nlp)
00422 {
00423 try {
00424    int i,j,n,nspace;
00425    string s;
00426    const Namelist *pNLcol = &nlp.NLcols;
00427    const Namelist *pNLrow = &nlp.NLrows;
00428 
00429       // first make sure we have both namelists
00430    if(nlp.NLrows.size() == 0 && nlp.NLcols.size() == 0) {
00431       os << " Error -- Namelists in LabelledMatrix are empty! ";
00432       return os;
00433    }
00434    if(nlp.NLrows.size() == 0) pNLrow = pNLcol;
00435    if(nlp.NLcols.size() == 0) pNLcol = pNLrow;
00436 
00437       // on column labels line
00438    os << setw(0);
00439    if(nlp.rc == 0) {    // only if printing both column and row labels
00440       os << nlp.tag << " ";                                       // tag
00441       if(nlp.msg.size() > 0)                                      // msg
00442          s = nlp.msg;
00443       else
00444          s = rightJustify(string(""),nlp.wid);
00445       os << s << " ";
00446       if(nlp.msg.size() > 0 && nlp.msg.size() < nlp.wid)
00447          os << rightJustify(string(""),nlp.wid-nlp.msg.size());   // space
00448    }
00449       // print column labels
00450    if(nlp.rc != 1) { // but not if 'rows only'
00451       n = (nlp.M.cols() < pNLcol->size() ? nlp.M.cols() : pNLcol->size());
00452       for(i=0; i<n; i++) {
00453          if(pNLcol->getName(i).size() > nlp.wid)
00454             s = leftJustify(pNLcol->getName(i),nlp.wid);
00455          else
00456             s = rightJustify(pNLcol->getName(i),nlp.wid);
00457          os << s;                                                 // label
00458          if(i-n+1) os << " ";
00459       }
00460       os << endl;
00461    }
00462 
00463    if(nlp.form == 1) os << fixed;
00464    if(nlp.form == 2) os << scientific;
00465 
00466    if(nlp.msg.size() > nlp.wid) nspace = nlp.msg.size()-nlp.wid;
00467    else nspace = 0;
00468 
00469       // print one row per line
00470    for(i=0; i<nlp.M.rows(); i++) {
00471       os << nlp.tag << " ";                                       // tag
00472       if(nspace) os << rightJustify(string(""),nspace);           // space
00473          // print row labels
00474       if(nlp.rc != 2) { // but not if 'columns only'
00475          if(pNLrow->getName(i).size() > nlp.wid)
00476             s = leftJustify(pNLrow->getName(i),nlp.wid);
00477          else
00478             s = rightJustify(pNLrow->getName(i),nlp.wid);
00479          os << s << " ";                                          // label
00480       }
00481          // finally, print the data
00482       for(j=0; j<nlp.M.cols(); j++) {
00483          os << setw(nlp.wid) << setprecision(nlp.prec) << nlp.M(i,j);
00484          if(j-nlp.M.cols()+1) os << " ";                          // data
00485       }
00486       if(i<nlp.M.rows()-1) os << endl;
00487    }
00488 
00489    return os;
00490 }
00491 catch(Exception& e) { GPSTK_RETHROW(e); }
00492 }
00493 
00494 } // end namespace gpstk
00495 
00496 //------------------------------------------------------------------------------------
00497 //------------------------------------------------------------------------------------

Generated on Wed Feb 8 03:31:01 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1