Example #1
0
// are two Namelists identical, ignoring a permutation?
bool operator==(const Namelist& N1, const Namelist& N2)
{
try {
   if(N1.size() != N2.size()) return false;
   if(N1.size() == 0) return true;
   for(unsigned int i=0; i<N1.size(); i++) {
      unsigned int match=0;
      for(unsigned int j=0; j<N2.size(); j++)
         if(N1.labels[i] == N2.labels[j]) match++;
      if(match != 1) return false;     // if > 1, N2 is invalid
   }
   return true;
}
catch(Exception& e) { GPSTK_RETHROW(e); }
}
Example #2
0
File: SRI.cpp Project: SGL-UT/GPSTk
 // --------------------------------------------------------------------------------
 // explicit constructor - throw if the dimensions are inconsistent.
 SRI::SRI(const Matrix<double>& r,
          const Vector<double>& z,
          const Namelist& nl)
    throw(MatrixException)
 {
    if(r.rows() != r.cols() || r.rows() != z.size() || r.rows() != nl.size()) {
       MatrixException me("Invalid dimensions in explicit SRI constructor:\n R is "
             + asString<int>(r.rows()) + "x"
             + asString<int>(r.cols()) + ", Z has length "
             + asString<int>(z.size()) + " and NL has length "
             + asString<int>(nl.size())
             );
       GPSTK_THROW(me);
    }
    if(r.rows() <= 0) return;
    R = r;
    Z = z;
    names = nl;
 }
Example #3
0
//------------------------------------------------------------------------------------
// explicit constructor - throw if the dimensions are inconsistent.
SRIleastSquares::SRIleastSquares(const Matrix<double>& Rin,
                     const Vector<double>& Zin,
                     const Namelist& NLin)
   throw(MatrixException)
{
   defaults();
   if(Rin.rows() != Rin.cols() ||
      Rin.rows() != Zin.size() ||
      Rin.rows() != NLin.size()) {
      MatrixException me("Invalid input dimensions: R is "
         + asString<int>(Rin.rows()) + "x"
         + asString<int>(Rin.cols()) + ", Z has length "
         + asString<int>(Zin.size()) + ", and NL has length "
         + asString<int>(NLin.size())
         );
      GPSTK_THROW(me);
   }
   R = Rin;
   Z = Zin;
   names = NLin;
}
Example #4
0
File: SRI.cpp Project: SGL-UT/GPSTk
   // --------------------------------------------------------------------------------
   // Split this SRI (call it S) into two others, S1 and Sleft, where S1 has
   // a Namelist identical to the input Namelist (NL); set *this = S1 at the
   // end. NL must be a non-empty subset of names, and (names ^ NL) also must
   // be non-empty; throw MatrixException if this is not true. The second
   // output SRI, Sleft, will have the same names as S, but perhaps permuted.
   //
   // The routine works by first permuting S so that its Namelist if of the
   // form {N2,NL}, where N2 = (names ^ NL); this is possible only if NL is
   // a non-trivial subset of names. Then, the rows of S (rows of R and elements
   // of Z) naturally separate into the two component SRIs, with zeros in the
   // elements of the first SRI which correspond to N2, and those in Sleft
   // which correspond to NL.
   //
   //    Example:    S.name = A B C D E F G and NL = D E F G.
   // (Obviously, S may be permuted into such an order whenever this is needed.)
   // Note that here the R,Z pair is written in a format reminiscent of the
   // set of equations implied by R*X=Z, i.e. 1A+2B+3C+4D+5E+6F+7G=a, etc.
   //
   //          S (R Z)       =         S1            +         Sleft
   // with    names                       NL                  names
   //     A B C D E F G           . . . D E F G           A B C D E F G   
   //     - - - - - - -  -        - - - - - - -  -        - - - - - - -  -
   //     1 2 3 4 5 6 7  a   =    . . . . . . .  .   +    1 2 3 4 5 6 7  a
   //       8 9 1 2 3 4  b          . . . . . .  .          8 9 1 2 3 4  b
   //         5 6 7 8 9  c            . . . . .  .            5 6 7 8 9  c
   //           1 2 3 4  d              1 2 3 4  d              . . . .  d
   //             5 6 7  e                5 6 7  e                . . .  e
   //               8 9  f                  8 9  f                  . .  f
   //                 1  g                    1  g                    .  g
   //
   // where "." denotes a zero.  The split is simply separating the linear
   // equations which make up R*X=Z into two groups; because of the ordering,
   // one of the groups of equations (S1) depends only on a particular subset
   // of the elements of the state vector, i.e. the elements labelled by the
   // Namelist NL.
   //
   // The equation shown here is an information equation; if the two SRIs S1
   // and Sleft were merged again, none of the information would be lost.
   // Note that S1 has no dependence on A B C (hence the .'s), and therefore
   // its size can be reduced. However S2 still depends on the full names
   // Namelist. Sleft is necessarily singular, but S1 is not.
   //
   // Note that the SRI contains information about both the solution and
   // the covariance, i.e. state and noise, and therefore one must be very careful
   // in interpreting the results of split and merge (operator+=). [Be especially
   // careful about the idea that a merge might be reversible with a split() or
   // vice-versa - strictly this is never possible unless the Namelists are
   // mutually exclusive - two separate problems.]
   //
   // For example, suppose two different SRI's, which have some elements in common,
   // are merged. The combined SRI will have more information (it can't have less)
   // about the common elements, and therefore the solution will be 'better'
   // (assuming the underlying model equations for those elements are identical).
   // However the noises will also be combined, and the results you get might be
   // surprising. Also, note that if you then split the combined SRI again, the
   // solution won't change but the noises will be very different; in particular
   // the new split part will take all the information with it, so the common states
   // will have lower noise than they did in the original SRI.
   // See the test program tsri.cpp
   //
   void SRI::split(const Namelist& NL, SRI& Sleft)
      throw(MatrixException,VectorException)
   {
      try {
         Sleft = SRI(0);
         unsigned int n,m;
         n = NL.size();
         m = names.size();
         if(n >= m) {
            MatrixException me("split: Input Namelist must be a subset of this one");
            GPSTK_THROW(me);
         }

         unsigned int i,j;
            // copy names and permute it so that its end matches NL 
         Namelist N0(names);
         for(i=1; i<=n; i++) {           // loop (backwards) over names in NL
            for(j=1; j<=m; j++) {        // search (backwards) in NO for a match
               if(NL.labels[n-i] == N0.labels[m-j]) {  // if found a match
                  N0.swap(m-i,m-j);      // then move matching name to end
                  break;                 // and go on to next name in NL
               }
            }
            if(j > m) {
               MatrixException me("split: Input Namelist is not non-trivial subset");
               GPSTK_THROW(me);
            }
         }

            // copy *this into Sleft, then do the permutation
         Sleft = *this;
         Sleft.permute(N0);

            // copy parts of Sleft into S1, and then zero out those parts of Sleft
         SRI S1(NL);
         S1.R = Matrix<double>(Sleft.R,m-n,m-n,n,n);
         //S1.Z = Vector<double>(Sleft.Z,m-n,n);
         S1.Z.resize(n);
         for(i=0; i<n; i++) S1.Z(i) = Sleft.Z(m-n+i);
         for(i=m-n; i<m; i++) Sleft.zeroOne(i);

         *this = S1;
      }
      catch(MatrixException& me) {
         GPSTK_RETHROW(me);
      }
      catch(VectorException& ve) {
         GPSTK_RETHROW(ve);
      }
   }
Example #5
0
File: SRI.cpp Project: SGL-UT/GPSTk
   // ---------------------------------------------------------------------------
   // modify SRIs
   // --------------------------------------------------------------------------------
   // Permute the SRI elements to match the input Namelist, which may differ with
   // the SRI Namelist by AT MOST A PERMUTATION, throw if this is not true.
   void SRI::permute(const Namelist& nl)
      throw(MatrixException,VectorException)
   {
      if(identical(names,nl)) return;
      if(names != nl) {
         MatrixException me("Invalid input: Namelists must be == to permute");
         GPSTK_THROW(me);
      }

      try {
         unsigned int i,j;
         // build a permutation matrix
         Matrix<double> P(R.rows(),R.rows(),0.0);
         for(i=0; i<R.rows(); i++) {
            j = nl.index(names.getName(i));
            P(j,i) = 1;
         }

         Matrix<double> B;
         Vector<double> Q;
         B = P * R * transpose(P);
         Q = P * Z;

         // re-triangularize
         R = 0.0;
         Z = 0.0;
         SrifMU(R,Z,B,Q);
         names = nl;
      }
      catch(MatrixException& me) {
         GPSTK_RETHROW(me);
      }
      catch(VectorException& ve) {
         GPSTK_RETHROW(ve);
      }
   }
Example #6
0
//------------------------------------------------------------------------------------
// called by Estimation() - inside the data loop, inside the iteration loop
// Input is Namelist DNL, the double difference data Namelist (DataNL)
// Output is MCov, the measurement covariance matrix for this data (MeasCov).
// Let:
//  d = vector of one-way data (one site, one satellite)
// sd = vector of single difference data (two sites, one satellite)
// dd = vector of double difference data (two sites, two satellites)
// DD and SD are matricies with elements 0,1,-1 which transform d to sd to dd:
// sd = SD * d
// dd = DD * sd
// dd = DD * SD * d
// The covariance matrix will be MC = (DD*SD)*transpose(DD*SD)
//                                  = DD*SD*transpose(SD)*transpose(DD)
// If the one-way data has a measurement covariance, then fill the vector d with
// them; then MC = DD*SD* d * transpose(SD)*transpose(DD).
// Building DD and SD is just a matter of lists:
// loop through the dd namelist, keeping lists of:
// one-way data (site-satellite pairs) (d)
// single differences (site-site-satellite sets) (sd)
// and you have a list of double differences (DNL)
//
void BuildStochasticModel(int count, Namelist& DNL, Matrix<double>& MCov)
   throw(Exception)
{
try {
   unsigned int m=DNL.size();
   if(m==0) return;

   int i,j,in,jn,kn;
   string site1,site2;
   GSatID sat1,sat2;
   vector<double> d;    // weights of one-way data
   vector<OWid> ld;     // labels of d
   vector<SDid> sd;

   for(i=0; i<DNL.size(); i++) {
      // break the label into site1,site2,sat1,sat2
      DecomposeName(DNL.getName(i), site1, site2, sat1, sat2);
      if(index(ld,OWid(site1,sat1)) == -1) ld.push_back(OWid(site1,sat1));
      if(index(ld,OWid(site1,sat2)) == -1) ld.push_back(OWid(site1,sat2));
      if(index(ld,OWid(site2,sat1)) == -1) ld.push_back(OWid(site2,sat1));
      if(index(ld,OWid(site2,sat2)) == -1) ld.push_back(OWid(site2,sat2));
      if(index(sd,SDid(site1,site2,sat1)) == -1) sd.push_back(SDid(site1,site2,sat1));
      if(index(sd,SDid(site1,site2,sat2)) == -1) sd.push_back(SDid(site1,site2,sat2));
   }

      // fill d with the weights
   d = vector<double>(ld.size());
   for(i=0; i<ld.size(); i++) d[i] = StochasticWeight(ld[i], count);

   // temp
   //format f113s(11,3,2);
   //oflog << "DDs are (" << DNL.size() << "):\n" << setw(20) << DNL << endl;
   //oflog << "SDs are: (" << sd.size() << ")" << fixed << endl;
   //for(i=0; i<sd.size(); i++) oflog << " / " << sd[i];
   //oflog << endl;
   //oflog << "OWs are: (" << ld.size() << ")" << endl;
   //for(i=0; i<ld.size(); i++) oflog << " / " << ld[i];
   //oflog << endl;
   //oflog << "OW wts are: (" << d.size() << ")" << endl;
   //for(i=0; i<d.size(); i++) oflog << " " << f113s << d[i];
   //oflog << endl;

   Matrix<double> SD(sd.size(),ld.size(),0.0);
   Matrix<double> DD(m,sd.size(),0.0);
   // TD need to account for signs here ... sd[.] may be site2,site1,sat1 ...
   for(in=0; in<DNL.size(); in++) {
      DecomposeName(DNL.getName(in), site1, site2, sat1, sat2);
      jn = index(sd,SDid(site1,site2,sat1));        // site1-site2, sat1
      DD(in,jn) = 1;
      kn = index(ld,OWid(site1,sat1));              // site1, sat1
      SD(jn,kn) = d[kn];
      kn = index(ld,OWid(site2,sat1));              // site2, sat1
      SD(jn,kn) = -d[kn];

      jn = index(sd,SDid(site1,site2,sat2));        // site1-site2, sat2
      DD(in,jn) = -1;
      kn = index(ld,OWid(site1,sat2));              // site1, sat2
      SD(jn,kn) = d[kn];
      kn = index(ld,OWid(site2,sat2));              // site2, sat2
      SD(jn,kn) = -d[kn];
   }

   //oflog << " SD is\n" << fixed << setw(3) << SD << endl;
   //oflog << " DD is\n" << fixed << setw(3) << DD << endl;

   Matrix<double> T;
   T = DD * SD;
   MCov = T * transpose(T);

   static bool once=true;
   if(once) {
      oflog << "Measurement covariance (model " << CI.StochasticModel << ") is\n"
      << scientific << setw(8) << setprecision(3) << MCov << endl;
      once = false;
   }

}
catch(Exception& e) { GPSTK_RETHROW(e); }
catch(exception& e) { Exception E("std except: "+string(e.what())); GPSTK_THROW(E); }
catch(...) { Exception e("Unknown exception"); GPSTK_THROW(e); }
}
Example #7
0
File: SRI.cpp Project: SGL-UT/GPSTk
   // --------------------------------------------------------------------------------
   // Vector version of stateFix with several states given in a Namelist.
   void SRI::stateFix(const Namelist& dropNL, const Vector<double>& values_in)
      throw(MatrixException,VectorException)
   {
      try {
         if(dropNL.size() != values_in.size()) {
            VectorException e("Input has inconsistent lengths");
            GPSTK_THROW(e);
         }
/*
         // build a vector of indexes to keep
         int i,j;
         vector<int> indexes;
         for(i=0; i<names.size(); i++) {
            j = dropNL.index(names.getName(i)); // index in dropNL, this state
            if(j == -1) indexes.push_back(i);// not found in dropNL, so keep
         }

         const int n=indexes.size();         // new dimension
         if(n == 0) {
            Exception e("Cannot drop all states");
            GPSTK_THROW(e);
         }

         Vector<double> X,newX(n);
         Matrix<double> C,newC(n,n);
         Namelist newNL;

         double big,small;
         getStateAndCovariance(X,C,&small,&big);

         for(i=0; i<n; i++) {
            newX(i) = X(indexes[i]);
            for(j=0; j<n; j++) newC(i,j) = C(indexes[i],indexes[j]);
            newNL += names.getName(indexes[i]);
         }

         R = Matrix<double>(inverseUT(upperCholesky(newC)));
         Z = Vector<double>(R*newX);
         names = newNL;
*/
         size_t i,j,k;
            // create a vector of indexes and corresponding values
         vector<int> indx;
         vector<double> value;
         for(i=0; i<dropNL.size(); i++) {
            int in = names.index(dropNL.getName(i));   // in must be allowed to be -1
            if(in > -1) {
               indx.push_back(in);
               value.push_back(values_in(i));
            }
            //else nothing happens
         }
         const unsigned int m = indx.size();
         const unsigned int n = R.rows();
         if(m == 0) return;
         if(m == n) {
            *this = SRI(0);
            return;
         }
            // move the X(in) terms to the data vector on the RHS
         for(k=0; k<m; k++)
            for(i=0; i<indx[k]; i++)
               Z(i) -= R(i,indx[k])*value[k];

            // first remove the rows in indx
         bool skip;
         Vector<double> Ztmp(n-m,0.0);
         Matrix<double> Rtmp(n-m,n,0.0);
         for(i=0,k=0; i<n; i++) {
            skip = false;
            for(j=0; j<m; j++) if((int)i == indx[j]) { skip=true; break; }
            if(skip) continue;      // skip row to be dropped

            Ztmp(k) = Z(i);
            for(j=i; j<n; j++) Rtmp(k,j) = R(i,j);
            k++;
         }

            // Z is now done
         Z = Ztmp;

            // now remove columns in indx
         R = Matrix<double>(n-m,n-m,0.0);
         for(j=0,k=0; j<n; j++) {
            skip = false;
            for(i=0; i<m; i++) if((int)j == indx[i]) { skip=true; break; }
            if(skip) continue;      // skip col to be dropped

            for(i=0; i<=j; i++) R(i,k) = Rtmp(i,j);
            k++;
         }

            // remove the names
         for(k=0; k<dropNL.size(); k++) {
            std::string name(dropNL.getName(k));
            names -= name;
         }
      }
      catch(MatrixException& me) {
         GPSTK_RETHROW(me);
      }
      catch(VectorException& ve) {
         GPSTK_RETHROW(ve);
      }
   }
Example #8
0
//------------------------------------------------------------------------------------
// Read all the files on the command line, they should contain covariance and state
// with labels. Merge all these SRIs and output the final covariance and state.
int main(int argc, char **argv)
{
   try {
      bool verbose=false;
      int i,n,N,nfile,nline,nword;
      string line,word;
      Matrix<double> cov;
      Vector<double> state;
      Namelist name;
      SRI S;

      if(argc <= 1) {
         cout << "Prgm mergeSRI combines solution and covariance results from "
              << "different sources\n   into a single result. Each file named on the "
              << "command line consists of lines,\n   one per row of the covariance "
              << "matrix, of the form\n      label(i) cov(i,0) cov(i,1) ... cov(i,n) "
              << "solution(i)\n   where there are n lines in the file (i.e. the "
              << "covariance matrix is square)\n   and labels are used consistently "
              << "among all the results in all the files.\n   Results are output as "
              << "a single combined namelist, covariance and solution.\n";
         return 0;
      }

      nfile = 0;
      for(i=1; i<argc; i++) {
         if(string(argv[i]) == string("-v") ||
            string(argv[i]) == string("--verbose")) {
            verbose = true;
            continue;
         }

         ifstream ifs(argv[i]);
         if(!ifs) {
            cout << "Could not open file " << argv[i] << endl;
            continue;
         }
         if(verbose) cout << "Opened file " << argv[i] << endl;

         // read the file
         N = nline = 0;            // N is the dimension of cov and state and name
         while(!ifs.eof() && ifs.good()) {
            getline(ifs,line);
            StringUtils::stripTrailing(line,'\r');
            if(ifs.bad()) break;
            StringUtils::stripLeading(line);
            if(line.empty()) break;
            n = StringUtils::numWords(line);
            if(N == 0) {
               N = n-2;
               cov = Matrix<double>(N,N,0.0);
               state = Vector<double>(N,0.0);
               name.clear();
            }
            else if(n-2 != N) {
               cerr << "Warning - dimensions are wrong in file " << argv[i]
                  << " : " << n-2 << " != " << N << endl;
            }
            nword = 0;
            while(1) {
               word = StringUtils::stripFirstWord(line);
               if(word.empty()) break;
               if(nword == 0) {
                  name += word;
               }
               else if(nword < N+1) {
                  cov(nline,nword-1) = StringUtils::asDouble(word);
               }
               else if(nword == N+1) {
                  state(nline) = StringUtils::asDouble(word);
               }
               nword++;
            };
            nline++;
            if(nline > N) break;
         }
         ifs.close();

         if(N <= 0 || name.size() <= 0) {
            cout << "Empty file - ignore : " << argv[i] << endl;
            continue;
         }

         name.resize(N);
         cout << "Add file " << argv[i] << " : state names " << name << endl;
         if(verbose) {
            LabeledVector Lstate(name,state);
            Lstate.fixed().setw(16).setprecision(6);
            cout << "State" << endl << Lstate << endl;
            LabeledMatrix Lcov(name,cov);
            Lcov.scientific().setw(16).setprecision(6);
            cout << "Covariance" << endl << Lcov << endl;
         }

         SRI S1(name);
         S1.addAPriori(cov,state);
         S += S1;

         nfile++;
      }

      if(nfile <= 0) {
         cout << "No files!\n";
         return 0;
      }

      double small,big;
      S.getStateAndCovariance(state,cov,&small,&big);
      cout << endl;
      LabeledVector Ls(name,state);
      Ls.fixed().setw(16).setprecision(6);
      cout << "Final state" << endl << Ls << endl;
      LabeledMatrix Lc(name,cov);
      Lc.scientific().setw(16).setprecision(6);
      cout << endl << "Final covariance" << endl << Lc << endl;
   }
   catch(MatrixException& me) {
      cerr << "Exception: " << me << endl;
      return -1;
   }
   return 0;
}