6#include <QtTest/QtTest>
16const QString
WEBPAGE (
"https://tools.timodenk.com/cubic-spline-interpolation");
29void TestSpline::cleanupTestCase ()
34bool TestSpline::coefCheckX (
const vector<double> &t,
35#ifdef SHOWCOEFFICIENTS
36 const vector<SplinePair> &xy,
38 const vector<SplinePair> & ,
43 double aUntranslated = 0, bUntranslated = 0, cUntranslated = 0, dUntranslated = 0;
46#ifdef SHOWCOEFFICIENTS
48 <<
"(t,x) inputs to be copied to " <<
WEBPAGE.toLatin1().data()
50 for (i = 0; i < t.size(); i++) {
51 cout << t[i] <<
" " << xy[i].x() << endl;
54 <<
"x=d*(t-ti)^3+c*(t-ti)^2+b*(t-ti)+a natural cubic spline results to be used in this code"
56 for (i = 0; i < t.size() - 1; i++) {
61 s.m_elements[i].a().x(),
62 s.m_elements[i].b().x(),
63 s.m_elements[i].c().x(),
64 s.m_elements[i].d().x());
67 <<
"x=d*t^3+c*t^2+b*t+a outputs to be compared to results from " <<
WEBPAGE.toLatin1().data()
70 for (i = 0; i < t.size() - 1; i++) {
71 s.computeUntranslatedCoefficients (s.m_elements[i].a().x(),
72 s.m_elements[i].b().x(),
73 s.m_elements[i].c().x(),
74 s.m_elements[i].d().x(),
80#ifdef SHOWCOEFFICIENTS
94 success &= (qAbs (aUntranslated - -8.3608) < 8.3608 / 10000.0);
95 success &= (qAbs (bUntranslated - 4.2505) < 4.2505 / 10000.0);
96 success &= (qAbs (cUntranslated - -0.63092) < 0.63092 / 10000.0);
97 success &= (qAbs (dUntranslated - 0.035051) < 0.035051 / 10000.0);
102bool TestSpline::coefCheckY (
const vector<double> &t,
103#ifdef SHOWCOEFFICIENTS
104 const vector<SplinePair> &xy,
106 const vector<SplinePair> & ,
111 double aUntranslated = 0, bUntranslated = 0, cUntranslated = 0, dUntranslated = 0;
114#ifdef SHOWCOEFFICIENTS
116 <<
"(t,y) inputs to be copied to " <<
WEBPAGE.toLatin1().data()
118 for (i = 0; i < xy.size(); i++) {
119 cout << t[i] <<
" " << xy[i].y() << endl;
122 <<
"y=d*(t-ti)^3+c*(t-ti)^2+b*(t-ti)+a natural cubic spline results to be used in this code"
124 for (i = 0; i < xy.size() - 1; i++) {
129 s.m_elements[i].a().y(),
130 s.m_elements[i].b().y(),
131 s.m_elements[i].c().y(),
132 s.m_elements[i].d().y());
135 <<
"y=d*t^3+c*t^2+b*t+a outputs to be compared to results from " <<
WEBPAGE.toLatin1().data()
138 for (i = 0; i < t.size() - 1; i++) {
139 s.computeUntranslatedCoefficients (s.m_elements[i].a().y(),
140 s.m_elements[i].b().y(),
141 s.m_elements[i].c().y(),
142 s.m_elements[i].d().y(),
148#ifdef SHOWCOEFFICIENTS
162 success &= (qAbs (aUntranslated - -7.0) < 7.0 / 10000.0);
163 success &= (qAbs (bUntranslated - 3.5667) < 3.5667 / 10000.0);
164 success &= (qAbs (cUntranslated - -0.6) < 0.6 / 10000.0);
165 success &= (qAbs (dUntranslated - 0.033333) < 0.033333 / 10000.0);
170void TestSpline::coefShow (
const QString &leftHandSide,
171 const QString &independentVariable,
179 cout << leftHandSide.toLatin1().data() << scientific
180 << d <<
"*" << independentVariable.toLatin1().data() <<
"^3 + "
181 << c <<
"*" << independentVariable.toLatin1().data() <<
"^2 + "
182 << b <<
"*" << independentVariable.toLatin1().data() <<
" + "
183 << a <<
" (" << tLow <<
"<t<" << tHigh <<
")" << endl;
187void TestSpline::initTestCase ()
194 const bool NO_RESET =
false;
196 const bool NO_EXPORT_IMAGE_ONLY =
false;
197 const QString NO_EXPORT_IMAGE_EXTENSION;
213 NO_EXPORT_IMAGE_ONLY,
214 NO_EXPORT_IMAGE_EXTENSION,
220void TestSpline::testCoefficientsFromOrdinals ()
224 vector<SplinePair> xy;
236 vector<SplinePair>::const_iterator itr;
237 for (itr = xy.begin(); itr != xy.end(); itr++) {
238 t.push_back (counter++);
244 success &= coefCheckX (t,
247 success &= coefCheckY (t,
254void TestSpline::testSharpTransition ()
256 const int NUM_T = 60;
257 const double SPLINE_EPSILON = 0.01;
259 map<double, bool> xMerged;
264 vector<SplinePair> xyBefore;
276 vector<SplinePair>::const_iterator itrB;
277 for (itrB = xyBefore.begin(); itrB != xyBefore.end(); itrB++) {
279 t.push_back (pair.
x());
280 xMerged [pair.
x ()] =
true;
284 double tStart = t[0];
285 double tStop = t[t.size() - 1];
286 for (
int i = 0; i <= NUM_T; i++) {
287 double t = tStart + (double) i * (tStop - tStart) / (double) NUM_T;
289 if (xMerged.find (t) == xMerged.end ()) {
298 vector<SplinePair> xyAfter;
299 map<double, bool>::const_iterator itrX;
300 for (itrX = xMerged.begin(); itrX != xMerged.end(); itrX++) {
301 double x = itrX->first;
303 xyAfter.push_back (pair);
307 cout <<
"set datafile missing \"?\"" << endl;
308 cout <<
"plot \"gnuplot.in\" using 1:2 with linespoints, \"gnuplot.in\" using 1:3 with lines" << endl;
312 map<double, bool>::const_iterator itrM;
313 for (itrM = xMerged.begin(); itrM != xMerged.end(); itrM++) {
314 double x = itrM->first;
316 string yB =
"?", yA =
"?";
318 vector<SplinePair>::iterator itrB;
319 for (itrB = xyBefore.begin(); itrB != xyBefore.end(); itrB++) {
320 if (itrB->x() == x) {
328 vector<SplinePair>::iterator itrA;
329 for (itrA = xyAfter.begin(); itrA != xyAfter.end(); itrA++) {
330 if (itrA->x() == x) {
338 if (itrB != xyBefore.end() &&
339 itrA != xyAfter.end()) {
342 double yBefore = itrB->y();
343 double yAfter = itrA->y();
344 if (qAbs (yBefore - yAfter) > SPLINE_EPSILON) {
350 cout << x <<
", " << yB <<
", " << yA << endl;
357void TestSpline::testSplinesAsControlPoints ()
359 const int T_START = 1, T_STOP = 7;
360 const double SPLINE_EPSILON = 0.01;
361 const int NUM_T = 60;
366 vector<SplinePair> xy;
369 t.push_back (T_START);
375 t.push_back (T_STOP);
388 for (
int i = 0; i <= NUM_T; i++) {
389 double t = T_START + (double) i * (T_STOP - T_START) / (double) NUM_T;
391 SplinePair spBezier = s.interpolateControlPoints (t);
393 double xCoeff = spCoeff.
x();
394 double yCoeff = spCoeff.
y();
395 double xControl = spBezier.
x();
396 double yControl = spBezier.
y();
398 if (qAbs (xCoeff - xControl) > SPLINE_EPSILON) {
402 if (qAbs (yCoeff - yControl) > SPLINE_EPSILON) {
void initializeLogging(const QString &name, const QString &filename, bool isDebug)
const bool NO_EXPORT_ONLY
const QStringList NO_COMMAND_LINE
const QString NO_ERROR_REPORT_LOG_FILE
const bool NO_GNUPLOT_LOG_FILES
const QString NO_REGRESSION_OPEN_FILE
const QStringList NO_LOAD_STARTUP_FILES
const bool NO_REGRESSION_IMPORT
const bool NO_DROP_REGRESSION
const QString WEBPAGE("https://tools.timodenk.com/cubic-spline-interpolation")
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.
double y() const
Get method for y.
double x() const
Get method for x.
Cubic interpolation given independent and dependent value vectors.
Unit test of spline library.
TestSpline(QObject *parent=0)
Single constructor.