ARLambda.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: ARLambda.cpp 2620 2011-05-26 14:42:13Z 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 //  Wei Yan - Chinese Academy of Sciences . 2011
00027 //
00028 //============================================================================
00029 
00030 #include "ARLambda.hpp"
00031 
00032 
00033 namespace gpstk
00034 {
00035    Vector<double> ARLambda::resolveIntegerAmbiguity( 
00036                                                const Vector<double>& ambFloat, 
00037                                                const Matrix<double>& ambCov )
00038       throw(ARException)
00039    {
00040       // check input
00041       if( ambFloat.size()!=ambCov.rows() || ambFloat.size()!=ambCov.cols() )
00042       {
00043          ARException e("The dimension of input does not match.");
00044          GPSTK_THROW(e);
00045       }
00046 
00047       try
00048       {
00049          Matrix<double> F; Vector<double> S;
00050          if( lambda(ambFloat,ambCov,F,S,2)==0 )
00051          {
00052             Vector<double> ambFixed( ambFloat.size(), 0.0 );
00053             for(int i=0; i<ambFloat.size(); i++) 
00054             {
00055                ambFixed(i) = F(i,0);
00056             }
00057 
00058             squaredRatio = (S(0)<1e-12) ? 9999.9 : S(1)/S(0);
00059             
00060             return ambFixed;
00061          }
00062          else
00063          {
00064             ARException e("Failed to resolve the integer ambiguities.");
00065             GPSTK_THROW(e);
00066          }
00067       }
00068       catch(Exception& e)
00069       {
00070          GPSTK_RETHROW(e);
00071       }
00072       catch (...)
00073       {
00074          ARException e("Failed to resolve the integer ambiguities.");
00075          GPSTK_THROW(e);
00076       }
00077          // it should never go here, but we sill return the float ambiguities
00078       return ambFloat;
00079 
00080    }  // End of method 'ARMLambda::resolveIntegerAmbiguity()'
00081 
00082    
00083    int ARLambda::factorize( const Matrix<double>& Q, 
00084                             Matrix<double>& L, 
00085                             Vector<double>& D)
00086    {
00087       // TODO: CHECK UNEXPECTED INPUT
00088       // L:nxn Z:nxn 0<=(i,j)<n
00089 
00090       const int n = static_cast<int>(Q.rows());
00091 
00092       Matrix<double> QC(Q);
00093       L.resize(n, n, 0.0);
00094       D.resize(n, 0.0);
00095 
00096       for(int i = n-1; i >= 0; i--) 
00097       {
00098          D(i) = QC(i,i);
00099          if( D(i) <= 0.0 ) return -1;
00100          double temp = std::sqrt(D(i));
00101          for(int j=0; j<=i; j++) L(i,j) = QC(i,j)/temp;
00102          for(int j=0; j<=i-1; j++) 
00103          {
00104             for(int k=0; k<=j; k++) QC(j,k) -= L(i,k) * L(i,j);
00105          }
00106          for(int j=0; j<=i; j++) L(i,j) /= L(i,i);
00107       }
00108 
00109       return 0;
00110 
00111    }  // End of method 'ARLambda::factorize()'
00112 
00113 
00114    void ARLambda::gauss(Matrix<double>& L, Matrix<double>& Z, int i, int j)
00115    {
00116       //TODO: CHECK UNEXPECTED INPUT
00117       // L:nxn Z:nxn 0<=(i,j)<n
00118 
00119       const int n = L.rows();
00120       const int mu = (int)round(L(i,j));
00121       if(mu != 0) 
00122       {
00123          for(int k=i; k<n; k++) L(k,j) -= (double)mu*L(k,i);
00124          for(int k=0; k<n; k++) Z(k,j) -= (double)mu*Z(k,i);
00125       }
00126    }  // End of method 'ARLambda::gauss()'
00127 
00128    
00129    void ARLambda::permute( Matrix<double>& L, 
00130                            Vector<double>& D, 
00131                            int j, 
00132                            double del, 
00133                            Matrix<double>& Z )
00134    {  
00135       //TODO: CHECK UNEXPECTED INPUT
00136       // L:nxn D:nx1 Z:nxn 0<=j<n
00137 
00138       const int n = L.rows();
00139 
00140       double eta=D(j)/del;
00141       double lam=D(j+1)*L(j+1,j)/del;
00142 
00143       D[j]=eta*D(j+1); 
00144       D(j+1)=del;
00145       for(int k=0;k<=j-1;k++) 
00146       {
00147          double a0=L(j,k); 
00148          double a1=L(j+1,k);
00149          L(j,k) =-L(j+1,j)*a0 + a1;
00150          L(j+1,k) = eta*a0 + lam*a1;
00151       }
00152       L(j+1,j)=lam;
00153       for(int k=j+2; k<n; k++) swap(L(k,j),L(k,j+1));
00154       for(int k=0; k<n; k++) swap(Z(k,j),Z(k,j+1));
00155 
00156    }  // End of method 'ARLambda::permute()'
00157 
00158    
00159    void ARLambda::reduction( Matrix<double>& L, 
00160                              Vector<double>& D,
00161                              Matrix<double>& Z)
00162    {
00163       //TODO: CHECK UNEXPECTED INPUT
00164       // L:nxn D:nx1 Z:nxn 0<=j<n
00165 
00166       const int n = L.rows();
00167 
00168       int j(n-2), k(n-2);
00169       while(j>=0) 
00170       {
00171          if(j<=k)
00172          {
00173             for (int i=j+1; i<n; i++) 
00174             {
00175                gauss(L,Z,i,j);
00176             }
00177          } 
00178 
00179          double del=D(j)+L(j+1,j)*L(j+1,j)*D(j+1);
00180 
00181          if(del+1E-6<D(j+1)) 
00182          { 
00183             permute(L,D,j,del,Z);
00184             k=j; j=n-2;
00185          }
00186          else
00187          { 
00188             j--;
00189          }
00190 
00191       }  // end while
00192 
00193    }  // End of method 'ARLambda::reduction()'
00194 
00195 
00196    int ARLambda::search( const Matrix<double>& L, 
00197                          const Vector<double>& D, 
00198                          const Vector<double>& zs, 
00199                          Matrix<double>& zn, 
00200                          Vector<double>& s, 
00201                           const int& m )
00202    {
00203 
00204       ARException e("The LAMBDA search method have not been implemented.");
00205       GPSTK_THROW(e);
00206 
00207       // TODO: CHECK UNEXPECTED INPUT
00208       // n - number of float parameters
00209       // m - number of fixed solutions
00210       // L - nxn
00211       // D - nx1
00212       // zs - nxn
00213       // zn - nxm
00214       // s  - m
00215       const int LOOPMAX = 10000;
00216       const int n = L.rows();
00217 
00218       zn.resize(n,m,0.0);
00219       s.resize(m,0.0);
00220 
00221       Matrix<double> S(n,n,0.0);
00222       Vector<double> dist(n,0.0),zb(n,0.0),z(n,0.0),step(n,0.0);
00223 
00224       int k=n-1; dist[k]=0.0;
00225       zb(k)=zs(k);
00226       z(k)=round(zb(k)); 
00227       double y=zb(k)-z(k); 
00228       step(k)=sign(y);
00229 
00230       int c(0),nn(0),imax(0);
00231       double maxdist=1E99;
00232       for(int c=0;c<LOOPMAX;c++)
00233       {
00234          double newdist=dist(k)+y*y/D(k);
00235          if(newdist<maxdist) 
00236          {
00237             if(k!=0) 
00238             {
00239                dist(--k)=newdist;
00240                for(int i=0;i<=k;i++)
00241                {
00242                   S(k,i)=S(k+1,i)+(z(k+1)-zb(k+1))*L(k+1,i);
00243                }
00244                zb(k)=zs(k)+S(k,k);
00245                z(k)=round(zb(k)); y=zb(k)-z(k); step(k)=sign(y);
00246             }
00247             else 
00248             {
00249                if(nn<m) 
00250                {
00251                   if(nn==0||newdist>s(imax)) imax=nn;
00252                   for(int i=0;i<n;i++) zn(i,nn)=z(i);
00253                   s(nn++)=newdist;
00254                }
00255                else 
00256                {
00257                   if(newdist<s(imax)) 
00258                   {
00259                      for(int i=0;i<n;i++) zn(i,imax)=z(i);
00260                      s(imax)=newdist;
00261                      for(int i=imax=0;i<m;i++) if (s(imax)<s(i)) imax=i;
00262                   }
00263                   maxdist=s(imax);
00264                }
00265                z(0)+=step(0); y=zb(0)-z(0); step(0)=-step(0)-sign(step(0));
00266             }
00267          }
00268          else 
00269          {
00270             if(k==n-1) break;
00271             else 
00272             {
00273                k++;
00274                z(k)+=step(k); y=zb(k)-z(k); step(k)=-step(k)-sign(step(k));
00275             }
00276          }
00277       }
00278       for(int i=0;i<m-1;i++) 
00279       { 
00280          for(int j=i+1;j<m;j++) 
00281          {
00282             if(s(i)<s(j)) continue;
00283             swap(s(i),s(j));
00284             for(k=0;k<n;k++) swap(zn(k,i),zn(k,j));
00285          }
00286       }
00287 
00288       if (c>=LOOPMAX) 
00289       {
00290          return -1;
00291       }
00292 
00293       return 0;
00294 
00295    }  // End of method 'ARLambda::search()'
00296 
00297 
00298    int ARLambda::lambda( const Vector<double>& a, 
00299                          const Matrix<double>& Q, 
00300                          Matrix<double>& F,
00301                          Vector<double>& s,
00302                          const int& m )
00303    {
00304       if( (a.size()!=Q.rows()) || (Q.rows()!=Q.cols()) ) return -1;
00305       if( m < 1) return -1;
00306 
00307       const int n = static_cast<int>(a.size());
00308 
00309       Matrix<double> L(n,n,0.0),E(n,m,0.0);
00310       Vector<double> D(n,0.0),z(n,0.0);
00311       Matrix<double> Z = ident<double>(n);
00312 
00313       if (factorize(Q,L,D)==0) 
00314       {      
00315          reduction(L,D,Z);
00316          z = transpose(Z)*a;
00317 
00318          if (search(L,D,z,E,s,m)==0) 
00319          {
00320             try
00321             {  // F=Z'\E - Z nxn  E nxm F nxm
00322                F = transpose( inverseLUD(Z) ) * E;
00323             }
00324             catch(...) 
00325             { return -1; }
00326          }
00327       }
00328 
00329       return 0;
00330 
00331    }  // End of method 'ARLambda::lambda()'
00332 
00333 
00334 }   // End of namespace gpstk
00335 

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