00001 #pragma ident "$Id: Bancroft.cpp 1161 2008-03-27 17:16:22Z ckiesch $"
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 <cstdlib>
00031 #include "Bancroft.hpp"
00032 #include "MiscMath.hpp"
00033 #include "Matrix.hpp"
00034 #include "Vector.hpp"
00035
00036 using namespace std;
00037 using namespace gpstk;
00038
00039 namespace gpstk
00040 {
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 int Bancroft::Compute( Matrix<double>& Data,
00060 Vector<double>& X )
00061 throw(Exception)
00062 {
00063
00064 try
00065 {
00066
00067 int N = Data.rows();
00068 Matrix<double> B(0,4);
00069
00070
00071 if( testInput )
00072 {
00073
00074 double satRadius = 0.0;
00075
00076
00077 for( int i=0; i < N; i++ )
00078 {
00079
00080
00081 if( !( (Data(i,3) >= minPRange) && (Data(i,3) <= maxPRange) ) )
00082 {
00083 continue;
00084 }
00085
00086
00087
00088 satRadius = RSS(Data(i,0), Data(i,1) , Data(i,2));
00089
00090
00091
00092 if( !( (satRadius >= minRadius) && (satRadius <= maxRadius) ) )
00093 {
00094 continue;
00095 }
00096
00097
00098
00099 MatrixRowSlice<double> goodRow(Data,i);
00100 B = B && goodRow;
00101
00102 }
00103
00104
00105
00106 if( (N = B.rows()) < 4 )
00107 {
00108 return -1;
00109 }
00110
00111 }
00112 else
00113 {
00114
00115
00116 B = Data;
00117 }
00118
00119
00120 Matrix<double> BT=transpose(B);
00121 Matrix<double> BTBI(4,4), M(4,4,0.0);
00122 Vector<double> aux(4), alpha(N), solution1(4), solution2(4);
00123
00124
00125 BTBI = BT * B;
00126
00127
00128 try
00129 {
00130 BTBI = inverseChol( BTBI );
00131 }
00132 catch(...)
00133 {
00134 return -2;
00135 }
00136
00137
00138 for( int i=0; i < N; i++ )
00139 {
00140
00141
00142 aux(0) = B(i,0);
00143 aux(1) = B(i,1);
00144 aux(2) = B(i,2);
00145 aux(3) = B(i,3);
00146 alpha(i) = 0.5 * Minkowski(aux, aux);
00147 }
00148
00149 Vector<double> tau(N,1.0), BTBIBTtau(4), BTBIBTalpha(4);
00150
00151 BTBIBTtau = BTBI * BT * tau;
00152 BTBIBTalpha = BTBI * BT * alpha;
00153
00154
00155 double a(Minkowski(BTBIBTtau, BTBIBTtau));
00156 double b(2.0 * (Minkowski(BTBIBTtau, BTBIBTalpha) - 1.0));
00157 double c(Minkowski(BTBIBTalpha, BTBIBTalpha));
00158
00159
00160 double discriminant = b*b - 4.0 * a * c;
00161 if (discriminant < 0.0)
00162 {
00163 return -2;
00164 }
00165
00166
00167 double DELTA1 = ( -b + SQRT(discriminant) ) / ( 2.0 * a );
00168 double DELTA2 = ( -b - SQRT(discriminant) ) / ( 2.0 * a );
00169
00170
00171 M(0,0) = 1.0;
00172 M(1,1) = 1.0;
00173 M(2,2) = 1.0;
00174 M(3,3) = - 1.0;
00175
00176
00177 solution1 = M * BTBI * ( BT * DELTA1 * tau + BT * alpha );
00178 double radius1(RSS(solution1(0), solution1(1), solution1(2)));
00179
00180 solution2 = M * BTBI * ( BT * DELTA2 * tau + BT * alpha );
00181 double radius2(RSS(solution2(0), solution2(1), solution2(2)));
00182
00183
00184 if ( ChooseOne )
00185 {
00186 if ( ABS(CloseTo-radius1) < ABS(CloseTo-radius2) )
00187 {
00188 X = solution1;
00189 }
00190 else
00191 {
00192 X = solution2;
00193 }
00194 }
00195 else
00196 {
00197
00198 X = solution1;
00199 SecondSolution = solution2;
00200 }
00201
00202 return 0;
00203
00204 }
00205 catch(Exception& e)
00206 {
00207 GPSTK_RETHROW(e);
00208 }
00209 }
00210
00211
00212
00213
00214 int Bancroft::Compute( const Matrix<double>& Data,
00215 Vector<double>& X )
00216 throw(Exception)
00217 {
00218 Matrix<double> Datanoconst(Data);
00219
00220 return Bancroft::Compute(Datanoconst, X);
00221
00222 }
00223
00224
00225 }