//------------------------------------------------------------------------------------ // 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); } }
// -------------------------------------------------------------------------------- // 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); } }