SolverWMS.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: SolverWMS.cpp 1325 2008-07-29 14:33:43Z architest $"
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 ). 2006, 2007, 2008
00027 //
00028 //============================================================================
00029 
00030 
00031 #include "SolverBase.hpp"
00032 #include "SolverWMS.hpp"
00033 #include "MatrixFunctors.hpp"
00034 
00035 
00036 namespace gpstk
00037 {
00038 
00039       // Index initially assigned to this class
00040    int SolverWMS::classIndex = 9100000;
00041 
00042 
00043       // Returns an index identifying this object.
00044    int SolverWMS::getIndex() const
00045    { return index; }
00046 
00047 
00048       // Returns a string identifying this object.
00049    std::string SolverWMS::getClassName() const
00050    { return "SolverWMS"; }
00051 
00052 
00053 
00054       /* Default constructor. When fed with GNSS data structures, the
00055        * default equation definition to be used is the common GNSS
00056        * code equation.
00057        */
00058    SolverWMS::SolverWMS()
00059    {
00060 
00061          // First, let's define a set with the typical unknowns
00062       TypeIDSet tempSet;
00063       tempSet.insert(TypeID::dx);
00064       tempSet.insert(TypeID::dy);
00065       tempSet.insert(TypeID::dz);
00066       tempSet.insert(TypeID::cdt);
00067 
00068          // Now, we build the default definition for a common GNSS 
00069          // code-based equation
00070       defaultEqDef.header = TypeID::prefitC;
00071       defaultEqDef.body = tempSet;
00072       setIndex();
00073 
00074    }  // End of 'SolverWMS::SolverWMS()'
00075 
00076 
00077 
00078       /* Explicit constructor. Sets the default equation definition
00079        * to be used when fed with GNSS data structures.
00080        *
00081        * @param eqDef     gnssEquationDefinition to be used
00082        */
00083    SolverWMS::SolverWMS(const gnssEquationDefinition& eqDef)
00084    {
00085 
00086       setDefaultEqDefinition(eqDef);
00087 
00088       setIndex();
00089 
00090    }  // End of 'SolverWMS::SolverWMS()'
00091 
00092 
00093 
00094       /* Compute the Weighted Least Mean Squares Solution of the given
00095        * equations set.
00096        *
00097        * @param prefitResiduals   Vector of prefit residuals
00098        * @param designMatrix      Design matrix for the equation system
00099        * @param weightVector      Vector of weights assigned to each
00100        *                          satellite.
00101        *
00102        * @return
00103        *  0 if OK
00104        *  -1 if problems arose
00105        */
00106    int SolverWMS::Compute( const Vector<double>& prefitResiduals,
00107                            const Matrix<double>& designMatrix,
00108                            const Vector<double>& weightVector )
00109       throw(InvalidSolver)
00110    {
00111 
00112          // By default, results are invalid
00113       valid = false;
00114 
00115          // Check that everyting has a proper size
00116       int wSize = static_cast<int>(weightVector.size());
00117       int pSize = static_cast<int>(prefitResiduals.size());
00118       if (!(wSize==pSize))
00119       {
00120          InvalidSolver e("prefitResiduals size does not match dimension \
00121 of weightVector");
00122          GPSTK_THROW(e);
00123       }
00124 
00125       Matrix<double> wMatrix(wSize,wSize,0.0);  // Declare a weight matrix
00126 
00127          // Fill the weight matrix diagonal with the content of 
00128          // the weight vector
00129       for (int i=0; i<wSize; i++)
00130       {
00131          wMatrix(i,i) = weightVector(i);
00132       }
00133 
00134          // Call the more general SolverWMS::Compute() method
00135       return SolverWMS::Compute(prefitResiduals, designMatrix, wMatrix);
00136 
00137    }  // End of method 'SolverWMS::Compute()'
00138 
00139 
00140 
00141       // Compute the Weighted Least Mean Squares Solution of the given
00142       // equations set.
00143       //
00144       // @param prefitResiduals   Vector of prefit residuals
00145       // @param designMatrix      Design matrix for equation system
00146       // @param weightMatrix      Matrix of weights
00147       //
00148       // @return
00149       //  0 if OK
00150       //  -1 if problems arose
00151       //
00152    int SolverWMS::Compute( const Vector<double>& prefitResiduals,
00153                            const Matrix<double>& designMatrix,
00154                            const Matrix<double>& weightMatrix )
00155       throw(InvalidSolver)
00156    {
00157 
00158          // By default, results are invalid
00159       valid = false;
00160 
00161       if (!(weightMatrix.isSquare()))
00162       {
00163          InvalidSolver e("Weight matrix is not square");
00164          GPSTK_THROW(e);
00165       }
00166 
00167       int wRow = static_cast<int>(weightMatrix.rows());
00168       int pRow = static_cast<int>(prefitResiduals.size());
00169       if (!(wRow==pRow))
00170       {
00171          InvalidSolver e("prefitResiduals size does not match dimension of \
00172 weightMatrix");
00173          GPSTK_THROW(e);
00174       }
00175 
00176       int gCol = static_cast<int>(designMatrix.cols());
00177 
00178       int gRow = static_cast<int>(designMatrix.rows());
00179       if (!(gRow==pRow))
00180       {
00181          InvalidSolver e("prefitResiduals size does not match dimension \
00182 of designMatrix");
00183          GPSTK_THROW(e);
00184       }
00185 
00186       Matrix<double> AT = transpose(designMatrix);
00187       covMatrix.resize(gCol, gCol);
00188       covMatrixNoWeight.resize(gCol, gCol);
00189       solution.resize(gCol);
00190 
00191          // Temporary storage for covMatrix. It will be inverted later
00192       covMatrix = AT * weightMatrix * designMatrix;
00193 
00194          // Let's try to invert AT*W*A  matrix
00195       try { 
00196          covMatrix = inverseChol( covMatrix );
00197       }
00198       catch(...)
00199       {
00200          InvalidSolver e("Unable to invert matrix covMatrix");
00201          GPSTK_THROW(e);
00202       }
00203 
00204          // Temporary storage for covMatrixNoWeight. It will be inverted later
00205       covMatrixNoWeight = AT * designMatrix;
00206 
00207          // Let's try to invert AT*A  matrix
00208       try { 
00209          covMatrixNoWeight = inverseChol( covMatrixNoWeight );
00210       }
00211       catch(...)
00212       {
00213          InvalidSolver e("Unable to invert matrix covMatrixNoWeight");
00214          GPSTK_THROW(e);
00215       }
00216 
00217          // Now, compute the Vector holding the solution...
00218       solution = covMatrix * AT * weightMatrix * prefitResiduals;
00219 
00220          // ... and the postfit residuals Vector
00221       postfitResiduals = prefitResiduals - designMatrix * solution;
00222 
00223          // If everything is fine so far, then the results should be valid
00224       valid = true;
00225 
00226       return 0;
00227 
00228    }  // End of method 'SolverWMS::Compute()'
00229 
00230 
00231 
00232       /* Returns a reference to a satTypeValueMap object after solving
00233        * the previously defined equation system.
00234        *
00235        * @param gData     Data object holding the data.
00236        */
00237    satTypeValueMap& SolverWMS::Process(satTypeValueMap& gData)
00238       throw(ProcessingException)
00239    {
00240 
00241       try
00242       {
00243 
00244             // First, let's fetch the vector of prefit residuals
00245          Vector<double> prefit(gData.getVectorOfTypeID(defaultEqDef.header));
00246 
00247             // Second, generate the corresponding geometry/design matrix
00248          Matrix<double> dMatrix(gData.getMatrixOfTypes(defaultEqDef.body));
00249 
00250             // Third, generate the appropriate weights vector
00251          Vector<double> weightsVector(gData.getVectorOfTypeID(TypeID::weight));
00252 
00253             // Call the Compute() method with the defined equation model.
00254             // This equation model MUST HAS BEEN previously set, usually when
00255             // creating the SolverWMS object with the appropriate constructor.
00256          Compute(prefit, dMatrix, weightsVector);
00257 
00258             // Now we have to add the new values to the data structure
00259          if ( defaultEqDef.header == TypeID::prefitC )
00260          {
00261             gData.insertTypeIDVector(TypeID::postfitC, postfitResiduals);
00262          }
00263 
00264          if ( defaultEqDef.header == TypeID::prefitL )
00265          {
00266             gData.insertTypeIDVector(TypeID::postfitL, postfitResiduals);
00267          }
00268 
00269          return gData;
00270 
00271       }
00272       catch(Exception& u)
00273       {
00274             // Throw an exception if something unexpected happens
00275          ProcessingException e( getClassName() + ":"
00276                                 + StringUtils::asString( getIndex() ) + ":"
00277                                 + u.what() );
00278 
00279          GPSTK_THROW(e);
00280 
00281       }
00282 
00283    }   // End of method 'SolverWLMS::Process()'
00284 
00285 
00286 
00287 }  // End of namespace gpstk

Generated on Tue May 22 03:31:01 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1