Commit 43a7a87f authored by Nils Rummler's avatar Nils Rummler
Browse files

improved documentation of SplineTest and added a derivation export to MATLAB2

parent 6e4cd2ae
......@@ -20,60 +20,26 @@
#include <ITABase/Math/Spline.h>
#include <ITAException.h>
#include <ITAStopWatch.h>
#include <iostream>
#include <fstream>
//using namespace std;
bool MyCompare(std::vector<float> a, std::vector<float> b, float epsilon) {
if (a.size() != b.size()) return false;
bool temp = true;
for (int i = 0; i < a.size(); i++) {
if (std::abs(a[i] - b[i]) > epsilon) {
std::cout << "Value of index " << i << " differs over the tolerance of +-"<<epsilon << std::endl;
temp = false;
}
}
return temp;
}
int main(int iNumInArgs, char* pcInArgs[])
{
/*
//beispiel von TM interaktiv, look if it's working in general
std::vector<float> vdSupportingPoints{1,7,12,15,19};
std::vector<float> vdDataPoints = {8,10,7,8,7};
int iPolynomialOrder = 3;
IW_ITA_BASE_SPLINE::ITABase::CPiecewisePolynomial myPoly1 = IW_ITA_BASE_SPLINE::ITABase::Spline(vdSupportingPoints,vdDataPoints,iPolynomialOrder);
if MyCompare(std::cout << "Quick and dirty test: "<< myPoly1.Value(5)<<" -hier soll grob 10 rauskommen;)";
using namespace ITABase::Math;
float epsilon = 0.1;
//Matlab spline. DataPoints sind aus randi
std::vector<float> vdDataPoints = { 13,14,2,14,10,2,5,9,15,15,3,15,11,4,0,-1,-5,-15,-11,-3,2 };
std::vector<float> vdX = { -10, float(1.5), float(-7.898),3, float(3.3), float(9.9),-2 };
std::vector<float> vdResult = { float(13.0000), float(17.4325), float(2.4282), float(8.0000), float(9.4143), float(11.4819), float(15.0000) };
int iPolynomialOrder = 3;
/*IW_ITA_BASE_SPLINE::ITABase::CPiecewisePolynomial myPoly1 = IW_ITA_BASE_SPLINE::ITABase::Spline(vdSupportingPoints, vdDataPoints, iPolynomialOrder);
std::cout << "MATLAB SPLINE TEST 1" << std::endl;
if (MyCompare(vdResult, myPoly1.Value(vdX),epsilon))
std::cout << "Test 1 bestanden" << std::endl;
std::vector<float> vdResult2 = { float(77.0000), float(7.9485), float(18.7512), float(50.0000), float(70.7647), float(36.3051), float(28.0000)
*/
//Test 2, Speedtest
bool SpeedTest() {
//the following data is random.
std::vector<float> vdSupportingPoints{ -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<float> vdDataPoints2{ 77, 80, 19, 49, 45, 65, 71, 76, 28, 68, 66, 17,12, 50, 96, 35, 59, 23, 76, 26, 51 };
std::vector<float> vdX = { -10, float(1.5), float(-7.898),float(3.3), float(3.3), float(9.9),float(-2.5),float(8.9),float(0.01),float(-4.3) };
IW_ITA_BASE_SPLINE::ITABase::CPiecewisePolynomial myPoly= ITABase::CubicSpline(vdSupportingPoints, vdDataPoints2);
CPiecewisePolynomial myPoly = CubicSpline(vdSupportingPoints, vdDataPoints2);
std::vector<float> result(10);
ITAStopWatch myWatch = ITAStopWatch();
std::cout << "Rueckgabe von piecwisePolynomial Objekten" << std::endl;
for (int k = 0; k < 100; k++) {
myWatch.start();
myPoly = ITABase::CubicSpline(vdSupportingPoints, vdDataPoints2);
myPoly = CubicSpline(vdSupportingPoints, vdDataPoints2);
myWatch.stop();
}
std::cout << myWatch << std::endl;
......@@ -82,19 +48,22 @@ int main(int iNumInArgs, char* pcInArgs[])
for (int k = 0; k < 100; k++) {
myWatch.start();
result = ITABase::CubicSpline(vdSupportingPoints, vdDataPoints2, vdX);
result = CubicSpline(vdSupportingPoints, vdDataPoints2, vdX);
myWatch.stop();
}
std::cout << myWatch << std::endl;
/*
//Test 3, export Coefficients to .txt to plot them in Matlab
return true;
}
//!creates one .txt file with the Points a spline function shall be constructed for and one with the cooeficients, this programm has computes. A third contains the coefficenc of the derivate. All can be read by the SplineTest.m into MATLAB.
void Compare2MATLAB(){
//the following data is random.
std::vector<float> vdSupportingPoints{ -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<float> vdDataPoints{ 77, 80, 19, 49, 45, 65, 71, 76, 28, 68, 66, 17,12, 50, 96, 35, 59, 23, 76, 26, 51 };
std::vector<float> vdX = { -10, float(1.5), float(-7.898),float(3.3), float(3.3), float(9.9),float(-2.5),float(8.9),float(0.01),float(-4.3) };
IW_ITA_BASE_SPLINE::ITABase::CPiecewisePolynomial myPoly = ITABase::CubicSpline(vdSupportingPoints, vdDataPoints);
CPiecewisePolynomial myPoly =CubicSpline(vdSupportingPoints, vdDataPoints);
CPiecewisePolynomial myDerivate = myPoly.Derivation();
std::vector<float>::const_iterator itCoeff = myPoly.getCoefficients();//Access to private property...
std::vector<float> vdCoeff = myPoly.Coefficients();
std::ofstream myFile;
myFile.open("points.txt");
for (int k = 0; k < vdDataPoints.size(); k++) {
......@@ -104,28 +73,87 @@ int main(int iNumInArgs, char* pcInArgs[])
myFile.open("coeff.txt");
for (int k = 0; k < vdDataPoints.size() - 1; k++) {
myFile << itCoeff[4 * k] << ", " << itCoeff[4 * k + 1] << ", " << itCoeff[4 * k + 2] << ", " << itCoeff[4 * k + 3] << std::endl;
myFile << vdCoeff[4 * k] << ", " << vdCoeff[4 * k + 1] << ", " << vdCoeff[4 * k + 2] << ", " << vdCoeff[4 * k + 3] << std::endl;
}
myFile.close();
//Test 4 last check up
//should equal the SupportingPoint
vdCoeff = myDerivate.Coefficients();
myFile.open("derivate.txt");
for (int k = 0; k < vdDataPoints.size() - 1; k++) {
myFile << vdCoeff[3 * k] << ", " << vdCoeff[3 * k + 1] << ", " << vdCoeff[3 * k + 2] << std::endl;
}
myFile.close();
return;
}
//!Checks the general behavior of the code
bool GeneralTest(){
//the following data is random.
std::vector<float> vdSupportingPoints{ -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<float> vdDataPoints{ 77, 80, 19, 49, 45, 65, 71, 76, 28, 68, 66, 17,12, 50, 96, 35, 59, 23, 76, 26, 51 };
std::vector<float> vdX = { -10, float(1.5), float(-7.898),float(3.3), float(3.3), float(9.9),float(-2.5),float(8.9),float(0.01),float(-4.3) };
CPiecewisePolynomial myPoly = CubicSpline(vdSupportingPoints, vdDataPoints);
std::cout << "At supportion Point 0, the calculated value should be 66: " << myPoly.Value(0) << std::endl;
//should get specific Value
std::cout << "At random Point x=0.5 the spline should interpolate ~40.9: " << myPoly.Value(0.5) << std::endl;
//deviation test
std::vector<float> vdBreakPoints = { 0, 1 };
std::vector<float> vdCoeff = { 1,1,1};
std::vector<float> vdCoeff = { 1,1,1 };
int iOrder = 2;
IW_ITA_BASE_SPLINE::ITABase::CPiecewisePolynomial myPoly2 = ITABase::CPiecewisePolynomial(vdBreakPoints,vdCoeff,iOrder);
CPiecewisePolynomial myPoly2 = CPiecewisePolynomial(vdBreakPoints, vdCoeff, iOrder);
myPoly2 = myPoly2.Derivation();
std::cout << "The deviation of x^2+x+1 should be: " << myPoly2.getCoefficients()[0] << " * x + " << myPoly2.getCoefficients()[1] << std::endl;
std::cout << "The deviation of x^2+x+1 should be: " << myPoly2.Coefficients()[0] << " * x + " << myPoly2.Coefficients()[1] << std::endl;
std::cout << "so the new polynoial only got " << myPoly2.NumCoefficients() << " coefficients." << std::endl;
//should trhow exception
myPoly2.Value(2);
*/
//exceptions for Piecewise Polynoms
std::cout << "Testing the Value function with Argument out of it's range:" << std::endl;
try { myPoly2.Value(2); }
catch (ITAException& err) {
std::cout << err << std::endl;
}
//exceptions for spline
std::cout<<"Testing spline with to few Points:" << std::endl;
try {
std::vector<float> vdSupportingPoints{ -10, -9 };
std::vector<float> vdDataPoints{ 77, 80 };
myPoly = CubicSpline(vdSupportingPoints, vdDataPoints);
}
catch (ITAException& err) {
std::cout << err << std::endl;
}
std::cout << "Testing non matching dimensions:"<<std::endl;
try {
std::vector<float> vdSupportingPoints{ -10, -5 ,-1,0,3 };//5points
std::vector<float> vdDataPoints{ 77, 80,4,5,-4,-1 };//6 Points
myPoly = CubicSpline(vdSupportingPoints, vdDataPoints);
}
catch(ITAException& err){
std::cout << err << std::endl;
}
std::cout << "Testing with non ascending supportingPoints" << std::endl;
try {
std::vector<float> vdSupportingPoints{ -10, 5 ,-1,0,3};
std::vector<float> vdDataPoints{ 77, 80,4,5,-4 };
myPoly = CubicSpline(vdSupportingPoints, vdDataPoints);
}
catch (ITAException& err) {
std::cout << err << std::endl;
}
return true;
}
//! SplineTest.cpp consists of several Test for Speed, functionality and DataExport to MATLAB, to compare and plot splines
int main(int iNumInArgs, char* pcInArgs[])
{
std::cout << "Checking starts" << std::endl;
std::cout << "Test 1: general Test for functions" << std::endl << std::endl;
GeneralTest();
std::cout << std::endl << "Test 2: Speedtest" << std::endl << std::endl;
SpeedTest();
std::cout << "The next function will write 3 .txt files that need to be imported to MATLAB with the help of SplineTest.m" << std::endl;
Compare2MATLAB();
return 0;
}
%Plots the desired Spline interpolation for the DataPoint Values at the
%Supporting Point location indicated in the provided .txt file and compares
%the MATLAB spline against the spline created with C++ by reading another
%.txt file
%.txt file. Compares also the first derivate of both splines
%
%Expected file Formats:
% coeff.txt
......@@ -14,7 +14,17 @@
% sup2, data2
% sup3, data3
% ... , ...
% derivate.txt
% a1, b1, c1
% a2, b2, c2
% a3, b3, c3
% ...,...,...,...
% The SupportingPoints need to be sorted ascending!
%
% You will find that the spline computed by matlab will overshoot close to
% the bordering sampling points more then the splines from ITA. This comes
% from using natural Splines(ITA) vs. clamped splines(Matlab). It's
% illustrated in the difference data ploted in both figures.
%% read Data from files
FID = fopen('points.txt');
......@@ -45,8 +55,27 @@ while ischar(tline)
k = k+1;
end
fclose(FID);
FID = fopen('derivate.txt');
if FID == -1
disp('unable to read indicated file');
return
end
deriv_coeff = zeros(size(supPoints,1)-1,3);%alocate
tline = fgetl(FID);
k=1;
while ischar(tline)
C = textscan(tline,'%f','Delimiter',',');
deriv_coeff(k,:) = C{1,1};
tline = fgetl(FID);
k = k+1;
end
fclose(FID);
%coeffs of deriv_coeff
%% plot
%spline
myPoly = mkpp(supPoints,coeff);
grain = (supPoints(end)-supPoints(1))/(10*size(supPoints,1)); %how dense shall the plotted points be?
......@@ -58,5 +87,23 @@ grid on
title 'Splines: Matlab vs. ITA'
plot(xx,ppval(myPoly,xx));
plot(xx,spline(supPoints,dataPoints,xx)-ppval(myPoly,xx));
legend('Data','Matlab','ITA','Diff');
legend('Sampling Points','Matlab','ITA','Diff');
hold off
%derivation of spline
myDerivate = mkpp(supPoints,deriv_coeff);
matlabDerivate = fnder(spline(supPoints,dataPoints));
grain = (supPoints(end)-supPoints(1))/(10*size(supPoints,1)); %how dense shall the plotted points be?
xx = [supPoints(1) : grain : supPoints(end)];
figure
plot(xx,ppval(matlabDerivate,xx));
hold on
grid on
title '1st derivitate of Splines: Matlab vs. ITA'
plot(xx,ppval(myDerivate,xx));
plot(xx,ppval(matlabDerivate,xx)-ppval(myDerivate,xx));
legend('Matlab','ITA','Diff');
hold off
\ No newline at end of file
-73.4604, 0, 27.4868
175.302, -146.921, -45.9736
-162.748, 203.683, -17.5923
100.69, -121.813, 23.343
-66.0135, 79.568, 2.22051
49.3634, -52.459, 15.775
-92.4402, 46.2679, 12.6795
164.398, -138.613, -33.4929
-142.15, 190.183, -7.70791
14.2029, -94.1177, 40.3245
70.3385, -65.7119, -39.5902
-22.5569, 74.9651, -34.9636
16.8892, 29.8513, 17.4446
-150, 63.6297, 64.1851
238.11, -236.37, -22.1851
-226.441, 239.85, -20.4449
232.654, -213.032, -7.03549
-257.175, 252.276, 12.5868
220.046, -262.074, 7.68815
-89.0092, 178.018, -34.3395
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment