General Purpose Geodetic Library
SgCubicSpline.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 
24 #include <SgCubicSpline.h>
25 #include <SgLogger.h>
26 
27 
28 
29 
30 /*=======================================================================================================
31 *
32 * METHODS:
33 *
34 *======================================================================================================*/
35 //
36 // static first:
37 const QString SgCubicSpline::className()
38 {
39  return "SgCubicSpline";
40 };
41 
42 
43 
44 //
46 {
47  isOk_ = false;
48  if (dimension_>0 && numOfRecords_>3)
49  {
50  // check the order of arg:
51  double f=argument_.getElement(0);
52  for (int i=1; i<numOfRecords_; i++)
53  {
54  if (f >= argument_.getElement(i))
55  {
57  ": the argument [" + QString().setNum(i) + "] has a wrong order, the table is skipped");
58  for (int k=0; k<numOfRecords_; k++)
60  QString().sprintf(": [%04d] = %.6f", k, argument_.getElement(k)));
61  return;
62  };
63  f = argument_.getElement(i);
64  };
65  for (int i=0; i<dimension_; i++)
66  solveSpline(i);
67  isOk_ = true;
68  };
69 };
70 
71 
72 
73 //
75 {
76  SgVector aleph(numOfRecords_), beth(numOfRecords_);
77  double f;
78 
79  f = h(1) + h(2);
80  aleph(2) = -0.5*h(2)/f;
81  beth (2) = 3.0*(table_.getElement(0, nCol)/h(1) -
82  table_.getElement(1, nCol)*(1.0/h(1) + 1.0/h(2)) +
83  table_.getElement(2, nCol)/h(2)
84  )/f;
85 
86  for (int i=2; i<numOfRecords_-2; i++)
87  {
88  f = aleph(i)*h(i) + 2.0*(h(i) + h(i+1));
89  aleph(i+1) = -h(i+1)/f;
90  beth (i+1) = (6.0*( table_.getElement(i-1, nCol)/h(i) -
91  table_.getElement(i, nCol)*(1.0/h(i) + 1.0/h(i+1)) +
92  table_.getElement(i+1, nCol)/h(i+1)
93  ) - beth(i)*h(i))/f;
94  };
95 
96  coeffs_(numOfRecords_-1, nCol) = 0.0;
97  coeffs_(numOfRecords_-2, nCol) =
98  (6.0*(table_.getElement(numOfRecords_-3, nCol)/h(numOfRecords_-2) -
99  table_.getElement(numOfRecords_-2, nCol)*(1.0/h(numOfRecords_-2) + 1.0/h(numOfRecords_-1)) +
101  ) - h(numOfRecords_-2)*beth(numOfRecords_-2)
102  )/(h(numOfRecords_-2)*aleph(numOfRecords_-2) + 2.0*(h(numOfRecords_-2) + h(numOfRecords_-1)));
103 
104  for (int i=numOfRecords_-3; i>0; i--)
105  coeffs_(i, nCol) = aleph.getElement(i+1)*coeffs_.getElement(i+1, nCol) + beth.getElement(i+1);
106 
107  coeffs_(0, nCol) = 0.0;
108 };
109 
110 
111 
112 //
113 double SgCubicSpline::spline(double arg, int nColumn, double &r)
114 {
115  double d=0.0;
116  r = 0.0;
117  if (!isOk_)
118  return d;
119 
120  // get the idx:
121  int nIdx=0;
122  if (arg <= argument_.getElement(1))
123  nIdx = 1;
124  else if (argument_.getElement(numOfRecords_-1) <= arg)
125  nIdx = numOfRecords_ - 1;
126  else
127  {
128  int i=2;
129  while (i<numOfRecords_ && argument_.getElement(i-1) <= arg)
130  i++;
131  nIdx = i - 1;
132  };
133 
134  double f1, f2, h2;
135 
136  f1 = argument_.getElement(nIdx) - arg;
137  f2 = arg - argument_.getElement(nIdx-1);
138  h2 = h(nIdx)*h(nIdx);
139 
140  d = ( coeffs_.getElement(nIdx-1, nColumn)*f1*f1*f1/6.0 +
141  coeffs_.getElement(nIdx, nColumn)*f2*f2*f2/6.0 +
142  (table_.getElement(nIdx-1, nColumn) - coeffs_.getElement(nIdx-1, nColumn)*h2/6.0)*f1 +
143  (table_.getElement(nIdx, nColumn) - coeffs_.getElement(nIdx, nColumn)*h2/6.0)*f2)/h(nIdx);
144 
145  r = (-coeffs_.getElement(nIdx-1, nColumn)*f1*f1/2.0 +
146  coeffs_.getElement(nIdx, nColumn)*f2*f2/2.0 +
147  table_.getElement(nIdx, nColumn) - table_.getElement(nIdx-1, nColumn) +
148  (coeffs_.getElement(nIdx-1, nColumn) - coeffs_.getElement(nIdx, nColumn))*h2/6.0 )/h(nIdx);
149 
150  return d;
151 };
152 /*=====================================================================================================*/
153 
154 
155 
156 
157 /*=======================================================================================================
158 *
159 * FRIENDS:
160 *
161 *======================================================================================================*/
162 //
163 
164 
165 
166 /*=====================================================================================================*/
167 //
168 // aux functions:
169 //
170 
171 
172 // i/o:
173 
174 
175 /*=====================================================================================================*/
176 //
177 // constants:
178 //
179 
180 
181 /*=====================================================================================================*/
SgLogger * logger
Definition: SgLogger.cpp:231
void prepare4Spline()
static const QString className()
SgMatrix table_
SgMatrix coeffs_
void solveSpline(int)
double h(int i) const
double spline(double arg, int nColumn, double &r)
SgVector argument_
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ INTERP
Definition: SgLogger.h:71
double getElement(unsigned int i, unsigned int j) const
Definition: SgMatrix.h:385
double getElement(unsigned int i) const
Definition: SgVector.h:362