SolverGeneral.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: SolverGeneral.cpp 2877 2011-08-20 08:40:11Z yanweignss $"
00002 
00008 //============================================================================
00009 //
00010 //  This file is part of GPSTk, the GPS Toolkit.
00011 //
00012 //  The GPSTk is free software; you can redistribute it and/or modify
00013 //  it under the terms of the GNU Lesser General Public License as published
00014 //  by the Free Software Foundation; either version 2.1 of the License, or
00015 //  any later version.
00016 //
00017 //  The GPSTk is distributed in the hope that it will be useful,
00018 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //  GNU Lesser General Public License for more details.
00021 //
00022 //  You should have received a copy of the GNU Lesser General Public
00023 //  License along with GPSTk; if not, write to the Free Software Foundation,
00024 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 //
00026 //  Dagoberto Salazar - gAGE ( http://www.gage.es ). 2009
00027 //
00028 //============================================================================
00029 
00030 
00031 #include "SolverGeneral.hpp"
00032 #include "GeneralConstraint.hpp"
00033 
00034 namespace gpstk
00035 {
00036 
00037       // Index initially assigned to this class
00038    int SolverGeneral::classIndex = 9600000;
00039 
00040 
00041       // Returns an index identifying this object.
00042    int SolverGeneral::getIndex() const
00043    { return index; }
00044 
00045 
00046       // Returns a string identifying this object.
00047    std::string SolverGeneral::getClassName() const
00048    { return "SolverGeneral"; }
00049 
00050 
00051 
00052       /* Explicit constructor.
00053        *
00054        * @param equationList  List of objects describing the equations
00055        *                      to be solved.
00056        */
00057    SolverGeneral::SolverGeneral( const std::list<Equation>& equationList )
00058       : firstTime(true)
00059    {
00060 
00061          // Visit each "Equation" in 'equationList' and add them to 'equSystem'
00062       for( std::list<Equation>::const_iterator itEq = equationList.begin();
00063            itEq != equationList.end();
00064            ++itEq )
00065       {
00066          equSystem.addEquation( (*itEq) );
00067       }
00068 
00069    }  // End of constructor 'SolverGeneral::SolverGeneral()'
00070 
00071 
00072       /* Returns a reference to a gnnsSatTypeValue object after
00073        * solving the previously defined equation system.
00074        *
00075        * @param gData    Data object holding the data.
00076        */
00077    gnssSatTypeValue& SolverGeneral::Process(gnssSatTypeValue& gData)
00078       throw(ProcessingException)
00079    {
00080 
00081       try
00082       {
00083 
00084             // Build a gnssRinex object and fill it with data
00085          gnssRinex g1;
00086          g1.header = gData.header;
00087          g1.body = gData.body;
00088 
00089             // Call the Process() method with the appropriate input object
00090          Process(g1);
00091 
00092             // Update the original gnssSatTypeValue object with the results
00093          gData.body = g1.body;
00094 
00095          return gData;
00096 
00097       }
00098       catch(Exception& u)
00099       {
00100             // Throw an exception if something unexpected happens
00101          ProcessingException e( getClassName() + ":"
00102                                 + StringUtils::asString( getIndex() ) + ":"
00103                                 + u.what() );
00104 
00105          GPSTK_THROW(e);
00106 
00107       }
00108 
00109    }  // End of method 'SolverGeneral::Process()'
00110 
00111 
00112 
00113       /* Returns a reference to a gnnsRinex object after solving
00114        * the previously defined equation system.
00115        *
00116        * @param gData     Data object holding the data.
00117        */
00118    gnssRinex& SolverGeneral::Process(gnssRinex& gData)
00119       throw(ProcessingException)
00120    {
00121 
00122       try
00123       {
00124 
00125             // Build a gnssDataMap object and fill it with data
00126          gnssDataMap gdsMap;
00127          SourceID source( gData.header.source );
00128          gdsMap.addGnssRinex( gData );
00129 
00130             // Call the Process() method with the appropriate input object,
00131             // and update the original gnssRinex object with the results
00132          Process(gdsMap);
00133          gData = gdsMap.getGnssRinex( source );
00134 
00135          return gData;
00136 
00137       }
00138       catch(Exception& u)
00139       {
00140             // Throw an exception if something unexpected happens
00141          ProcessingException e( getClassName() + ":"
00142                                 + StringUtils::asString( getIndex() ) + ":"
00143                                 + u.what() );
00144 
00145          GPSTK_THROW(e);
00146 
00147       }
00148 
00149    }  // End of method 'SolverGeneral::Process()'
00150 
00151 
00152 
00153       /* Returns a reference to a gnssDataMap object after solving
00154        *  the previously defined equation system.
00155        *
00156        * @param gData    Data object holding the data.
00157        */
00158    gnssDataMap& SolverGeneral::Process( gnssDataMap& gdsMap )
00159       throw(ProcessingException)
00160    {
00161 
00162       try
00163       {
00164 
00165             // Prepare everything before computing
00166          preCompute(gdsMap);
00167 
00168 
00169             // Call the Compute() method with the defined equation model.
00170             // This equation model MUST HAS BEEN previously set, usually when
00171             // creating the SolverPPP object with the appropriate
00172             // constructor.
00173          Compute( measVector,
00174                   hMatrix,
00175                   rMatrix );
00176 
00177 
00178             // Store data after computing
00179          postCompute(gdsMap);
00180 
00181 
00182       }
00183       catch(Exception& u)
00184       {
00185             // Throw an exception if something unexpected happens
00186          ProcessingException e( getClassName() + ":"
00187                                 + StringUtils::asString( getIndex() ) + ":"
00188                                 + u.what() );
00189 
00190          GPSTK_THROW(e);
00191 
00192       }
00193 
00194       return gdsMap;
00195 
00196    }  // End of method 'SolverGeneral::Prepare()'
00197 
00198 
00199 
00200       /* Code to be executed before 'Compute()' method.
00201        *
00202        * @param gData    Data object holding the data.
00203        */
00204    gnssDataMap& SolverGeneral::preCompute( gnssDataMap& gdsMap )
00205       throw(ProcessingException)
00206    {
00207 
00208       try
00209       {
00210 
00211             // Prepare the equation system with current data
00212          equSystem.Prepare(gdsMap);
00213 
00214             // Get matrices and vectors out of equation system
00215             // Measurements vector (Prefit-residuals)
00216          measVector = equSystem.getPrefitsVector();
00217 
00218             // Geometry matrix
00219          hMatrix = equSystem.getGeometryMatrix();
00220 
00221             // Weights matrix
00222          rMatrix = equSystem.getWeightsMatrix();
00223 
00224             // State Transition Matrix (PhiMatrix)
00225          phiMatrix = equSystem.getPhiMatrix();
00226 
00227             // Noise covariance matrix (QMatrix)
00228          qMatrix = equSystem.getQMatrix();
00229 
00230 
00231             // Get the number of unknowns being processed
00232          int numUnknowns( equSystem.getTotalNumVariables() );
00233 
00234             // Get the set with unknowns being processed
00235          VariableSet unkSet( equSystem.getVarUnknowns() );
00236 
00237             // Feed the filter with the correct state and covariance matrix
00238          if(firstTime)
00239          {
00240 
00241             Vector<double> initialState(numUnknowns, 0.0);
00242             Matrix<double> initialErrorCovariance( numUnknowns,
00243                                                    numUnknowns,
00244                                                    0.0 );
00245 
00246                // Fill the initialErrorCovariance matrix
00247 
00248             int i(0);      // Set an index
00249 
00250             for( VariableSet::const_iterator itVar = unkSet.begin();
00251                  itVar != unkSet.end();
00252                  ++itVar )
00253             {
00254 
00255                initialErrorCovariance(i,i) = (*itVar).getInitialVariance();
00256                ++i;
00257             }
00258 
00259 
00260                // Reset Kalman filter
00261             kFilter.Reset( initialState, initialErrorCovariance );
00262 
00263                // No longer first time
00264             firstTime = false;
00265 
00266          }
00267          else
00268          {
00269                // Adapt the size to the current number of unknowns
00270             Vector<double> currentState(numUnknowns, 0.0);
00271             Matrix<double> currentErrorCov(numUnknowns, numUnknowns, 0.0);
00272 
00273 
00274                // Fill the state vector
00275 
00276             int i(0);      // Set an index
00277 
00278             for( VariableSet::const_iterator itVar = unkSet.begin();
00279                  itVar != unkSet.end();
00280                  ++itVar )
00281             {
00282 
00283                currentState(i) = stateMap[ (*itVar) ];
00284                ++i;
00285             }
00286 
00287 
00288                // Fill the covariance matrix
00289 
00290                // We need a copy of 'unkSet'
00291             VariableSet tempSet( unkSet );
00292 
00293             i = 0;         // Reset 'i' index
00294 
00295             for( VariableSet::const_iterator itVar1 = unkSet.begin();
00296                  itVar1 != unkSet.end();
00297                  ++itVar1 )
00298             {
00299 
00300                   // Fill the diagonal element
00301                currentErrorCov(i, i) = covarianceMap[ (*itVar1) ][ (*itVar1) ];
00302 
00303                int j(i+1);      // Set 'j' index
00304 
00305                   // Remove current Variable from 'tempSet'
00306                tempSet.erase( (*itVar1) );
00307 
00308                for( VariableSet::const_iterator itVar2 = tempSet.begin();
00309                     itVar2 != tempSet.end();
00310                     ++itVar2 )
00311                {
00312 
00313                      // Check if '(*itVar2)' belongs to 'covarianceMap'
00314                   if( covarianceMap.find( (*itVar2) ) != covarianceMap.end() )
00315                   {
00316                         // If it belongs, get element from 'covarianceMap'
00317                      currentErrorCov(i, j) =
00318                         currentErrorCov(j, i) =
00319                            covarianceMap[ (*itVar1) ][ (*itVar2) ];
00320                   }
00321                   else
00322                   {
00323                         // If it doesn't belong, ask for default covariance
00324                      currentErrorCov(i, j) =
00325                         currentErrorCov(j, i) = (*itVar2).getInitialVariance();
00326                   }
00327 
00328                   ++j;
00329                }
00330 
00331                ++i;
00332 
00333             }  // End of for( VariableSet::const_iterator itVar1 = unkSet...'
00334 
00335 
00336                // Reset Kalman filter to current state and covariance matrix
00337             kFilter.Reset( currentState, currentErrorCov );
00338 
00339          }  // End of 'if(firstTime)'
00340 
00341 
00342       }
00343       catch(Exception& u)
00344       {
00345             // Throw an exception if something unexpected happens
00346          ProcessingException e( getClassName() + ":"
00347                                 + StringUtils::asString( getIndex() ) + ":"
00348                                 + u.what() );
00349 
00350          GPSTK_THROW(e);
00351 
00352       }
00353 
00354       return gdsMap;
00355 
00356    }  // End of method 'SolverGeneral::preCompute()'
00357 
00358 
00359 
00360       // Compute the solution of the given equations set.
00361       //
00362       // @param prefitResiduals   Vector of prefit residuals
00363       // @param designMatrix      Design matrix for equation system
00364       // @param weightMatrix      Matrix of weights
00365       //
00366       // \warning A typical Kalman filter works with the measurements noise
00367       // covariance matrix, instead of the matrix of weights. Beware of this
00368       // detail, because this method uses the later.
00369       //
00370       // @return
00371       //  0 if OK
00372       //  -1 if problems arose
00373       //
00374    int SolverGeneral::Compute( const Vector<double>& prefitResiduals,
00375                                const Matrix<double>& designMatrix,
00376                                const Matrix<double>& weightMatrix )
00377       throw(InvalidSolver)
00378    {
00379 
00380          // By default, results are invalid
00381       valid = false;
00382 
00383       if (!(weightMatrix.isSquare()))
00384       {
00385          InvalidSolver e("Weight matrix is not square");
00386          GPSTK_THROW(e);
00387       }
00388 
00389       int wRow = static_cast<int>(weightMatrix.rows());
00390       int pRow = static_cast<int>(prefitResiduals.size());
00391       if (!(wRow==pRow))
00392       {
00393          InvalidSolver e("prefitResiduals size does not match dimension of \
00394 weightMatrix");
00395          GPSTK_THROW(e);
00396       }
00397 
00398       int gRow = static_cast<int>(designMatrix.rows());
00399       if (!(gRow==pRow))
00400       {
00401          InvalidSolver e("prefitResiduals size does not match dimension \
00402 of designMatrix");
00403          GPSTK_THROW(e);
00404       }
00405 
00406       if (!(phiMatrix.isSquare()))
00407       {
00408          InvalidSolver e("phiMatrix is not square");
00409          GPSTK_THROW(e);
00410       }
00411 
00412          // Get the number of unknowns being processed
00413       int numUnknowns( equSystem.getTotalNumVariables() );
00414 
00415       int phiRow = static_cast<int>(phiMatrix.rows());
00416       if (!(phiRow==numUnknowns))
00417       {
00418          InvalidSolver e("Number of unknowns does not match dimension \
00419 of phiMatrix");
00420          GPSTK_THROW(e);
00421       }
00422 
00423       if (!(qMatrix.isSquare()))
00424       {
00425          InvalidSolver e("qMatrix is not square");
00426          GPSTK_THROW(e);
00427       }
00428 
00429       int qRow = static_cast<int>(qMatrix.rows());
00430       if (!(qRow==numUnknowns))
00431       {
00432          InvalidSolver e("Number of unknowns does not match dimension \
00433 of qMatrix");
00434          GPSTK_THROW(e);
00435       }
00436 
00437          // After checking sizes, let's invert the matrix of weights in order
00438          // to get the measurements noise covariance matrix, which is what we
00439          // use in the "SimpleKalmanFilter" class
00440       Matrix<double> measNoiseMatrix;
00441 
00442       try
00443       {
00444          measNoiseMatrix = inverseChol(weightMatrix);
00445       }
00446       catch(...)
00447       {
00448          InvalidSolver e("Correct(): Unable to compute measurements noise \
00449 covariance matrix.");
00450          GPSTK_THROW(e);
00451       }
00452 
00453 
00454       try
00455       {
00456 
00457             // Call the Kalman filter object.
00458          kFilter.Compute( phiMatrix,
00459                           qMatrix,
00460                           prefitResiduals,
00461                           designMatrix,
00462                           measNoiseMatrix );
00463 
00464       }
00465       catch(InvalidSolver& e)
00466       {
00467          GPSTK_RETHROW(e);
00468       }
00469 
00470          // Store the solution
00471       solution = kFilter.xhat;
00472 
00473          // Store the covariance matrix of the solution
00474       covMatrix = kFilter.P;
00475 
00476          // Compute the postfit residuals Vector
00477       postfitResiduals = prefitResiduals - (designMatrix * solution);
00478 
00479          // If everything is fine so far, then the results should be valid
00480       valid = true;
00481 
00482       return 0;
00483 
00484    }  // End of method 'SolverGeneral::Compute()'
00485 
00486 
00487 
00488       /* Code to be executed after 'Compute()' method.
00489        *
00490        * @param gData    Data object holding the data.
00491        */
00492    gnssDataMap& SolverGeneral::postCompute( gnssDataMap& gdsMap )
00493       throw(ProcessingException)
00494    {
00495 
00496       try
00497       {
00498 
00499             // Clean up values in 'stateMap' and 'covarianceMap'
00500          stateMap.clear();
00501          covarianceMap.clear();
00502 
00503 
00504             // Get the set with unknowns being processed
00505          VariableSet unkSet( equSystem.getVarUnknowns() );
00506 
00507 
00508             // Store values of current state
00509 
00510          int i(0);      // Set an index
00511 
00512          for( VariableSet::const_iterator itVar = unkSet.begin();
00513               itVar != unkSet.end();
00514               ++itVar )
00515          {
00516 
00517             stateMap[ (*itVar) ] = solution(i);
00518             ++i;
00519          }
00520 
00521 
00522             // Store values of covariance matrix
00523 
00524             // We need a copy of 'unkSet'
00525          VariableSet tempSet( unkSet );
00526 
00527          i = 0;         // Reset 'i' index
00528 
00529          for( VariableSet::const_iterator itVar1 = unkSet.begin();
00530               itVar1 != unkSet.end();
00531               ++itVar1 )
00532          {
00533 
00534                // Fill the diagonal element
00535             covarianceMap[ (*itVar1) ][ (*itVar1) ] = covMatrix(i, i);
00536 
00537             int j(i+1);      // Set 'j' index
00538 
00539                // Remove current Variable from 'tempSet'
00540             tempSet.erase( (*itVar1) );
00541 
00542             for( VariableSet::const_iterator itVar2 = tempSet.begin();
00543                  itVar2 != tempSet.end();
00544                  ++itVar2 )
00545             {
00546 
00547                covarianceMap[ (*itVar1) ][ (*itVar2) ] = covMatrix(i, j);
00548 
00549                ++j;
00550             }
00551 
00552             ++i;
00553 
00554          }  // End of for( VariableSet::const_iterator itVar1 = unkSet...'
00555 
00556 
00557             // Store the postfit residuals in the GNSS Data Structure
00558 
00559             // We need the list of equations being processed
00560          std::list<Equation> equList( equSystem.getCurrentEquationsList() );
00561 
00562          i = 0;         // Reset 'i' index
00563 
00564             // Visit each equation in "equList"
00565          for( std::list<Equation>::const_iterator itEq = equList.begin();
00566               itEq != equList.end();
00567               ++itEq )
00568          {
00569 
00570                // Get the TypeID of the residuals. The original type by default.
00571             TypeID residualType( (*itEq).header.indTerm.getType() );
00572 
00573                // Prefits are treated different
00574             if( residualType == TypeID::prefitC )
00575             {
00576                residualType = TypeID::postfitC;
00577             }
00578             else
00579             {
00580                if( residualType == TypeID::prefitL )
00581                {
00582                   residualType = TypeID::postfitL;
00583                }
00584             }
00585 
00586             gdsMap.insertValue( (*itEq).header.equationSource,
00587                                 (*itEq).header.equationSat,
00588                                 residualType,
00589                                 postfitResiduals(i) );
00590 
00591             ++i;  // Increment counter
00592 
00593          }  // End of 'for( std::list<Equation>::const_iterator itEq = ...'
00594 
00595       }
00596       catch(Exception& u)
00597       {
00598             // Throw an exception if something unexpected happens
00599          ProcessingException e( getClassName() + ":"
00600                                 + StringUtils::asString( getIndex() ) + ":"
00601                                 + u.what() );
00602 
00603          GPSTK_THROW(e);
00604 
00605       }
00606 
00607       return gdsMap;
00608 
00609    }  // End of method 'SolverGeneral::postCompute()'
00610 
00611 
00612 
00613       /* Returns the solution associated to a given Variable.
00614        *
00615        * @param variable    Variable object solution we are looking for.
00616        */
00617    double SolverGeneral::getSolution( const Variable& variable ) const
00618       throw(InvalidRequest)
00619    {
00620 
00621          // Look the variable inside the state map
00622       VariableDataMap::const_iterator it( stateMap.find( variable ) );
00623 
00624          // Check if the provided Variable exists in the solution. If not,
00625          // an InvalidSolver exception will be issued.
00626       if( it == stateMap.end() )
00627       {
00628          InvalidRequest e("Variable not found in solution vector.");
00629          GPSTK_THROW(e);
00630       }
00631 
00632          // Return value
00633       return (*it).second;
00634 
00635    }  // End of method 'SolverGeneral::getSolution()'
00636 
00637 
00638 
00639       /* Returns the solution associated to a given TypeID.
00640        *
00641        * @param type    TypeID of the solution we are looking for.
00642        *
00643        * \warning In the case the solution contains more than one variable
00644        * of this type, only the first one will be returned.
00645        */
00646    double SolverGeneral::getSolution( const TypeID& type ) const
00647       throw(InvalidRequest)
00648    {
00649 
00650          // Declare an iterator for 'stateMap' and go to the first element
00651       VariableDataMap::const_iterator it = stateMap.begin();
00652 
00653          // Look for a variable with the same type
00654       while( (*it).first.getType() != type &&
00655              it != stateMap.end() )
00656       {
00657          ++it;
00658 
00659          // If the same type is not found, throw an exception
00660          if( it == stateMap.end() )
00661          {
00662              InvalidRequest e("Type not found in solution vector.");
00663              GPSTK_THROW(e);
00664          }
00665       }
00666 
00667          // Else, return the corresponding value
00668       return (*it).second;
00669 
00670    }  // End of method 'SolverGeneral::getSolution()'
00671 
00672 
00673 
00674       /* Returns the solution associated to a given TypeID and SourceID.
00675        *
00676        * @param type    TypeID of the solution we are looking for.
00677        * @param source  SourceID of the solution we are looking for.
00678        *
00679        * \warning In the case the solution contains more than one variable
00680        * of this type, only the first one will be returned.
00681        */
00682    double SolverGeneral::getSolution( const TypeID& type,
00683                                       const SourceID& source ) const
00684       throw(InvalidRequest)
00685    {
00686 
00687          // Declare an iterator for 'stateMap' and go to the first element
00688       VariableDataMap::const_iterator it = stateMap.begin();
00689 
00690          // Look for a variable with the same type and source
00691       while( !( (*it).first.getType()   == type &&
00692                 (*it).first.getSource() == source ) &&
00693              it != stateMap.end() )
00694       {
00695          ++it;
00696 
00697          // If it is not found, throw an exception
00698          if( it == stateMap.end() )
00699          {
00700              InvalidRequest e("Type and source not found in solution vector.");
00701              GPSTK_THROW(e);
00702          }
00703       }
00704 
00705          // Else, return the corresponding value
00706       return (*it).second;
00707 
00708    }  // End of method 'SolverGeneral::getSolution()'
00709 
00710 
00711       /* Returns the solution associated to a given TypeID, SourceID and
00712        *  SatID.
00713        *
00714        * @param type    TypeID of the solution we are looking for.
00715        * @param sat     SatID of the solution we are looking for.
00716        *
00717        * \warning In the case the solution contains more than one variable
00718        * of this type, only the first one will be returned.
00719        */
00720    double SolverGeneral::getSolution( const TypeID& type,
00721                                       const SatID& sat ) const
00722       throw(InvalidRequest)
00723    {
00724 
00725       // Declare an iterator for 'stateMap' and go to the first element
00726       VariableDataMap::const_iterator it = stateMap.begin();
00727 
00728       // Look for a variable with the same type and source
00729       while( !( (*it).first.getType()   == type &&
00730              (*it).first.getSatellite() == sat ) &&
00731              it != stateMap.end() )
00732       {
00733          ++it;
00734 
00735          // If it is not found, throw an exception
00736          if( it == stateMap.end() )
00737          {
00738             InvalidRequest e("Type and source not found in solution vector.");
00739             GPSTK_THROW(e);
00740          }
00741       }
00742 
00743       // Else, return the corresponding value
00744       return (*it).second;
00745 
00746    }  // End of method 'SolverGeneral::getSolution()'
00747 
00748 
00749       /* Returns the solution associated to a given TypeID, SourceID and
00750        * SatID.
00751        *
00752        * @param type    TypeID of the solution we are looking for.
00753        * @param source  SourceID of the solution we are looking for.
00754        * @param sat     SatID of the solution we are looking for.
00755        *
00756        * \warning In the case the solution contains more than one variable
00757        * of this type, only the first one will be returned.
00758        */
00759    double SolverGeneral::getSolution( const TypeID& type,
00760                                       const SourceID& source,
00761                                       const SatID& sat ) const
00762       throw(InvalidRequest)
00763    {
00764 
00765          // Declare an iterator for 'stateMap' and go to the first element
00766       VariableDataMap::const_iterator it = stateMap.begin();
00767 
00768          // Look for a variable with the same type, source and satellite
00769       while( !( (*it).first.getType()      == type    &&
00770                 (*it).first.getSource()    == source  &&
00771                 (*it).first.getSatellite() == sat        ) &&
00772              it != stateMap.end() )
00773       {
00774          ++it;
00775 
00776          // If it is not found, throw an exception
00777          if( it == stateMap.end() )
00778          {
00779              InvalidRequest e("Type, source and SV not found in solution vector.");
00780              GPSTK_THROW(e);
00781          }
00782       }
00783 
00784          // Else, return the corresponding value
00785       return (*it).second;
00786 
00787    }  // End of method 'SolverGeneral::getSolution()'
00788 
00789       /* Returns the covariance associated to a given Variable.
00790        *
00791        * @param var1    first variable object
00792        * @param var2    second variable object
00793        */
00794    double SolverGeneral::getCovariance( const Variable& var1, 
00795                                         const Variable& var2 ) const
00796       throw(InvalidRequest)
00797    {
00798       std::map<Variable, VariableDataMap >::const_iterator it1 = covarianceMap.find(var1);
00799       if(it1!=covarianceMap.end())
00800       {
00801          VariableDataMap::const_iterator it2 = it1->second.find(var2);
00802          if(it2!=it1->second.end())
00803          {
00804             return it2->second;
00805          }
00806          else
00807          {
00808             it1 = covarianceMap.find(var2);
00809             if(it1!=covarianceMap.end())
00810             {
00811                it2 = it1->second.find(var1);
00812                if(it2!=it1->second.end()) return it2->second;
00813             }
00814          }
00815       }
00816       
00817          // Once code go here, we failed to find the value, and throw exception.
00818       InvalidRequest e("Failed to get the covariance value.");
00819       GPSTK_THROW(e);
00820 
00821       return 0.0;
00822    }
00823 
00824 
00825       /* Returns the variance associated to a given Variable.
00826        *
00827        * @param variable    Variable object variance we are looking for.
00828        */
00829    double SolverGeneral::getVariance(const Variable& variable) const 
00830       throw(InvalidRequest)
00831    {
00832 
00833          // Check if the provided Variable exists in the solution. If not,
00834          // an InvalidSolver exception will be issued.
00835       if( stateMap.find( variable ) == stateMap.end() )
00836       {
00837          InvalidRequest e("Variable not found in covariance matrix.");
00838          GPSTK_THROW(e);
00839       }
00840 
00841          // Return value
00842       return getCovariance(variable,variable);
00843 
00844    }  // End of method 'SolverGeneral::getVariance()'
00845 
00846 
00847 
00848       /* Returns the variance associated to a given TypeID.
00849        *
00850        * @param type    TypeID of the variance we are looking for.
00851        *
00852        * \warning In the case the solution contains more than one variable
00853        * of this type, only the first one will be returned.
00854        */
00855    double SolverGeneral::getVariance(const TypeID& type) const 
00856       throw(InvalidRequest)
00857    {
00858 
00859          // Declare an iterator for 'covarianceMap' and go to the first element
00860       std::map<Variable, VariableDataMap >::const_iterator it
00861                                                       = covarianceMap.begin();
00862 
00863          // Look for a variable with the same type
00864       while( (*it).first.getType() != type &&
00865              it != covarianceMap.end() )
00866       {
00867          ++it;
00868 
00869          // If the same type is not found, throw an exception
00870          if( it == covarianceMap.end() )
00871          {
00872              InvalidRequest e("Type not found in covariance matrix.");
00873              GPSTK_THROW(e);
00874          }
00875       }
00876 
00877          // Else, return the corresponding value
00878       return getCovariance(it->first,it->first); 
00879 
00880    }  // End of method 'SolverGeneral::getVariance()'
00881 
00882 
00883       /* Returns the variance associated to a given TypeID.
00884        *
00885        * @param type    TypeID of the variance we are looking for.
00886        * @param source  SourceID of the solution we are looking for.
00887        * 
00888        * \warning In the case the solution contains more than one variable
00889        * of this type, only the first one will be returned.
00890        */
00891    double SolverGeneral::getVariance( const TypeID& type,
00892                                       const SourceID& source ) const 
00893       throw(InvalidRequest)
00894    {
00895          // Declare an iterator for 'stateMap' and go to the first element
00896       VariableDataMap::const_iterator it = stateMap.begin();
00897 
00898          // Look for a variable with the same type and source
00899       while( !( (*it).first.getType()   == type &&
00900          (*it).first.getSource() == source ) &&
00901          it != stateMap.end() )
00902       {
00903          ++it;
00904 
00905          // If it is not found, throw an exception
00906          if( it == stateMap.end() )
00907          {
00908             InvalidRequest e("Type and source not found in solution vector.");
00909             GPSTK_THROW(e);
00910          }
00911       }
00912 
00913          // Else, return the corresponding value
00914       return getCovariance(it->first,it->first);
00915 
00916    }  // End of method 'SolverGeneral::getVariance()'
00917 
00918 
00919       /* Returns the variance associated to a given TypeID.
00920        *
00921        * @param type    TypeID of the variance we are looking for.
00922        * @param source  SourceID of the solution we are looking for.
00923        * @param sat     SatID of the solution we are looking for.
00924        *
00925        * \warning In the case the solution contains more than one variable
00926        * of this type, only the first one will be returned.
00927        */
00928    double SolverGeneral::getVariance( const TypeID& type,
00929                                       const SatID& sat ) const 
00930       throw(InvalidRequest)
00931    {
00932       // Declare an iterator for 'stateMap' and go to the first element
00933       VariableDataMap::const_iterator it = stateMap.begin();
00934 
00935       // Look for a variable with the same type and source
00936       while( !( (*it).first.getType()   == type &&
00937              (*it).first.getSatellite() == sat ) &&
00938              it != stateMap.end() )
00939       {
00940          ++it;
00941 
00942          // If it is not found, throw an exception
00943          if( it == stateMap.end() )
00944          {
00945             InvalidRequest e("Type and source not found in solution vector.");
00946             GPSTK_THROW(e);
00947          }
00948       }
00949 
00950       // Else, return the corresponding value
00951       return getCovariance(it->first,it->first);
00952 
00953 
00954    }  // End of method 'SolverGeneral::getVariance()'
00955 
00956 
00957       /* Returns the variance associated to a given TypeID.
00958        *
00959        * @param type    TypeID of the variance we are looking for.
00960        * @param source  SourceID of the solution we are looking for.
00961        * @param sat     SatID of the solution we are looking for.
00962        *
00963        * \warning In the case the solution contains more than one variable
00964        * of this type, only the first one will be returned.
00965        */
00966    double SolverGeneral::getVariance( const TypeID& type,
00967                                       const SourceID& source,
00968                                       const SatID& sat ) const 
00969       throw(InvalidRequest)
00970    {
00971          // Declare an iterator for 'stateMap' and go to the first element
00972       VariableDataMap::const_iterator it = stateMap.begin();
00973 
00974          // Look for a variable with the same type, source and satellite
00975       while( !( (*it).first.getType()      == type    &&
00976          (*it).first.getSource()    == source  &&
00977          (*it).first.getSatellite() == sat        ) &&
00978          it != stateMap.end() )
00979       {
00980          ++it;
00981 
00982          // If it is not found, throw an exception
00983          if( it == stateMap.end() )
00984          {
00985             InvalidRequest e("Type, source and SV not found in solution vector.");
00986             GPSTK_THROW(e);
00987          }
00988       }
00989 
00990          // Else, return the corresponding value
00991       return getCovariance(it->first,it->first);
00992 
00993    }  // End of method 'SolverGeneral::getVariance()'
00994 
00995 
00996       /* Set the solution associated to a given Variable.
00997        *
00998        * @param variable    Variable object solution we are looking for.
00999        * @param val         solution value for the Variable object
01000        */
01001    SolverGeneral& SolverGeneral::setSolution( const Variable& variable,
01002                                               const double& val )
01003       throw(InvalidRequest)
01004    {
01005       VariableDataMap::iterator it = stateMap.find(variable);
01006       if(it!=stateMap.end())
01007       {
01008          stateMap[variable] = val;
01009       }
01010       else
01011       {
01012          InvalidRequest e("The variable not exist in the solver.");
01013          GPSTK_THROW(e);
01014       }
01015 
01016       return (*this);
01017    }
01018 
01019 
01026    SolverGeneral& SolverGeneral::setCovariance( const Variable& var1, 
01027                                                 const Variable& var2,
01028                                                 const double& cov)
01029       throw(InvalidRequest)
01030    {  
01031       std::map<Variable, VariableDataMap >::iterator it1 = covarianceMap.find(var1);
01032       if(it1!=covarianceMap.end())
01033       {
01034          VariableDataMap::iterator it2 = it1->second.find(var2);
01035          if(it2!=it1->second.end())
01036          {
01037             covarianceMap[var1][var2] = cov;
01038             return (*this);
01039          }
01040          else
01041          {
01042             it1 = covarianceMap.find(var2);
01043             if(it1!=covarianceMap.end())
01044             {
01045                it2 = it1->second.find(var1);
01046                if(it2!=it1->second.end())
01047                {
01048                   covarianceMap[var2][var1] = cov;
01049                   return (*this);
01050                }
01051             }
01052          }
01053       }
01054 
01055       // One code go here, we failed to find the value, and throw exception.
01056       InvalidRequest e("The input variables are not exist in the solver.");
01057       GPSTK_THROW(e);
01058       
01059       return (*this);
01060    }
01061 
01062 
01063 }  // End of namespace gpstk

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