2 #include "MainWindow.h" 5 #include <QtTest/QtTest> 7 #include "SplinePair.h" 9 #include "Test/TestSpline.h" 15 const QString WEBPAGE (
"https://tools.timodenk.com/cubic-spline-interpolation");
21 const int NUM_ITERATIONS = 24;
28 void TestSpline::cleanupTestCase ()
33 bool TestSpline::coefCheckX (
const vector<double> &t,
34 #ifdef SHOWCOEFFICIENTS
35 const vector<SplinePair> &xy,
37 const vector<SplinePair> & ,
42 double aUntranslated = 0, bUntranslated = 0, cUntranslated = 0, dUntranslated = 0;
45 #ifdef SHOWCOEFFICIENTS 47 <<
"(t,x) inputs to be copied to " << WEBPAGE.toLatin1().data()
49 for (i = 0; i < t.size(); i++) {
50 cout << t[i] <<
" " << xy[i].x() << endl;
53 <<
"x=d*(t-ti)^3+c*(t-ti)^2+b*(t-ti)+a natural cubic spline results to be used in this code" 55 for (i = 0; i < t.size() - 1; i++) {
60 s.m_elements[i].a().x(),
61 s.m_elements[i].b().x(),
62 s.m_elements[i].c().x(),
63 s.m_elements[i].d().x());
66 <<
"x=d*t^3+c*t^2+b*t+a outputs to be compared to results from " << WEBPAGE.toLatin1().data()
69 for (i = 0; i < t.size() - 1; i++) {
70 s.computeUntranslatedCoefficients (s.m_elements[i].a().x(),
71 s.m_elements[i].b().x(),
72 s.m_elements[i].c().x(),
73 s.m_elements[i].d().x(),
79 #ifdef SHOWCOEFFICIENTS 93 success &= (qAbs (aUntranslated - -8.3608) < 8.3608 / 10000.0);
94 success &= (qAbs (bUntranslated - 4.2505) < 4.2505 / 10000.0);
95 success &= (qAbs (cUntranslated - -0.63092) < 0.63092 / 10000.0);
96 success &= (qAbs (dUntranslated - 0.035051) < 0.035051 / 10000.0);
101 bool TestSpline::coefCheckY (
const vector<double> &t,
102 #ifdef SHOWCOEFFICIENTS
103 const vector<SplinePair> &xy,
105 const vector<SplinePair> & ,
110 double aUntranslated = 0, bUntranslated = 0, cUntranslated = 0, dUntranslated = 0;
113 #ifdef SHOWCOEFFICIENTS 115 <<
"(t,y) inputs to be copied to " << WEBPAGE.toLatin1().data()
117 for (i = 0; i < xy.size(); i++) {
118 cout << t[i] <<
" " << xy[i].y() << endl;
121 <<
"y=d*(t-ti)^3+c*(t-ti)^2+b*(t-ti)+a natural cubic spline results to be used in this code" 123 for (i = 0; i < xy.size() - 1; i++) {
128 s.m_elements[i].a().y(),
129 s.m_elements[i].b().y(),
130 s.m_elements[i].c().y(),
131 s.m_elements[i].d().y());
134 <<
"y=d*t^3+c*t^2+b*t+a outputs to be compared to results from " << WEBPAGE.toLatin1().data()
137 for (i = 0; i < t.size() - 1; i++) {
138 s.computeUntranslatedCoefficients (s.m_elements[i].a().y(),
139 s.m_elements[i].b().y(),
140 s.m_elements[i].c().y(),
141 s.m_elements[i].d().y(),
147 #ifdef SHOWCOEFFICIENTS 161 success &= (qAbs (aUntranslated - -7.0) < 7.0 / 10000.0);
162 success &= (qAbs (bUntranslated - 3.5667) < 3.5667 / 10000.0);
163 success &= (qAbs (cUntranslated - -0.6) < 0.6 / 10000.0);
164 success &= (qAbs (dUntranslated - 0.033333) < 0.033333 / 10000.0);
169 void TestSpline::coefShow (
const QString &leftHandSide,
170 const QString &independentVariable,
178 cout << leftHandSide.toLatin1().data() << scientific
179 << d <<
"*" << independentVariable.toLatin1().data() <<
"^3 + " 180 << c <<
"*" << independentVariable.toLatin1().data() <<
"^2 + " 181 << b <<
"*" << independentVariable.toLatin1().data() <<
" + " 182 << a <<
" (" << tLow <<
"<t<" << tHigh <<
")" << endl;
186 void TestSpline::initTestCase ()
188 const QString NO_ERROR_REPORT_LOG_FILE;
189 const QString NO_REGRESSION_OPEN_FILE;
190 const bool NO_GNUPLOT_LOG_FILES =
false;
191 const bool NO_REGRESSION_IMPORT =
false;
192 const bool NO_RESET =
false;
193 const bool NO_EXPORT_ONLY =
false;
194 const bool NO_EXPORT_IMAGE_ONLY =
false;
195 const QString NO_EXPORT_IMAGE_EXTENSION;
196 const bool DEBUG_FLAG =
false;
197 const QStringList NO_LOAD_STARTUP_FILES;
198 const QStringList NO_COMMAND_LINE;
200 initializeLogging (
"engauge_test",
205 NO_REGRESSION_OPEN_FILE,
206 NO_REGRESSION_IMPORT,
207 NO_GNUPLOT_LOG_FILES,
210 NO_EXPORT_IMAGE_ONLY,
211 NO_EXPORT_IMAGE_EXTENSION,
212 NO_LOAD_STARTUP_FILES,
217 void TestSpline::testCoefficientsFromOrdinals ()
221 vector<SplinePair> xy;
233 vector<SplinePair>::const_iterator itr;
234 for (itr = xy.begin(); itr != xy.end(); itr++) {
235 t.push_back (counter++);
241 success &= coefCheckX (t,
244 success &= coefCheckY (t,
251 void TestSpline::testSharpTransition ()
253 const int NUM_T = 60;
254 const double SPLINE_EPSILON = 0.01;
256 map<double, bool> xMerged;
261 vector<SplinePair> xyBefore;
273 vector<SplinePair>::const_iterator itrB;
274 for (itrB = xyBefore.begin(); itrB != xyBefore.end(); itrB++) {
276 t.push_back (pair.
x());
277 xMerged [pair.
x ()] =
true;
281 double tStart = t[0];
282 double tStop = t[t.size() - 1];
283 for (
int i = 0; i <= NUM_T; i++) {
284 double t = tStart + (double) i * (tStop - tStart) / (double) NUM_T;
286 if (xMerged.find (t) == xMerged.end ()) {
292 Spline s (t, xyBefore, SPLINE_DISABLE_T_CHECK);
295 vector<SplinePair> xyAfter;
296 map<double, bool>::const_iterator itrX;
297 for (itrX = xMerged.begin(); itrX != xMerged.end(); itrX++) {
298 double x = itrX->first;
300 xyAfter.push_back (pair);
304 cout <<
"set datafile missing \"?\"" << endl;
305 cout <<
"plot \"gnuplot.in\" using 1:2 with linespoints, \"gnuplot.in\" using 1:3 with lines" << endl;
309 map<double, bool>::const_iterator itrM;
310 for (itrM = xMerged.begin(); itrM != xMerged.end(); itrM++) {
311 double x = itrM->first;
313 string yB =
"?", yA =
"?";
315 vector<SplinePair>::iterator itrB;
316 for (itrB = xyBefore.begin(); itrB != xyBefore.end(); itrB++) {
317 if (itrB->x() == x) {
325 vector<SplinePair>::iterator itrA;
326 for (itrA = xyAfter.begin(); itrA != xyAfter.end(); itrA++) {
327 if (itrA->x() == x) {
335 if (itrB != xyBefore.end() &&
336 itrA != xyAfter.end()) {
339 double yBefore = itrB->y();
340 double yAfter = itrA->y();
341 if (qAbs (yBefore - yAfter) > SPLINE_EPSILON) {
347 cout << x <<
", " << yB <<
", " << yA << endl;
354 void TestSpline::testSplinesAsControlPoints ()
356 const int T_START = 1, T_STOP = 7;
357 const double SPLINE_EPSILON = 0.01;
358 const int NUM_T = 60;
363 vector<SplinePair> xy;
366 t.push_back (T_START);
372 t.push_back (T_STOP);
385 for (
int i = 0; i <= NUM_T; i++) {
386 double t = T_START + (double) i * (T_STOP - T_START) / (double) NUM_T;
388 SplinePair spBezier = s.interpolateControlPoints (t);
390 double xCoeff = spCoeff.
x();
391 double yCoeff = spCoeff.
y();
392 double xControl = spBezier.
x();
393 double yControl = spBezier.
y();
395 if (qAbs (xCoeff - xControl) > SPLINE_EPSILON) {
399 if (qAbs (yCoeff - yControl) > SPLINE_EPSILON) {
Cubic interpolation given independent and dependent value vectors.
double y() const
Get method for y.
TestSpline(QObject *parent=0)
Single constructor.
double x() const
Get method for x.
Unit test of spline library.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Single X/Y pair for cubic spline interpolation initialization and calculations.