General Purpose Geodetic Library
SgPwlStorageBSplineL.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include <SgLogger.h>
24 
25 #include <SgPwlStorageBSplineL.h>
26 
27 #include <SgTaskConfig.h>
28 
29 
30 
31 
32 /*=======================================================================================================
33 *
34 * METHODS:
35 *
36 *======================================================================================================*/
37 //
38 // static first:
40 {
41  return "SgPwlStorageBSplineL";
42 };
43 
44 
45 
46 // An empty constructor:
48  SgPwlStorage()
49 {
50 };
51 
52 
53 
54 // A destructor:
56 {
57 };
58 
59 
60 
61 //
63 {
65  int nAs, nBs(2);
66  switch (dDomain)
67  {
68  default:
70  nAs = getNumOfPolynomials();
71  break;
72  case SgPartial::DD_RATE:
74  break;
75  };
76  return nAs + nBs;
77 };
78 
79 
80 
81 //
83 {
84  return numOfNodes_ - 1;
85 };
86 
87 
88 
89 //
91  const SgMJD& t0, const SgMJD& tN, const SgMJD& tRefer,
92  const SgTaskConfig* /*cfg*/)
93 {
94  if (isPOrigOwner_)
95  delete pOrig_;
96  pOrig_ = p;
97  isPOrigOwner_ = false;
98  tStart_ = t0;
99  tFinis_ = tN;
100  //tRefer_ = tN;
101  //tRefer_.setTime(0.0); // 0hr
102  tRefer_ = tRefer;
103  step_ = pOrig_->getStep();
104  // emulate SOLVE:
105 // SgMJD t0h(tN);
106 // t0h.setTime(0); // 0hr
107 // if (cfg->getIsSolveCompatible())
108 
109 /*
110  if (?)
111  {
112  SgMJD t0h(tRefer_);
113  if (step_ > tFinis_-tStart_)
114  {
115  tStart_ = t0h - ceil((t0h - t0)*24.0)/24.0;
116  tFinis_ = t0h + ceil((tN - t0h)*24.0)/24.0;
117  step_ = tFinis_ - tStart_;
118  }
119  else
120  {
121  tStart_ = t0h - ceil((t0h - t0)*24.0)/24.0;
122  tFinis_ = tStart_ + ceil((tN - tStart_)/step_)*step_;
123  };
124 //
125 // if (step_ < tFinis_-tStart_)
126 // {
127 // tStart_ = t0h - ceil((t0h - t0)/step_)*step_;
128 // tFinis_ = t0h + ceil((tN - t0h)/step_)*step_;
129 // }
130 // else
131 // {
132 // tStart_ = t0h - ceil((t0h - t0)*24.0)/24.0;
133 // tFinis_ = t0h + ceil((tN - t0h)*24.0)/24.0;
134 // step_ = tFinis_ - tStart_;
135 // };
136 //
137  }
138  else
139 */
140 
141  // if the step equal to an interval of data set, no polynomial terms are expected:
142  if (step_ > tFinis_-tStart_)
143  {
144  step_ = tFinis_ - tStart_ + 1.0E-4/DAY2SEC;
145  numOfPolynomials_ = 0;
146  }
147  else
149 
150 // if (numOfPolynomials_ == 1) // no polynomials
151 // numOfPolynomials_ = 0;
152 
153  if (numOfPolynomials_ > 0)
154  {
156  for (int i=0; i<numOfPolynomials_; i++)
157  {
158  pAi_[i].setName(pOrig_->getName() + ": A_" + QString("").sprintf("%d", i));
159  pAi_[i].tune(*pOrig_);
162  pAi_[i].setTLeft(tZero);
163  pAi_[i].setTRight(tInf);
164  };
166  "::deployParameters(): " + QString("").setNum(numOfPolynomials_) +
167  " polynomial parameters were allocated for " + pOrig_->getName() + " parameter");
168  };
169 
170  // B-Spline nodes:
171  // modify pOrig's a priori std.dev:
172 // pOrig_->setSigmaAPriori(pOrig_->getSigmaAPriori()*step_);
173  numOfNodes_ = floor((tFinis_ - tStart_)/step_) + 2;
175  for (int i=0; i<numOfNodes_; i++)
176  {
177  pBi_[i].setName(pOrig_->getName() + ": B_" + QString("").sprintf("%03d", i));
178  pBi_[i].tune(*pOrig_);
181  if (true)
182  {
183  pBi_[i].setTLeft (tStart_ + (i - 1)*step_);
184  pBi_[i].setTRight(tStart_ + (i + 1)*step_);
185  }
186  else // test:
187  {
188  pBi_[i].setTLeft(tZero);
189  pBi_[i].setTRight(tInf);
190  };
191  };
192  pBi_[0 ].setTLeft (tStart_);
194 
195  sumP2_ = 0.0;
196  sumX1P2_ = 0.0;
197  sumX2P2_ = 0.0;
198  sumT1P2_ = 0.0;
199 };
200 
201 
202 
203 //
205 {
207  return;
208  //
209  // adjust time from constraints equations:
210  SgMJD t(tt==tZero?tStart_:tt);
212  //
213  if (t < tStart_)
215  ": propagatePartials(): t(" + t.toString(SgMJD::F_YYYYMMDDHHMMSSSS) + ") < tStart(" +
217  if (tFinis_ < t)
219  ": propagatePartials(): tFinis(" + tFinis_.toString(SgMJD::F_YYYYMMDDHHMMSSSS) + ") < t(" +
221  //
222  double d(pOrig_->getD());
223  //
224  // Polynomials:
225  if (numOfPolynomials_ > 0)
226  {
227  double dt = (t - tRefer_);
228  double dd = 1.0;
229  switch (dDomain)
230  {
231  default:
233  for (int i=0; i<numOfPolynomials_; i++)
234  {
235  pAi_[i].setD(d*dd);
236  dd *= dt;
237  };
238  break;
239  case SgPartial::DD_RATE:
240  for (int i=1; i<numOfPolynomials_; i++)
241  {
242  pAi_[i].setD(i*d*dd);
243  dd *= dt/*/DAY2SEC*/;
244  };
245  break;
246  };
247  };
248  //
249  //
250  // B-Splines:
251  int j=calcCurrentIdx(t);
252  switch (dDomain)
253  {
254  default:
256  pBi_[j ].setD(d*((tStart_ - t) + (j+1)*step_)/step_);
257  pBi_[j+1].setD(d*((t - tStart_) - j*step_)/step_);
258  break;
259  case SgPartial::DD_RATE:
260  pBi_[j ].setD(-d/step_);
261  pBi_[j+1].setD( d/step_);
262  break;
263  };
264  //
265  pOrig_->zerofy();
266 };
267 
268 
269 
270 //
271 double SgPwlStorageBSplineL::calcAX(const SgMJD& t, bool isWorkingBand)
272 {
274  double f(0.0), s2(0.0), d;
275  int j, n;
276  //
277  // Polynomials:
278  if (numOfPolynomials_ > 0)
279  {
280  double dt = (t - tRefer_);
281  double dd = 1.0;
282  switch (dDomain)
283  {
284  default:
286  for (int i=0; i<numOfPolynomials_; i++)
287  {
288  f += pAi_[i].getSolution()*dd;
289  s2+= pAi_[i].getSigma()*pAi_[i].getSigma()*dd*dd;
290  dd *= dt;
291  };
292  break;
293  case SgPartial::DD_RATE:
294  for (int i=1; i<numOfPolynomials_; i++)
295  {
296  f += i*pAi_[i].getSolution()*dd;
297  s2+= i*i*pAi_[i].getSigma()*pAi_[i].getSigma()*dd*dd;
298  dd *= dt/*/DAY2SEC*/;
299  };
300  break;
301  };
302  };
303  //
304  // B-Splines:
305  double fs(0.0), s2s(s2), b;
306  if (numOfPolynomials_==1)
307  fs = f;
308  j = calcCurrentIdx(t);
309 
310  switch (dDomain)
311  {
312  default:
314  //
315  d = ((tStart_ - t) + (j+1)*step_)/step_;
316  b = pBi_[j].getSolution()*d;
317  f += b;
318  fs += b;
319  b = pBi_[j].getSigma()*pBi_[j].getSigma()*d*d;
320  s2 += b;
321  s2s+= b;
322  //
323  d = ((t - tStart_) - j*step_)/step_;
324  b = pBi_[j+1].getSolution()*d;
325  f += b;
326  fs += b;
327  b = pBi_[j+1].getSigma()*pBi_[j+1].getSigma()*d*d;
328  s2 += b;
329  s2s+= b;
330  //
331  n = std::min(pBi_[j].getNumObs(), pBi_[j+1].getNumObs());
332  //
333  // sets up the original parameter solution:
334  pOrig_->setSolution(fs);
335  pOrig_->setSigma(sqrt(s2s));
336  pOrig_->setNumObs(n);
337  // and statistics:
338  if (isWorkingBand)
339  {
340  sumP2_ += 1.0/s2;
341  sumX1P2_ += f /s2;
342  sumX2P2_ += f*f/s2;
343  sumT1P2_ += t.toDouble()/s2;
344  };
345  break;
346  case SgPartial::DD_RATE:
347  d = -pBi_[j ].getSolution()/step_;
348  f += d;
349  d = pBi_[j+1].getSolution()/step_;
350  f += d;
351  break;
352  };
353  // return Ax part:
354  return pOrig_->getD()*f;
355 };
356 
357 
358 
359 //
361 {
362  double f(0.0), d, dt(t - tStart_);
363  int j = calcCurrentIdx(t);
364  //
365  d = (-dt + (j+1)*step_)/step_;
366  f += pBi_[j ].getSolution()*d;
367  //
368  d = ( dt - j*step_)/step_;
369  f += pBi_[j+1].getSolution()*d;
370  //
371  // sets up the original parameter solution:
372  return f;
373 };
374 
375 
376 
377 //
379 {
380  // B-splines only:
381  double s2(0.0), d, dt(t - tStart_);
382  int j = calcCurrentIdx(t);
383  //
384  d = (-dt + (j+1)*step_)/step_;
385  s2 += pBi_[j ].getSigma()*pBi_[j ].getSigma()*d*d;
386  //
387  d = ( dt - j*step_)/step_;
388  s2 += pBi_[j+1].getSigma()*pBi_[j+1].getSigma()*d*d;
389  //
390  return sqrt(s2);
391 };
392 
393 
394 
395 //
396 double SgPwlStorageBSplineL::calc_P_a(const SgSymMatrix& P, int idx, const SgMJD& t)
397 {
399  double v(0.0);
400  if (numOfPolynomials_ > 0)
401  {
402  double dt = (t - tRefer_);
403  double dd = 1.0;
404  switch (dDomain)
405  {
406  default:
408  for (int i=0; i<numOfPolynomials_; i++)
409  {
410  v += P.getElement(idx, pAi_[i].getIdx())*dd;
411  dd *= dt;
412  };
413  break;
414  case SgPartial::DD_RATE:
415  for (int i=1; i<numOfPolynomials_; i++)
416  {
417  v += i*P.getElement(idx, pAi_[i].getIdx())*dd;
418  dd *= dt/*/DAY2SEC*/;
419  };
420  break;
421  };
422  };
423  //
424  int j=calcCurrentIdx(t);
425  switch (dDomain)
426  {
427  default:
429  v +=
430  P.getElement(idx, pBi_[j ].getIdx()) * ((tStart_ - t) + (j+1)*step_)/step_ +
431  P.getElement(idx, pBi_[j+1].getIdx()) * ((t - tStart_) - j*step_)/step_ ;
432  break;
433  case SgPartial::DD_RATE:
434  v += ( -P.getElement(idx, pBi_[j ].getIdx()) + P.getElement(idx, pBi_[j+1].getIdx()) )/step_;
435  break;
436  };
437  //
438  return pOrig_->getD()*v;
439 };
440 
441 
442 
443 //
444 double SgPwlStorageBSplineL::calc_aT_P_a(const SgVector& vP_a, const SgMJD& t)
445 {
447  double v(0.0);
448  if (numOfPolynomials_ > 0)
449  {
450  double dt = (t - tRefer_);
451  double dd = 1.0;
452  switch (dDomain)
453  {
454  default:
456  for (int i=0; i<numOfPolynomials_; i++)
457  {
458  v += vP_a.getElement(pAi_[i].getIdx())*dd;
459  dd *= dt;
460  };
461  break;
462  case SgPartial::DD_RATE:
463  for (int i=1; i<numOfPolynomials_; i++)
464  {
465  v += i*vP_a.getElement(pAi_[i].getIdx())*dd;
466  dd *= dt/*/DAY2SEC*/;
467  };
468  break;
469  };
470  };
471  //
472  int j=calcCurrentIdx(t);
473  switch (dDomain)
474  {
475  default:
477  v +=
478  vP_a.getElement(pBi_[j ].getIdx())*((tStart_ - t) + (j+1)*step_)/step_ +
479  vP_a.getElement(pBi_[j+1].getIdx())*((t - tStart_) - j*step_)/step_ ;
480  break;
481  case SgPartial::DD_RATE:
482  v += ( -vP_a.getElement(pBi_[j].getIdx()) + vP_a.getElement(pBi_[j+1].getIdx()) )/step_;
483  break;
484  };
485  //
486  return pOrig_->getD()*v;
487 };
488 
489 
490 
491 //
493 {
494  pars.clear();
496  int idx(calcCurrentIdx(t));
497  switch (dDomain)
498  {
499  default:
501  for (int i=0; i<getNumOfPolynomials(); i++)
502  pars.append(&pAi_[i]);
503  pars.append(&pBi_[idx ]);
504  pars.append(&pBi_[idx+1]);
505  break;
506  case SgPartial::DD_RATE:
507  for (int i=1; i<getNumOfPolynomials(); i++)
508  pars.append(&pAi_[i]);
509  pars.append(&pBi_[idx ]);
510  pars.append(&pBi_[idx+1]);
511  break;
512  };
513 };
514 
515 
516 
517 //
519 {
520  double vi, vim1, sD2;
521  sD2 = 0.0;
522  for (int i=1; i<numOfNodes_; i++)
523  {
524  vi = pBi_[i ].getSolution();
525  vim1 = pBi_[i-1].getSolution();
526  sD2 += (vi - vim1)*(vi - vim1);
527  };
528  return sD2/step_/step_;
529 };
530 /*=====================================================================================================*/
531 
532 
533 
534 
535 /*=======================================================================================================
536 *
537 * FRIENDS:
538 *
539 *======================================================================================================*/
540 //
541 
542 
543 
544 /*=====================================================================================================*/
545 //
546 // aux functions:
547 //
548 
549 
550 // i/o:
551 
552 
553 /*=====================================================================================================*/
554 //
555 // constants:
556 //
557 
558 
559 /*=====================================================================================================*/
SgLogger * logger
Definition: SgLogger.cpp:231
const SgMJD tZero(1957, 10, 4)
const SgMJD tInf(2100, 1, 1)
#define DAY2SEC
radians to mas:
Definition: SgMathSupport.h:56
bool isAttr(uint a) const
Definition: SgAttribute.h:226
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ ESTIMATOR
Definition: SgLogger.h:90
Definition: SgMJD.h:59
@ F_YYYYMMDDHHMMSSSS
Long verbose: Fri, the 2nd of Apr, 2010; 17hr 02min 43.6400sec.
Definition: SgMJD.h:67
QString toString(Format format=F_Verbose) const
Definition: SgMJD.cpp:1007
double toDouble() const
Definition: SgMJD.h:533
double getStep() const
Definition: SgParameter.h:523
double getSolution() const
Definition: SgParameter.h:435
void setTLeft(const SgMJD &t)
Definition: SgParameter.h:691
void setTRight(const SgMJD &t)
Definition: SgParameter.h:699
int getNumOfPolynomials() const
Definition: SgParameter.h:539
void tune(const SgParameterCfg &)
Definition: SgParameter.cpp:72
void setSigma(double v)
Definition: SgParameter.h:587
double getSigma() const
Definition: SgParameter.h:443
int getIdx() const
Definition: SgParameter.h:563
double getSigmaAPriori() const
Definition: SgParameter.h:475
void setSolution(double v)
Definition: SgParameter.h:579
void setSigmaAPriori(double v)
Definition: SgParameter.h:619
double getSigmaAPrioriAux() const
Definition: SgParameter.h:483
void setPMode(SgParameterCfg::PMode mode)
Definition: SgParameter.h:603
void setD(double d)
Definition: SgPartial.h:347
void setName(const QString &name)
Definition: SgPartial.h:339
@ DD_OFFSET
Definition: SgPartial.h:58
const QString & getName() const
Definition: SgPartial.h:283
double getD() const
Definition: SgPartial.h:291
void setNumObs(int n)
Definition: SgPartial.h:356
DataDomain getDataDomain() const
Definition: SgPartial.h:97
void zerofy()
Definition: SgPartial.h:408
@ Attr_IS_PARTIAL_SET
rise this bit on when the partial is assigned
Definition: SgPartial.h:53
virtual double calcAX(const SgMJD &, bool)
virtual double calc_aT_P_a(const SgVector &, const SgMJD &)
virtual double calcRateSigma(const SgMJD &)
virtual void deployParameters(SgParameter *, const SgMJD &tStart, const SgMJD &tFinis, const SgMJD &tRefer, const SgTaskConfig *)
virtual double calcRateRms4Sfo()
virtual void propagatePartials(const SgMJD &t)
virtual double calcRateSolution(const SgMJD &)
static const QString className()
virtual void getListOfActiveParameters(const SgMJD &t, QList< SgParameter * > &pars)
virtual double calc_P_a(const SgSymMatrix &, int, const SgMJD &)
virtual int getNumOfActiveParameters(const SgMJD &t)
int getNumOfPolynomials() const
Definition: SgPwlStorage.h:259
double sumT1P2_
Definition: SgPwlStorage.h:179
int numOfPolynomials_
Definition: SgPwlStorage.h:169
bool isPOrigOwner_
Definition: SgPwlStorage.h:180
const SgMJD & tRefer() const
Definition: SgPwlStorage.h:291
double sumX2P2_
Definition: SgPwlStorage.h:178
SgParameter * pOrig_
Definition: SgPwlStorage.h:165
int calcCurrentIdx(const SgMJD &t)
Definition: SgPwlStorage.h:345
SgParameter * pAi_
Definition: SgPwlStorage.h:167
double sumX1P2_
Definition: SgPwlStorage.h:177
SgParameter * pBi_
Definition: SgPwlStorage.h:168
double getElement(unsigned int i, unsigned int j) const
Definition: SgSymMatrix.h:274
double getElement(unsigned int i) const
Definition: SgVector.h:362