00001 #pragma ident "$Id: ARLambda.cpp 2620 2011-05-26 14:42:13Z yanweignss $"
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
00078 return ambFloat;
00079
00080 }
00081
00082
00083 int ARLambda::factorize( const Matrix<double>& Q,
00084 Matrix<double>& L,
00085 Vector<double>& D)
00086 {
00087
00088
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 }
00112
00113
00114 void ARLambda::gauss(Matrix<double>& L, Matrix<double>& Z, int i, int j)
00115 {
00116
00117
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 }
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
00136
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 }
00157
00158
00159 void ARLambda::reduction( Matrix<double>& L,
00160 Vector<double>& D,
00161 Matrix<double>& Z)
00162 {
00163
00164
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 }
00192
00193 }
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
00208
00209
00210
00211
00212
00213
00214
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 }
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 {
00322 F = transpose( inverseLUD(Z) ) * E;
00323 }
00324 catch(...)
00325 { return -1; }
00326 }
00327 }
00328
00329 return 0;
00330
00331 }
00332
00333
00334 }
00335