From 36c4b40a0f2789fd87db3be3fe9e27e0aaaba1c6 Mon Sep 17 00:00:00 2001
From: Claudio Scafuri <claudio.scafuri@elettra.eu>
Date: Wed, 25 Sep 2024 13:52:10 +0200
Subject: [PATCH] debian 12, restructured

---
 Makefile                                      |   82 +-
 .../interpolatingpolynomial.h                 |    0
 interpolator.h => include/interpolator.h      |    0
 .../multipolynomial.h                         |    0
 periodicspline.h => include/periodicspline.h  |    0
 spline.h => include/spline.h                  |    0
 spltest.cpp                                   |  138 ---
 interpolator.cpp => src/interpolator.cpp      |    0
 .../multipolynomial.cpp                       |    0
 periodicspline.cpp => src/periodicspline.cpp  |    0
 spline.cpp => src/spline.cpp                  |    0
 test_freespline.cpp                           |  263 ----
 test_inverse.cpp                              |   67 --
 test_multipoly.cpp                            |  282 -----
 test_obj/test_runner.gcda                     |  Bin 0 -> 27324 bytes
 test_obj/test_runner.gcno                     |  Bin 0 -> 248972 bytes
 test_periodicspline.cpp                       |  242 ----
 test_spline.cpp                               |  209 ----
 test_src/test_runner.cpp                      | 1064 +++++++++++++++++
 19 files changed, 1117 insertions(+), 1230 deletions(-)
 rename interpolatingpolynomial.h => include/interpolatingpolynomial.h (100%)
 rename interpolator.h => include/interpolator.h (100%)
 rename multipolynomial.h => include/multipolynomial.h (100%)
 rename periodicspline.h => include/periodicspline.h (100%)
 rename spline.h => include/spline.h (100%)
 delete mode 100644 spltest.cpp
 rename interpolator.cpp => src/interpolator.cpp (100%)
 rename multipolynomial.cpp => src/multipolynomial.cpp (100%)
 rename periodicspline.cpp => src/periodicspline.cpp (100%)
 rename spline.cpp => src/spline.cpp (100%)
 delete mode 100644 test_freespline.cpp
 delete mode 100644 test_inverse.cpp
 delete mode 100644 test_multipoly.cpp
 create mode 100644 test_obj/test_runner.gcda
 create mode 100644 test_obj/test_runner.gcno
 delete mode 100644 test_periodicspline.cpp
 delete mode 100644 test_spline.cpp
 create mode 100644 test_src/test_runner.cpp

diff --git a/Makefile b/Makefile
index 9553e53..52aa79c 100644
--- a/Makefile
+++ b/Makefile
@@ -40,10 +40,17 @@ DEBUG = -ggdb3
 RANLIB = ranlib
 #OPTIM = -O2
 
-INCLUDE = -I.
+INCLUDE = -I include
 CXXFLAGS += -std=c++17 -fPIC -D_REENTRANT $(DEBUG) $(OPTIM) $(WARN) $(INCLUDE)
 CFLAGS = $(CXXFLAGS)
 PROJECTHOME = .
+
+SRC_DIR = src
+OBJ_DIR = obj
+TEST_DIR = test
+TEST_OBJ_DIR = test_obj
+TEST_RUNNER = test_runner
+
 ##############################################
 # support for shared libray versioning
 #
@@ -84,9 +91,12 @@ LOCALDESTDIRHEADERS = $(LOCALPREFIX)/include
 # header files to be installed for distribution
 INSTHEADERS = periodicspline.h spline.h multipolynomial.h interpolatingpolynomial.h interpolator.h
 ################################################
+SRCS = $(wildcard $(SRC_DIR)/*.cpp)
+OBJS = $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS))
 
-OBJS = periodicspline.o spline.o multipolynomial.o interpolator.o
 
+TEST_SRCS = test_src/test_runner.cpp
+TEST_OBJS = test_obj/test_runner.o
 
 ########################################################################################
 # compiler warnings
@@ -97,48 +107,59 @@ WARN+= -pedantic -Wno-long-long # test with mysql due to long long variables!
 
 #######################################
 #options for coverage and performance analysis
-#DEBUG += -fprofile-arcs -ftest-coverage -pg
-#LDFLAGS += -fprofile-arcs -ftest-coverage -pg
+DEBUG += -fprofile-arcs -ftest-coverage -pg
+LDFLAGS += -fprofile-arcs -ftest-coverage -pg
 #####################################
 
+# Compile source files to object files
+$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
+	@mkdir -p $(OBJ_DIR)
+	$(CXX) $(CXXFLAGS) -c $< -o $@
+	
 
-all: lib libstatic test
-
-lib: $(PROJECTHOME)/lib/$(DT_SHLIB)
-
-libstatic: $(PROJECTHOME)/lib/$(LIBRARY)
-
-check: check_spline check_multipoly
+# Compile test source files to object files
+$(TEST_OBJ_DIR)/%.o: $(TEST_DIR)/%.cpp
+	@mkdir -p $(TEST_OBJ_DIR)
+	$(CXX) $(CXXFLAGS) -c $< -o $@
 
+$(TEST_OBJS): $(TEST_SRCS)
+	$(CXX) $(CXXFLAGS) -c $< -o $@
+	
+# Test target: compile and link the test executable
+test: $(TEST_OBJS) $(OBJS)
+	$(info [$(TEST_OBJS)])
+	$(info [$(TEST_SRCS)])
+	$(info [$(OBJS)])
+	$(CXX) $(CXXFLAGS) $(TEST_OBJS) $(OBJS) -o $(TEST_RUNNER)
+	./$(TEST_RUNNER)
 
-test: test_spline test_inverse test_freespline test_multipoly test_periodicspline spltest
 
-test_spline: test_spline.o spline.o interpolator.o
+all: lib libstatic 
 
-test_inverse: test_inverse.o spline.o interpolator.o
+lib: $(PROJECTHOME)/lib/$(DT_SHLIB)
 
-test_freespline: test_freespline.o spline.o interpolator.o
+libstatic: $(PROJECTHOME)/lib/$(LIBRARY)
 
-test_periodicspline: test_periodicspline.o periodicspline.o interpolator.o
+check: test
+	gcov test_src/test_runner.cpp
+	gcov src/spline.cpp
+	gcov src/interpolator.cpp
+	gcov src/multipolynomial.cpp
+	gcov src/peridocspline.cpp	
+	valgrind --num-callers=20 --leak-check=yes --leak-resolution=high --leak-check=full --show-reachable=yes --log-file=test_runner.grind ./test_runner
 
-spltest: spltest.o spline.o interpolator.o
 
-test_multipoly: test_multipoly.o multipolynomial.o interpolator.o
 
 
-check_spline: test_spline
+check_exec: test_runner
 	./test_spline
-	gcov test_spline.cpp
-	gcov spline.cpp
-	gcov interpolator.cpp
+	gcov test_src/test_runner.cpp
+	gcov src/spline.cpp
+	gcov src/interpolator.cpp
+	gcov src/multipolynomial.cpp
+	gcov src/peridocspline.cpp	
 	valgrind --num-callers=20 --leak-check=yes --leak-resolution=high --leak-check=full --show-reachable=yes --log-file=test_spline.grind ./test_spline
 
-check_multipoly: test_multipoly
-	gcov test_multipoly.cpp
-	gcov multipoly.cpp
-	gcov interpolator.cpp
-	valgrind --num-callers=20 --leak-check=yes --leak-resolution=high --leak-check=full --show-reachable=yes --log-file=test_multipoly.grind ./test_multipoly
-
 $(PROJECTHOME)/lib/$(LIBRARY):$(OBJS) $(MAKEFILE)
 #	@echo "Archiving $(LIBRARY) ... $(OBJS)"
 	mkdir -p -m 755 $(PROJECTHOME)/lib
@@ -160,7 +181,10 @@ doc:
 docclean:
 	rm -rf docs doxy.log
 clean:
-	rm -f *.o core* *.gcov *.gcno *.gcda *.grind *grind.core.* *.valgrind dump* gmon.out doxygen_log.txt dump* *.csv
+	rm -rf $(OBJ_DIR)
+	rm -rf $(TEST_RUNNER)
+	rm -rf $(TEST_OBJS)
+	rm -f *.o core* *.gcov *.gcno *.gcda *.grind *grind.core.* *.valgrind dump* gmon.out doxygen_log.txt dump* *.csv perf.data
 	rm -f test_spline test_inverse test_periodicspline test_freespline test_multipoly test_magnets test_dipole test_quadrupole test_sextupole test_kicker test_solenoid spltest
 	rm -f *.csv
 	rm -f doxy.log
diff --git a/interpolatingpolynomial.h b/include/interpolatingpolynomial.h
similarity index 100%
rename from interpolatingpolynomial.h
rename to include/interpolatingpolynomial.h
diff --git a/interpolator.h b/include/interpolator.h
similarity index 100%
rename from interpolator.h
rename to include/interpolator.h
diff --git a/multipolynomial.h b/include/multipolynomial.h
similarity index 100%
rename from multipolynomial.h
rename to include/multipolynomial.h
diff --git a/periodicspline.h b/include/periodicspline.h
similarity index 100%
rename from periodicspline.h
rename to include/periodicspline.h
diff --git a/spline.h b/include/spline.h
similarity index 100%
rename from spline.h
rename to include/spline.h
diff --git a/spltest.cpp b/spltest.cpp
deleted file mode 100644
index 3bd43a2..0000000
--- a/spltest.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-/* $Author: claudio $
- *
- * $Revision: 1.1.1.1 $
- *
- * $Log: spltest.cpp,v $
- * Revision 1.1.1.1  2012-09-05 08:17:22  claudio
- * Interpolator utility classes
- *
- */
-
-#include <cstdlib>
-#include <iostream>
-#include <iomanip>
-#include "spline.h"
-
-
-using namespace std;
-using namespace Interpolator;
-
-int main(){
-	
-	try{
-		double i_qd[]={0.0,14.8056,74.028,148.056,222.084,296.112,333.126,370.14};
-		double g_qd[]={0.0,0.7745,3.9519,7.9231,11.8187,15.7069,17.5649,19.2667};
-// 		doubleVector iqd;
-// 		doubleVector fieldqd;
-		vector<double> iqd;
-		vector<double> fieldqd;
-
-		//controle printout of table
-		int PRECISION=16;
-		int WIDTH=20;
-		
-		for (unsigned int i=0;i<8;i++){
-			iqd.push_back(i_qd[i]);
-			fieldqd.push_back(g_qd[i]);
-			
-			cout << setprecision(PRECISION) << setw(WIDTH) << right;
-			cout << iqd[i];
-			
-			cout << setprecision(PRECISION) << setw(WIDTH) << right;
-			cout << fieldqd[i] << endl;
-		}
-		Spline* dir= new Spline(iqd,fieldqd);
-		Spline* inv= new Spline(fieldqd,iqd);
-		
-		
-		double min=0.0,max=i_qd[7];
-		unsigned int steps=200;
-		double mincur=min;
-		double inccur=(max-min)/steps;
-		double I,g,inv_I;
-		cout << setw(WIDTH) << right;
-		cout << "I";
-		
-		cout << setw(WIDTH) << right;
-		cout << "g" ;
-		
-		cout << setw(WIDTH) << right;
-		cout << "inv_I" ;
-		
-		
-
-		cout << endl;
-		for(unsigned int i=0;i<=steps;i++){
-			I=mincur+ i*inccur;
-			g=dir->evaluate(I);
-			inv_I=inv->evaluate(g);
-			
-			
-			
-			cout << setprecision(PRECISION) << setw(WIDTH) << right;
-			cout << I;
-			
-			cout << setprecision(PRECISION) << setw(WIDTH) << right;
-			cout  << g;
-			
-			cout << setprecision(PRECISION) << setw(WIDTH) << right;
-			cout << inv_I;
-			
-			
-			if(I != 0.0) {
-				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-				cout  << 10000.0*((I-inv_I)/I);
-			}
-			else{
-				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-				cout  << 0.0;
-			}
-			
-// 			if(dir->bracket(g,I,1.0e-4,xmin,xmax)){
-// 				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-// 				cout << xmin;
-// 				
-// 				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-// 				cout << xmax;
-// 				
-// 				double I2=dir->solve(g,xmin,xmax,1.0e-8,100);
-// 				
-// 				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-// 				cout << I2;
-// 				
-// 			}
-// 			else{
-// 				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-// 				cout << "------";
-// 				
-// 				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-// 				cout << "++++++";
-// 				
-// 				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-// 				cout << "//////";
-// 			}
-			{
-
-				
-				double I2=dir->inverse_evaluate(g,I);
-				
-				cout << setprecision(PRECISION) << setw(WIDTH) << right;
-				cout << I2;
-				
-			}
-
-			
-			cout << endl;
-		}
-		
-		delete inv;
-		delete dir;
-	}
-	catch(std::invalid_argument& ex)
-	{
-		cout<<ex.what()<<endl;
-	}
-	return 0;
-}
diff --git a/interpolator.cpp b/src/interpolator.cpp
similarity index 100%
rename from interpolator.cpp
rename to src/interpolator.cpp
diff --git a/multipolynomial.cpp b/src/multipolynomial.cpp
similarity index 100%
rename from multipolynomial.cpp
rename to src/multipolynomial.cpp
diff --git a/periodicspline.cpp b/src/periodicspline.cpp
similarity index 100%
rename from periodicspline.cpp
rename to src/periodicspline.cpp
diff --git a/spline.cpp b/src/spline.cpp
similarity index 100%
rename from spline.cpp
rename to src/spline.cpp
diff --git a/test_freespline.cpp b/test_freespline.cpp
deleted file mode 100644
index 1856840..0000000
--- a/test_freespline.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * program to test spline class
- *
- * $Author: claudio $
- *
- * $Revision: 1.1.1.1 $
- *
- * $Log: test_freespline.cpp,v $
- * Revision 1.1.1.1  2012-09-05 08:17:22  claudio
- * Interpolator utility classes
- *
- *
- */
-
-#include <iostream>
-#include <fstream>
-#include "spline.h"
-#include <cmath>
-
-
-using namespace std;
-using namespace Interpolator;
-
-int main(){
-	cout<< "test of Spline interpolator class" << endl;
-	doubleVector x0,y0;
-	const int NP=30;
-	for(int i=0; i < NP; i++){
-		x0.push_back(i*i*.02);
-		y0.push_back(sin(i*i*.02));
-	}
-	Spline* test_spline = new Spline(x0,y0,NAN,0.0);
-	{
-		doubleVector a;
-		vector<double> b;
-		test_spline->get_base_points(a,b);
-		cout<<"test get_base_points()"<<endl;
-		for(int i=0; i < NP; i++ )
-			if((x0[i] != a[i]) ||(y0[i] != b[i])){
-				cout << i << " " << x0[i] << " " << a[i] << " | "<< y0[i] << " " << b[i] << endl;
-				return -1;
-			}
-		
-	}
-	{
-		cout << "test get_range()" << endl;
-		double minx,maxx;
-		test_spline->get_range(minx,maxx);
-		if( (minx != x0[0]) || (maxx != x0[NP-1]) ){
-			cout << minx << " " << x0[0] << " | " << maxx << " " << x0[NP-1] << endl;
-			return -1;
-		}
-	}
-	{
-		cout << "test evaluate()" << endl;
-		double xn=0.02;
-		double yn=test_spline->evaluate(xn);
-		cout << xn << " " << yn << endl;
-		yn=test_spline->evaluate(x0[5]);
-		cout << xn << " " << yn << " " << y0[5] << endl;	
-	}
-	{
-		cout << "test evaluate()" << endl;
-		double xn=0.02;
-		double yn=test_spline->evaluate(xn);
-		cout << xn << " " << yn << endl;
-		yn=test_spline->evaluate(x0[5]);
-		cout << xn << " " << yn << " " << y0[5] << endl;	
-	}
-	{	cout << "test evaluate()for plot" << endl;
-		doubleVector X;
-		doubleVector Y;
-		double range=x0[NP-1];
-		double nsteps=300;
-		for(int i=0;i<=nsteps;i++){
-			X.push_back((range*i)/nsteps);
-			Y.push_back(test_spline->evaluate(X[i]));
-		}
-		//print out data
-		cout<<"---------------------------"<<endl;
-		for(int i=0; i < NP; i++) cout<<x0[i]<<"\t"<<y0[i]<<endl;
-		cout<<"---------------------------"<<endl;
-		for(int i=0; i < nsteps; i++) cout<<X[i]<<"\t"<<Y[i]<<endl;
-		cout<<"+++++++++++++++++++++++++++"<<endl;
-	}
-	{	
-		cout << "test evaluate()for doubleVector" << endl;
-		doubleVector X;
-		doubleVector Y;
-		double range=x0[NP-1];
-		double nsteps=300;
-		for(int i=0;i<=nsteps;i++)
-			X.push_back((range*i)/nsteps);
-		Y=test_spline->evaluate(X);
-		//print out data
-		cout<<"###########################"<<endl;
-		for(int i=0; i < nsteps; i++) cout<<X[i]<<"\t"<<Y[i]<<endl;
-		cout<<"***************************"<<endl;
-	}
-	{
-		cout << "test range exception" << endl;
-		try{
-			test_spline->evaluate(-10.0);
-			cerr << "range_error not thrown!" << endl;
-		}
-		catch(std::range_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "test constructor with unequal lengths" << endl;
-		try{
-			doubleVector x,y;
-			x.push_back(1.0);
-			x.push_back(2.0);
-			x.push_back(3.0);
-			
-			y.push_back(4.0);
-			y.push_back(5.0);
-			Spline spl(x,y,NAN,0.0);
-			cerr << "length_error not thrown!" << endl;
-		}
-		catch(std::length_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "test constructor with out of order data" << endl;
-		try{
-			doubleVector x,y;
-			x.push_back(1.0);
-			x.push_back(2.0);
-			x.push_back(1.5);
-			
-			y.push_back(4.0);
-			y.push_back(5.0);
-			y.push_back(6.0);
-			Spline spl(x,y,NAN,0.0);
-			cerr << "domain_error not thrown!" << endl;
-		}
-		catch(std::domain_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "Test copy constructor" << endl;
-		Spline copy_spline(*test_spline);
-		double minx,maxx,copyminx,copymaxx;
-		test_spline->get_range(minx,maxx);
-		copy_spline.get_range(copyminx,copymaxx);
-		if( (minx != copyminx) || (maxx != copymaxx) ){
-			cerr << "COPY FAILED!" << endl;
-			return -1;
-		}
-		double range=x0[NP-1];
-		double nsteps=100;
-		for(int i=0;i<nsteps;i++){
-			double val=(range*i)/nsteps;
-			double y,ycopy;
-			ycopy=copy_spline.evaluate(val);
-			y=test_spline->evaluate(val);
-			if(y != ycopy){
-				cerr << "COPY FAILED " << val << " " << y << " " << ycopy << endl;
-			}
-		}
-	}
-	{
-		cout << "Test copy assignment operator" << endl;
-		Spline oper_spline=*test_spline;
-		double minx,maxx,operminx,opermaxx;
-		test_spline->get_range(minx,maxx);
-		oper_spline.get_range(operminx,opermaxx);
-		if( (minx != operminx) || (maxx != opermaxx) ){
-			cerr << "ASSIGN COPY FAILED!" << endl;
-			return -1;
-		}
-		double range=x0[NP-1];
-		double nsteps=100;
-		for(int i=0;i<nsteps;i++){
-			double val=(range*i)/nsteps;
-			double y,yoper;
-			yoper=oper_spline.evaluate(val);
-			y=test_spline->evaluate(val);
-			if(y != yoper){
-				cerr << "COPY FAILED " << val << " " << y << " " << yoper << endl;
-			}
-		}
-	}
-	cout << "test delete" << endl;
-	delete test_spline;
-	{
-		cout << "test leaks - new/delete" << endl;
-		Spline *dynspl;
-		doubleVector x,y;
-		x.push_back(1.0);
-		x.push_back(2.0);
-		x.push_back(3.5);
-		
-		y.push_back(4.0);
-		y.push_back(5.0);
-		y.push_back(6.0);
-		for(int i=0; i < 100 ; i++){
-			dynspl = new Spline(x,y,NAN,0.0);
-			delete dynspl;
-		}
-	}
-	{
-		cout << "test leaks - stack" << endl;
-		doubleVector x,y;
-		x.push_back(1.0);
-		x.push_back(2.0);
-		x.push_back(3.5);
-		
-		y.push_back(4.0);
-		y.push_back(5.0);
-		y.push_back(6.0);
-		for(int i=0; i < 100 ; i++){
-			Spline stspl(x,y,NAN,0.0);
-		}
-	}
-	
-	{
-		cout <<"test end conditions" << endl;
-		std::ofstream outfile;
-		outfile.open("splineval.csv",ios::out); //CHECK success
-		if ( (outfile.rdstate() & ifstream::failbit ) != 0 ) return -1;
-		doubleVector x,y;
-		x.push_back(0.0);y.push_back(0.0);
-		x.push_back(1.0);y.push_back(1.0);
-		x.push_back(1.5);y.push_back(1.0);
-		x.push_back(2.0);y.push_back(1.0);
-		x.push_back(3.0);y.push_back(0.0);
-		Spline nsp(x,y); //natural spline
-		Spline zsp(x,y,0.0,0.0); // spline with 0 derivate start and stop
-		Spline nzsp(x,y,NAN,0.0); // spline with 0 derivate at stop
-		Spline znsp(x,y,0.0,NAN); // spline with 0 derivate at start
-		Spline ddsp(x,y,-0.5,0.5); // spline with derivatives at start and stop
-		double X;
-		double Yn,Yz,Ynz,Yzn,Ydd;
-		double range=3.0;
-		int nsteps=300;
-		for(int i=0;i<=nsteps;i++){
-			X=((range*i)/nsteps);
-			Yn=nsp.evaluate(X);
-			Yz=zsp.evaluate(X);
-			Ynz=nzsp.evaluate(X);
-			Yzn=znsp.evaluate(X);
-			Ydd=ddsp.evaluate(X);
-			outfile<< X << "\t\t" << Yn << "\t\t" << Yz << "\t\t" << Ynz << "\t\t" << Yzn << "\t\t" << Ydd << std::endl;
-		}
-		outfile.close();
-	}
-	return 0;
-}
diff --git a/test_inverse.cpp b/test_inverse.cpp
deleted file mode 100644
index 0fa48ce..0000000
--- a/test_inverse.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * program to test spline classes
- *
- * $Author: claudio $
- *
- * $Revision: 1.1 $
- *
- * $Log: test_inverse.cpp,v $
- * Revision 1.1  2017-03-03 15:32:40  claudio
- * correctetd   spline::inverse_calculate if returned value is at range limit
- *
- * Revision 1.1.1.1  2012-09-05 08:17:22  claudio
- * Interpolator utility classes
- *
- *
- */
-
-#include <iostream>
-#include "spline.h"
-#include <cmath>
-//#include <stdexcept>
-
-using namespace std;
-using namespace Interpolator;
-int main(){
-	 cout << "test spline::inverse_evaluate" << endl;
-	{
-		
-		doubleVector x,y;
-		x.push_back(10.0); y.push_back(83.6);
-		x.push_back(12);   y.push_back(68.3);
-		x.push_back( 14);  y.push_back( 55.7);
-		x.push_back(      16); y.push_back(45.5);
-		x.push_back(       18); y.push_back(37.3);
-		x.push_back(       20); y.push_back(30.7);
-		x.push_back(       22); y.push_back(     25.4);
-		x.push_back(       24); y.push_back(     21.2);
-		x.push_back(       26); y.push_back(     17.9);
-		x.push_back(       28); y.push_back(     15.2);
-		x.push_back(      30); y.push_back(     13.1);
-		x.push_back(      32); y.push_back(     11.4);
-		x.push_back(      34); y.push_back(     10.1);
-		x.push_back(      36); y.push_back(     9);
-		x.push_back(      40); y.push_back(     7.5);
-		x.push_back(      50); y.push_back(     5.77);
-		Spline *lambdasplie = new Spline(x,y);
-		double gmin,gmax;
-		
-		lambdasplie->get_range(gmin,gmax);
-		double max = lambdasplie->evaluate(gmin);
-		double min = lambdasplie->evaluate(gmax);
-		double initial=min +((max-min)/2);
-		
-		double l=min;
-		double gap, linv;
-		cout << "l\tgap\tlinverse" <<  endl;
-		cout.precision(8);
-		while (l<max){
-			gap = lambdasplie->inverse_evaluate(l,initial);
-			linv =  lambdasplie->evaluate(gap);
-			cout << l <<"\t" << gap << "\t" << linv <<endl;
-			l+=0.05;
-		}
-		delete lambdasplie;
-	}
-	return 0;
-}
diff --git a/test_multipoly.cpp b/test_multipoly.cpp
deleted file mode 100644
index d67022b..0000000
--- a/test_multipoly.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * program to test multipolynomial class
- *
- * $Author: claudio $
- *
- * $Revision: 1.1.1.1 $
- *
- * $Log: test_multipoly.cpp,v $
- * Revision 1.1.1.1  2012-09-05 08:17:22  claudio
- * Interpolator utility classes
- *
- */
-
-#include <iostream>
-#include "multipolynomial.h"
-
-using namespace std;
-using namespace Interpolator;
-
-int main(){
-	cout << "test of multiPolynomial interpolator class" << endl;
-	try{
-	//create interpolating polynomials
-		
-		InterpolatingPolynomial p0,p1,p2;
-		p0.xMin=0.5;
-		p0.xMax=1.5;
-		p0.coefficient.push_back(1.1);
-		
-		p1.xMin=1.5;
-		p1.xMax=2.5;
-		p1.coefficient.push_back(1.1);
-		p1.coefficient.push_back(2.2);
-		
-		p2.xMin=2.5;
-		p2.xMax=3.5;
-		p2.coefficient.push_back(1.1);
-		p2.coefficient.push_back(2.2);
-		p2.coefficient.push_back(3.3);
-		
-	//stuff polynomial into vector
-		
-		InterpolatingPolynoamialVector pvector;
-		pvector.push_back(p0);
-		pvector.push_back(p1);
-		pvector.push_back(p2);
-		
-		multiPolynomial *multipoly = new multiPolynomial(pvector);
-		double minX,maxX;
-		multipoly->get_range(minX,maxX);
-		if( (minX != p0.xMin) || ( maxX != p2.xMax) ){
-			cout << "multiPoly.get_range(): error " << minX << " " << maxX << " " << p0.xMin << " " << p2.xMax << endl;
-			return -1; //stop further testing
-		}
-		delete multipoly;
-	}
-	catch(...){
-		cerr << " unexpected excpetion!" << endl;
-		return -1;
-	}
-	
-	{
-		cout << "test a single 2nd degree polynomial " << endl;
-		try{
-			InterpolatingPolynomial p0;
-			p0.xMin=0.0;
-			p0.xMax=4.0;
-			p0.coefficient.push_back(0.0); //a0
-			p0.coefficient.push_back(0.0); //a1
-			p0.coefficient.push_back(1.0); //a2 --> Y=X*X 
-			InterpolatingPolynoamialVector pvector;
-			pvector.push_back(p0);
-			multiPolynomial *multipoly = new multiPolynomial(pvector);
-			double v=0.0,y;
-			y=multipoly->evaluate(v); if( y != 0.0 ){ cerr << "value not correct (0.0): " << y << endl; return -1; }
-			v=1.0;
-			y=multipoly->evaluate(v); if( y != 1.0 ){ cerr << "value not correct (1.0): " << y << endl; return -1; }
-			v=4.0;
-			y=multipoly->evaluate(v); if( y != 16.0 ){ cerr << "value not correct (16.0): " << y << endl; return -1; }
-			doubleVector X;
-			for (int i=0; i<=400;i++) X.push_back(i/100.0); //create range for testing
-			doubleVector Y=multipoly->evaluate(X);
-			cout << "----------------------------------" << endl;
-			for (unsigned int i=0; i < X.size(); i++) cout << X[i] << "\t" << Y[i] << endl;
-			cout << "----------------------------------" << endl;
-			delete multipoly;
-		}
-		catch(std::range_error& ex){
-			std::cerr << ex.what() << std::endl;
-			return -1;
-		}
-		catch(std::length_error& ex){
-			std::cerr << ex.what() << std::endl;
-			return -1;
-		}
-		try{
-	//create interpolating polynomials
-			cout << "test non contiguos" << endl;
-			InterpolatingPolynomial p0,p1,p2;
-			p0.xMin=0.5;
-			p0.xMax=1.5;
-			p0.coefficient.push_back(1.1);
-			
-			p1.xMin=1.6; // <-------
-			p1.xMax=2.5;
-			p1.coefficient.push_back(1.1);
-			p1.coefficient.push_back(2.2);
-			
-			p2.xMin=2.5;
-			p2.xMax=3.5;
-			p2.coefficient.push_back(1.1);
-			p2.coefficient.push_back(2.2);
-			p2.coefficient.push_back(3.3);
-			
-	//stuff polynomial into vector
-			
-			InterpolatingPolynoamialVector pvector;
-			pvector.push_back(p0);
-			pvector.push_back(p1);
-			pvector.push_back(p2);
-			
-			multiPolynomial *multipoly = new multiPolynomial(pvector);
-			delete multipoly;
-		}
-		catch(std::domain_error& ex){
-			cout << "OK expected  exception: " << ex.what() << endl;
-			
-		}
-		catch(...){
-			cerr << " unexpected excpetion!" << endl;
-			return -1;
-		}
-		
-		try{
-	//create interpolating polynomials
-			cout << "test 3 polynomials" << endl;
-			InterpolatingPolynomial p0,p1,p2;
-			p0.xMin=0.0;
-			p0.xMax=1.5;
-			p0.coefficient.push_back(1.0); //c[0]
-			
-			p1.xMin=1.5;
-			p1.xMax=2.5;
-			p1.coefficient.push_back(0.0); //c[0]
-			p1.coefficient.push_back(0.0); //c[1]
-			p1.coefficient.push_back(1.0); //c[2]
-			
-			p2.xMin=2.5;
-			p2.xMax=3.5;
-			p2.coefficient.push_back(5.0);  //c[0]
-			p2.coefficient.push_back(-2.0); //c[1]
-	//stuff polynomial into vector
-			
-			InterpolatingPolynoamialVector pvector;
-			pvector.push_back(p0);
-			pvector.push_back(p1);
-			pvector.push_back(p2);
-			
-			multiPolynomial *multipoly = new multiPolynomial(pvector);
-			doubleVector X;
-			for (int i=0; i<=350;i++) X.push_back(i/100.0); //create range for testing
-			doubleVector Y=multipoly->evaluate(X);
-			cout << "-+++++++++++++++++++++++++++++++++" << endl;
-			for (unsigned int i=0; i < X.size(); i++) cout << X[i] << "\t" << Y[i] << endl;
-			cout << "++++++++++++++++++++++++++++++++++" << endl;
-			delete multipoly;
-		}
-		catch(std::domain_error& ex){
-			cout << "unexpected  exception: " << ex.what() << endl;
-			return -1;
-		}
-		catch(std::range_error& ex){
-			std::cerr << ex.what() << std::endl;
-			return -1;
-		}
-		catch(std::length_error& ex){
-			std::cerr << ex.what() << std::endl;
-			return -1;
-		}
-		catch(...){
-			cerr << " unexpected excpetion!" << endl;
-			return -1;
-		}
-		
-		try{
-	//create interpolating polynomials
-			cout << "test 3 identical polynomials" << endl;
-			InterpolatingPolynomial p0,p1,p2;
-			p0.xMin=0.0;
-			p0.xMax=1.5;
-			p0.coefficient.push_back(1.0); //c[0]
-			
-			
-			InterpolatingPolynoamialVector pvector;
-			pvector.push_back(p0);
-			pvector.push_back(p0);
-			pvector.push_back(p0);
-			
-			multiPolynomial *multipoly = new multiPolynomial(pvector);
-			doubleVector X;
-			for (int i=0; i<=150;i++) X.push_back(i/100.0); //create range for testing
-			doubleVector Y=multipoly->evaluate(X);
-			cout << "**********************************" << endl;
-			for (unsigned int i=0; i < X.size(); i++) cout << X[i] << "\t" << Y[i] << endl;
-			cout << "**********************************" << endl;
-			delete multipoly;
-		}
-		catch(std::domain_error& ex){
-			cout << "OK, exception caught: " << ex.what() << endl;
-		}
-		catch(std::range_error& ex){
-			std::cerr << ex.what() << std::endl;
-			return -1;
-		}
-		catch(std::length_error& ex){
-			std::cerr << ex.what() << std::endl;
-			return -1;
-		}
-		catch(...){
-			cerr << " unexpected excpetion!" << endl;
-			return -1;
-		}
-		try{
-	//create interpolating polynomials
-			cout << "test copy constructor" << endl;
-			InterpolatingPolynomial p0,p1,p2;
-			p0.xMin=0.0;
-			p0.xMax=1.5;
-			p0.coefficient.push_back(1.0); //c[0]
-			
-			p1.xMin=1.5;
-			p1.xMax=2.5;
-			p1.coefficient.push_back(0.0); //c[0]
-			p1.coefficient.push_back(0.0); //c[1]
-			p1.coefficient.push_back(1.0); //c[2]
-			
-			p2.xMin=2.5;
-			p2.xMax=3.5;
-			p2.coefficient.push_back(5.0);  //c[0]
-			p2.coefficient.push_back(-2.0); //c[1]
-	//stuff polynomial into vector
-			
-			InterpolatingPolynoamialVector pvector;
-			pvector.push_back(p0);
-			pvector.push_back(p1);
-			pvector.push_back(p2);
-			
-			multiPolynomial *multipoly = new multiPolynomial(pvector);
-			multiPolynomial copypoly=*multipoly;
-			doubleVector X;
-			for (int i=0; i<=350;i++) X.push_back(i/100.0); //create range for testing
-			doubleVector Y=multipoly->evaluate(X);
-			doubleVector Yc=copypoly.evaluate(X);
-			
-			for (unsigned int i=0; i < X.size(); i++){
-				if (Y[i] != Yc[i])
-					cerr << "COPY ERROR: " << X[i] << " " << Y[i] << " " << Yc[i] <<endl;
-			}
-			delete multipoly;
-		}
-		catch(...){
-			cerr << " test copy constructor: unexpected excpetion!" << endl;
-			return -1;
-		}
-	}
-	{
-		cout << "test interpolatore for constat value on simmetric range" << endl;
-		InterpolatingPolynomial p0;
-		InterpolatingPolynoamialVector pvector;
-		p0.xMin=-5.0;
-		p0.xMax=5.0;
-		p0.coefficient.push_back(0.52); //c[0]
-		pvector.push_back(p0);
-		multiPolynomial *multipoly = new multiPolynomial(pvector);
-		double a0=-4.99;
-		cout << "for "<< a0 << " "<< multipoly->evaluate(a0);
-		a0=4.99;
-		cout << "for "<< a0 << " "<< multipoly->evaluate(a0);
-		delete multipoly;
-	}
-	return 0;
-}
diff --git a/test_obj/test_runner.gcda b/test_obj/test_runner.gcda
new file mode 100644
index 0000000000000000000000000000000000000000..4efd016f8520e9fa7d1cf9bf6795fd8490652704
GIT binary patch
literal 27324
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
A{r~^~

literal 0
HcmV?d00001

diff --git a/test_obj/test_runner.gcno b/test_obj/test_runner.gcno
new file mode 100644
index 0000000000000000000000000000000000000000..4b985fd5a481894c197ae972ac0804f07a7a4f90
GIT binary patch
literal 248972
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%0Doa%O#lxv
zuoi&7GO#v)hZtA~z~2~H7r@^cSP#I%D*Tgytw6-TRhWLfdnM?$#6M+h2O{QTV0!>_
zGq3}Ic~p2T1N(xA$Ez?e1Fr!QPiEj;0P`_$5rFwscsc`b2NBO;;2i*-rNRO#EXcqW
zpsIycSd4)Wfrw`-&`z=!XW_#jY6%7-SW<<hR9KpUkAOCoQDIpIJ_;h1Q(<`qJ_aII
zU?A$8N(@91&tc$dP}M37d<wv-3|s?XH3qH)usQ?R0a$~9>jA8#!a6Ffufhfjv<0gn
z3!eiWbS{GtY^1{TRM?n-&x1Ceufhu$_yUM{p$eNYa07_gl!2&oG8l*=HfP|gpsFnx
z_!@vM8TdMYtr++wfEP3HEdVcJ;M)LR%D_zkUZ%pfDr~R9D->ueT?ZC!1|8Iq!3cIz
zVP_R~Vc-_f#;z*t#=!SL#O^BW!NB)H#GVX9ozt6vC}Lj*?gv#Jz(DkE?t>W^|4weZ
zhBbtN@$cg{IFy0$@8UK%jDhj*;Wjv&f${I)Hkir4`1fxc9Kk^J71|?JIGTaztEID4
zIG%y=uU)pznZUsKS1ucz$iVp5EgPJ~!1z}!8=TC*_}45OoWj8PS1cQx%0ToD!qZeZ
zlY!_PglDA=)6#ErZ9H{wiKdT?TehI_lh1Bw>K^y((z;z%-EsZ<W{nu#vUQD`Ei<$F
zj~+Q<Sa0{ZX00QS24@azGh*1p%n`!}_a2tfu6N6JHF{=bG_9F2&J~iDR?h9!#*P_X
zZE$AaVPpICuhzG6<!Uu*R_il3YfQB<S;Kk;5vmSK%jYiU+i6>WpO$uEdLH-K_O!I7
z>3Os7)3QG(>C?_|Y4$e&w)k3_eflz3h=ct0v!w-}%FIY_?0)utGmu)%91ORhlpso~
z?ek^0`}CXL&56ZV4VyNt!G7!XR_<|jr`M?2vqN^b_w3VqO#lCpzOU~($ok&j|L^I0
ztI?57?fZY1l9qm-EAq)af0W<#=YY-D_nqA1|B}8xGIoQ9j~v#_jsj}{Ki6it-1*$@
z@BjCVgw^QCrjEqFOG!(g=!*QHamk`<H+|c}MxvT~>_&oIZ~n7`OF8COn8E+KQn|Is
ztytmO<d&EsE|;y3{{FwCa~rzy{Sw31%As(}NVgLF@}iUwbn1pPUmEzx7sszky;HN-
zZkx4y@c#>)I?(mVTW>Dzm9{bWnbxUxiSS=flKtG1U%&r<>dWD&-Sw8=(lgypE2bCk
z^46i{JFP2AxW{Pu)qB)Gk@@@ojw4-rG4b!GB6S)4cPVM<Q(O;r*|UA>cV(Wq#d@@A
za*zK1)6`L3jK-g)?BK65;<$@yr*A6y^}g<(+A~P@jIBR-#F*^YX$?k>?%#Ltn8715
zGlscerlpl}dycPsy>d@VyWO+JF)r_y;XN}|?X|GWp8Ygo*1tZEzus-(eq;G;OQk;c
z*W>nw;CnsJE+Hemk-PU#O>BApE+Z|yzboUkBEwp=dUr!^>&jpqZI{(Mvt5>(mn~g?
zx;?9RR{wTAv%|81>_web?tZto%$7%g1HpFW1+F~b7pc_8>T+b$I`H3Rq@`Qiy0ofQ
zyX2T1C$F7ZeZ>jxanCOOhP4?Nc344|fM#B1|MA)1KX|hHy?r@ahTHvY3q}>c%krIM
zuL*2-GQGOH^&N7wc-bVlNw*ofX7<iwDm-0zy^X%Ta_HG5bNui&!TZIevL17JOS=7W
ox1Zv6U-vxOKPT7S+Lv^s)ONpT+GBOF_(!&&FZ@xFRR5^^57*w-HUIzs

literal 0
HcmV?d00001

diff --git a/test_periodicspline.cpp b/test_periodicspline.cpp
deleted file mode 100644
index 2d8af4e..0000000
--- a/test_periodicspline.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * program to test peridic spline class
- *
- * $Author: claudio $
- *
- * $Revision: 1.2 $
- *
- * $Log: test_periodicspline.cpp,v $
- * Revision 1.2  2017-03-06 13:13:20  claudio
- * use unsigned for comparison
- *
- * Revision 1.1.1.1  2012-09-05 08:17:22  claudio
- * Interpolator utility classes
- *
- *
- */
-
-#include <iostream>
-#include "periodicspline.h"
-#include <cmath>
-
-using namespace std;
-using namespace Interpolator;
-
-int main(){
-	cout<< "test of periodicSpline interpolator class" << endl;
-	doubleVector x0,y0;
-	const int NP=15;
-	const double k = (2*M_PI)/NP;
-	for(int i=0; i <= NP; i++){
-		x0.push_back(i*k);
-		y0.push_back(sin(i*k));
-	}
-	periodicSpline* test_spline = new periodicSpline(x0,y0);
-	{
-		doubleVector a;
-		doubleVector b;
-		test_spline->get_base_points(a,b);
-		cout<<"test get_base_points()"<<endl;
-		for(unsigned int i=0; i < a.size()-1; i++ )
-			if((x0[i] != a[i]) ||(y0[i] != b[i])){
-				cout << i << " " << x0[i] << " " << a[i] << " | "<< y0[i] << " " << b[i] << endl;
-				return -1;
-			}
-		
-	}
-	{
-		cout << "test get_range()" << endl;
-		double minx,maxx;
-		test_spline->get_range(minx,maxx);
-		int I=x0.size()-1;
-		if( (minx != x0[0]) || (maxx != x0[I]) ){
-			cout << minx << " " << x0[0] << " | " << maxx << " " << x0[I] << endl;
-			return -1;
-		}
-	}
-	{
-		cout << "test evaluate()" << endl;
-		double xn=0.02;
-		double yn=test_spline->evaluate(xn);
-		cout << xn << " " << yn << endl;
-		yn=test_spline->evaluate(x0[5]);
-		cout << xn << " " << yn << " " << y0[5] << endl;	
-	}
-	{
-		cout << "test evaluate()" << endl;
-		double xn=0.02;
-		double yn=test_spline->evaluate(xn);
-		cout << xn << " " << yn << endl;
-		yn=test_spline->evaluate(x0[5]);
-		cout << xn << " " << yn << " " << y0[5] << endl;	
-	}
-	{	cout << "test evaluate()for plot" << endl;
-		doubleVector X;
-		doubleVector Y;
-		double minx;
-		double range;
-		test_spline->get_range(minx,range);
-		double nsteps=100;
-		for(int i=0;i<=nsteps;i++){
-			X.push_back((range*i)/nsteps);
-			Y.push_back(test_spline->evaluate(X[i]));
-		}
-		//print out data
-		cout<<"---------------------------"<<endl;
-		for(unsigned int i=0; i < x0.size(); i++) cout<<x0[i]<<"\t"<<y0[i]<<endl;
-		cout<<"---------------------------"<<endl;
-		for(int i=0; i <= nsteps; i++) cout<<X[i]<<"\t"<<Y[i]<<endl;
-		cout<<"+++++++++++++++++++++++++++"<<endl;
-	}
-	{	
-		cout << "test evaluate()for doubleVector" << endl;
-		doubleVector X;
-		doubleVector Y;
-		double minx;
-		double range;
-		test_spline->get_range(minx,range);
-		double nsteps=100;
-		for(int i=0;i<=nsteps;i++)
-			X.push_back((range*i)/nsteps);
-		Y=test_spline->evaluate(X);
-		//print out data
-		cout<<"###########################"<<endl;
-		for(int i=0; i <= nsteps; i++) cout<<X[i]<<"\t"<<Y[i]<<endl;
-		cout<<"***************************"<<endl;
-	}
-	{
-		cout << "test range exception" << endl;
-		try{
-			test_spline->evaluate(-10.0);
-			cerr << "range_error not thrown!" << endl;
-		}
-		catch(std::range_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "test constructor with unequal lengths" << endl;
-		try{
-			doubleVector x,y;
-			x.push_back(1.0);
-			x.push_back(2.0);
-			x.push_back(3.0);
-			
-			y.push_back(4.0);
-			y.push_back(5.0);
-			periodicSpline spl(x,y);
-			cerr << "length_error not thrown!" << endl;
-		}
-		catch(std::length_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "test constructor with out of order data" << endl;
-		try{
-			doubleVector x,y;
-			x.push_back(1.0);
-			x.push_back(2.0);
-			x.push_back(1.5);
-			
-			y.push_back(4.0);
-			y.push_back(5.0);
-			y.push_back(6.0);
-			periodicSpline spl(x,y);
-			cerr << "domain_error not thrown!" << endl;
-		}
-		catch(std::domain_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "Test copy constructor" << endl;
-		periodicSpline copy_spline(*test_spline);
-		double minx,maxx,copyminx,copymaxx;
-		test_spline->get_range(minx,maxx);
-		copy_spline.get_range(copyminx,copymaxx);
-		if( (minx != copyminx) || (maxx != copymaxx) ){
-			cerr << "COPY FAILED!" << endl;
-			return -1;
-		}
-		double range;
-		test_spline->get_range(minx,range);
-		double nsteps=100;
-		for(int i=0;i<nsteps;i++){
-			double val=(range*i)/nsteps;
-			double y,ycopy;
-			ycopy=copy_spline.evaluate(val);
-			y=test_spline->evaluate(val);
-			if(y != ycopy){
-				cerr << "COPY FAILED " << val << " " << y << " " << ycopy << endl;
-			}
-		}
-	}
-	{
-		cout << "Test copy operator" << endl;
-		periodicSpline copy_spline(*test_spline);
-		copy_spline=*test_spline;
-		double minx,maxx,copyminx,copymaxx;
-		test_spline->get_range(minx,maxx);
-		copy_spline.get_range(copyminx,copymaxx);
-		if( (minx != copyminx) || (maxx != copymaxx) ){
-			cerr << "COPY FAILED!" << endl;
-			return -1;
-		}
-		double range;
-		test_spline->get_range(minx,range);
-		double nsteps=100;
-		for(int i=0;i<nsteps;i++){
-			double val=(range*i)/nsteps;
-			double y,ycopy;
-			ycopy=copy_spline.evaluate(val);
-			y=test_spline->evaluate(val);
-			if(y != ycopy){
-				cerr << "COPY FAILED " << val << " " << y << " " << ycopy << endl;
-			}
-		}
-	}
-	cout << "test delete" << endl;
-	delete test_spline;
-	{
-		cout << "test leaks - new/delete" << endl;
-		periodicSpline *dynspl;
-		doubleVector x,y;
-		x.push_back(1.0);
-		x.push_back(2.0);
-		x.push_back(3.5);
-		
-		y.push_back(4.0);
-		y.push_back(5.0);
-		y.push_back(6.0);
-		for(int i=0; i < 100 ; i++){
-			dynspl = new periodicSpline(x,y);
-			delete dynspl;
-		}
-	}
-	{
-		cout << "test leaks - stack" << endl;
-		doubleVector x,y;
-		x.push_back(1.0);
-		x.push_back(2.0);
-		x.push_back(3.5);
-		
-		y.push_back(4.0);
-		y.push_back(5.0);
-		y.push_back(6.0);
-		for(int i=0; i < 100 ; i++){
-			periodicSpline stspl(x,y);
-		}
-	}
-	
-	return 0;
-}
diff --git a/test_spline.cpp b/test_spline.cpp
deleted file mode 100644
index b2f0a97..0000000
--- a/test_spline.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * program to test spline classes
- *
- * $Author: claudio $
- *
- * $Revision: 1.1.1.1 $
- *
- * $Log: test_spline.cpp,v $
- * Revision 1.1.1.1  2012-09-05 08:17:22  claudio
- * Interpolator utility classes
- *
- *
- */
-
-#include <iostream>
-#include "spline.h"
-#include <cmath>
-//#include <stdexcept>
-
-using namespace std;
-using namespace Interpolator;
-int main(){
-	cout<< "test of Spline interpolator class" << endl;
-	doubleVector x0,y0;
-	const int NP=30;
-	for(int i=0; i < NP; i++){
-		x0.push_back(i*i*.02);
-		y0.push_back(sin(i*i*.02));
-	}
-	Spline* test_spline = new Spline(x0,y0);
-	{
-		doubleVector a;
-		doubleVector b;
-		test_spline->get_base_points(a,b);
-		cout<<"test get_base_points()"<<endl;
-		for(int i=0; i < NP; i++ )
-			if((x0[i] != a[i]) ||(y0[i] != b[i])){
-				cout << i << " " << x0[i] << " " << a[i] << " | "<< y0[i] << " " << b[i] << endl;
-				return -1;
-			}
-		
-	}
-	{
-		cout << "test get_range()" << endl;
-		double minx,maxx;
-		test_spline->get_range(minx,maxx);
-		if( (minx != x0[0]) || (maxx != x0[NP-1]) ){
-			cout << minx << " " << x0[0] << " | " << maxx << " " << x0[NP-1] << endl;
-			return -1;
-		}
-	}
-	{
-		cout << "test evaluate()" << endl;
-		double xn=0.02;
-		double yn=test_spline->evaluate(xn);
-		cout << xn << " " << yn << endl;
-		yn=test_spline->evaluate(x0[5]);
-		cout << xn << " " << yn << " " << y0[5] << endl;	
-	}
-	{
-		cout << "test evaluate()" << endl;
-		double xn=0.02;
-		double yn=test_spline->evaluate(xn);
-		cout << xn << " " << yn << endl;
-		yn=test_spline->evaluate(x0[5]);
-		cout << xn << " " << yn << " " << y0[5] << endl;	
-	}
-	{	cout << "test evaluate()for plot" << endl;
-		doubleVector X;
-		doubleVector Y;
-		double range=x0[NP-1];
-		double nsteps=100;
-		for(int i=0;i<nsteps;i++){
-			X.push_back((range*i)/nsteps);
-			Y.push_back(test_spline->evaluate(X[i]));
-		}
-		//print out data
-		cout<<"---------------------------"<<endl;
-		for(int i=0; i < NP; i++) cout<<x0[i]<<"\t"<<y0[i]<<endl;
-		cout<<"---------------------------"<<endl;
-		for(int i=0; i < nsteps; i++) cout<<X[i]<<"\t"<<Y[i]<<endl;
-		cout<<"+++++++++++++++++++++++++++"<<endl;
-	}
-	{	
-		cout << "test evaluate()for doubleVector" << endl;
-		doubleVector X;
-		doubleVector Y;
-		double range=x0[NP-1];
-		double nsteps=100;
-		for(int i=0;i<nsteps;i++)
-			X.push_back((range*i)/nsteps);
-		Y=test_spline->evaluate(X);
-		//print out data
-		cout<<"###########################"<<endl;
-		for(int i=0; i < nsteps; i++) cout<<X[i]<<"\t"<<Y[i]<<endl;
-		cout<<"***************************"<<endl;
-	}
-	{
-		cout << "test range exception" << endl;
-		try{
-			test_spline->evaluate(-10.0);
-			cerr << "range_error not thrown!" << endl;
-		}
-		catch(std::range_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "test constructor with unequal lengths" << endl;
-		try{
-			doubleVector x,y;
-			x.push_back(1.0);
-			x.push_back(2.0);
-			x.push_back(3.0);
-			
-			y.push_back(4.0);
-			y.push_back(5.0);
-			Spline spl(x,y);
-			cerr << "length_error not thrown!" << endl;
-		}
-		catch(std::length_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "test constructor with out of order data" << endl;
-		try{
-			doubleVector x,y;
-			x.push_back(1.0);
-			x.push_back(2.0);
-			x.push_back(1.5);
-			
-			y.push_back(4.0);
-			y.push_back(5.0);
-			y.push_back(6.0);
-			Spline spl(x,y);
-			cerr << "domain_error not thrown!" << endl;
-		}
-		catch(std::domain_error& ex){
-			cout << "OK, catched expected exception: "<< ex.what() <<  endl;
-		}
-		catch(...){
-			cerr << "unexpected exception thrown!" << endl;
-		}
-	}
-	{
-		cout << "Test copy constructor" << endl;
-		//Spline copy_spline=*test_spline;
-		Spline copy_spline(*test_spline);
-		double minx,maxx,copyminx,copymaxx;
-		test_spline->get_range(minx,maxx);
-		copy_spline.get_range(copyminx,copymaxx);
-		if( (minx != copyminx) || (maxx != copymaxx) ){
-			cerr << "COPY FAILED!" << endl;
-			return -1;
-		}
-		double range=x0[NP-1];
-		double nsteps=100;
-		for(int i=0;i<nsteps;i++){
-			double val=(range*i)/nsteps;
-			double y,ycopy;
-			ycopy=copy_spline.evaluate(val);
-			y=test_spline->evaluate(val);
-			if(y != ycopy){
-				cerr << "COPY FAILED " << val << " " << y << " " << ycopy << endl;
-			}
-		}
-	}
-	cout << "test delete" << endl;
-	delete test_spline;
-	{
-		cout << "test leaks - new/delete" << endl;
-		Spline *dynspl;
-		doubleVector x,y;
-		x.push_back(1.0);
-		x.push_back(2.0);
-		x.push_back(3.5);
-		
-		y.push_back(4.0);
-		y.push_back(5.0);
-		y.push_back(6.0);
-		for(int i=0; i < 100 ; i++){
-			dynspl = new Spline(x,y);
-			delete dynspl;
-		}
-	}
-	{
-		cout << "test leaks - stack" << endl;
-		doubleVector x,y;
-		x.push_back(1.0);
-		x.push_back(2.0);
-		x.push_back(3.5);
-		
-		y.push_back(4.0);
-		y.push_back(5.0);
-		y.push_back(6.0);
-		for(int i=0; i < 100 ; i++){
-			Spline stspl(x,y);
-		}
-	}
-	
-	return 0;
-}
diff --git a/test_src/test_runner.cpp b/test_src/test_runner.cpp
new file mode 100644
index 0000000..346ac10
--- /dev/null
+++ b/test_src/test_runner.cpp
@@ -0,0 +1,1064 @@
+/*
+ * program to test interpolator library
+ *
+ */
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include "spline.h"
+#include "multipolynomial.h"
+#include "periodicspline.h"
+#include <cmath>
+
+using namespace std;
+using namespace Interpolator;
+
+int main() {
+	{
+		cout << "test of multiPolynomial interpolator class" << endl;
+		try {
+			//create interpolating polynomials
+
+			InterpolatingPolynomial p0, p1, p2;
+			p0.xMin = 0.5;
+			p0.xMax = 1.5;
+			p0.coefficient.push_back(1.1);
+
+			p1.xMin = 1.5;
+			p1.xMax = 2.5;
+			p1.coefficient.push_back(1.1);
+			p1.coefficient.push_back(2.2);
+
+			p2.xMin = 2.5;
+			p2.xMax = 3.5;
+			p2.coefficient.push_back(1.1);
+			p2.coefficient.push_back(2.2);
+			p2.coefficient.push_back(3.3);
+
+			//stuff polynomial into vector
+
+			InterpolatingPolynoamialVector pvector;
+			pvector.push_back(p0);
+			pvector.push_back(p1);
+			pvector.push_back(p2);
+
+			multiPolynomial *multipoly = new multiPolynomial(pvector);
+			double minX, maxX;
+			multipoly->get_range(minX, maxX);
+			if ((minX != p0.xMin) || (maxX != p2.xMax)) {
+				cout << "multiPoly.get_range(): error " << minX << " " << maxX
+						<< " " << p0.xMin << " " << p2.xMax << endl;
+				return -1; //stop further testing
+			}
+			delete multipoly;
+		} catch (...) {
+			cerr << " unexpected excpetion!" << endl;
+			return -1;
+		}
+
+		{
+			cout << "test a single 2nd degree polynomial " << endl;
+			try {
+				InterpolatingPolynomial p0;
+				p0.xMin = 0.0;
+				p0.xMax = 4.0;
+				p0.coefficient.push_back(0.0); //a0
+				p0.coefficient.push_back(0.0); //a1
+				p0.coefficient.push_back(1.0); //a2 --> Y=X*X
+				InterpolatingPolynoamialVector pvector;
+				pvector.push_back(p0);
+				multiPolynomial *multipoly = new multiPolynomial(pvector);
+				double v = 0.0, y;
+				y = multipoly->evaluate(v);
+				if (y != 0.0) {
+					cerr << "value not correct (0.0): " << y << endl;
+					return -1;
+				}
+				v = 1.0;
+				y = multipoly->evaluate(v);
+				if (y != 1.0) {
+					cerr << "value not correct (1.0): " << y << endl;
+					return -1;
+				}
+				v = 4.0;
+				y = multipoly->evaluate(v);
+				if (y != 16.0) {
+					cerr << "value not correct (16.0): " << y << endl;
+					return -1;
+				}
+				doubleVector X;
+				for (int i = 0; i <= 400; i++)
+					X.push_back(i / 100.0); //create range for testing
+				doubleVector Y = multipoly->evaluate(X);
+				cout << "----------------------------------" << endl;
+				for (unsigned int i = 0; i < X.size(); i++)
+					cout << X[i] << "\t" << Y[i] << endl;
+				cout << "----------------------------------" << endl;
+				delete multipoly;
+			} catch (std::range_error &ex) {
+				std::cerr << ex.what() << std::endl;
+				return -1;
+			} catch (std::length_error &ex) {
+				std::cerr << ex.what() << std::endl;
+				return -1;
+			}
+			try {
+				//create interpolating polynomials
+				cout << "test non contiguos" << endl;
+				InterpolatingPolynomial p0, p1, p2;
+				p0.xMin = 0.5;
+				p0.xMax = 1.5;
+				p0.coefficient.push_back(1.1);
+
+				p1.xMin = 1.6; // <-------
+				p1.xMax = 2.5;
+				p1.coefficient.push_back(1.1);
+				p1.coefficient.push_back(2.2);
+
+				p2.xMin = 2.5;
+				p2.xMax = 3.5;
+				p2.coefficient.push_back(1.1);
+				p2.coefficient.push_back(2.2);
+				p2.coefficient.push_back(3.3);
+
+				//stuff polynomial into vector
+
+				InterpolatingPolynoamialVector pvector;
+				pvector.push_back(p0);
+				pvector.push_back(p1);
+				pvector.push_back(p2);
+
+				multiPolynomial *multipoly = new multiPolynomial(pvector);
+				delete multipoly;
+			} catch (std::domain_error &ex) {
+				cout << "OK expected  exception: " << ex.what() << endl;
+
+			} catch (...) {
+				cerr << " unexpected excpetion!" << endl;
+				return -1;
+			}
+
+			try {
+				//create interpolating polynomials
+				cout << "test 3 polynomials" << endl;
+				InterpolatingPolynomial p0, p1, p2;
+				p0.xMin = 0.0;
+				p0.xMax = 1.5;
+				p0.coefficient.push_back(1.0); //c[0]
+
+				p1.xMin = 1.5;
+				p1.xMax = 2.5;
+				p1.coefficient.push_back(0.0); //c[0]
+				p1.coefficient.push_back(0.0); //c[1]
+				p1.coefficient.push_back(1.0); //c[2]
+
+				p2.xMin = 2.5;
+				p2.xMax = 3.5;
+				p2.coefficient.push_back(5.0);  //c[0]
+				p2.coefficient.push_back(-2.0); //c[1]
+				//stuff polynomial into vector
+
+				InterpolatingPolynoamialVector pvector;
+				pvector.push_back(p0);
+				pvector.push_back(p1);
+				pvector.push_back(p2);
+
+				multiPolynomial *multipoly = new multiPolynomial(pvector);
+				doubleVector X;
+				for (int i = 0; i <= 350; i++)
+					X.push_back(i / 100.0); //create range for testing
+				doubleVector Y = multipoly->evaluate(X);
+				cout << "-+++++++++++++++++++++++++++++++++" << endl;
+				for (unsigned int i = 0; i < X.size(); i++)
+					cout << X[i] << "\t" << Y[i] << endl;
+				cout << "++++++++++++++++++++++++++++++++++" << endl;
+				delete multipoly;
+			} catch (std::domain_error &ex) {
+				cout << "unexpected  exception: " << ex.what() << endl;
+				return -1;
+			} catch (std::range_error &ex) {
+				std::cerr << ex.what() << std::endl;
+				return -1;
+			} catch (std::length_error &ex) {
+				std::cerr << ex.what() << std::endl;
+				return -1;
+			} catch (...) {
+				cerr << " unexpected excpetion!" << endl;
+				return -1;
+			}
+
+			try {
+				//create interpolating polynomials
+				cout << "test 3 identical polynomials" << endl;
+				InterpolatingPolynomial p0, p1, p2;
+				p0.xMin = 0.0;
+				p0.xMax = 1.5;
+				p0.coefficient.push_back(1.0); //c[0]
+
+				InterpolatingPolynoamialVector pvector;
+				pvector.push_back(p0);
+				pvector.push_back(p0);
+				pvector.push_back(p0);
+
+				multiPolynomial *multipoly = new multiPolynomial(pvector);
+				doubleVector X;
+				for (int i = 0; i <= 150; i++)
+					X.push_back(i / 100.0); //create range for testing
+				doubleVector Y = multipoly->evaluate(X);
+				cout << "**********************************" << endl;
+				for (unsigned int i = 0; i < X.size(); i++)
+					cout << X[i] << "\t" << Y[i] << endl;
+				cout << "**********************************" << endl;
+				delete multipoly;
+			} catch (std::domain_error &ex) {
+				cout << "OK, exception caught: " << ex.what() << endl;
+			} catch (std::range_error &ex) {
+				std::cerr << ex.what() << std::endl;
+				return -1;
+			} catch (std::length_error &ex) {
+				std::cerr << ex.what() << std::endl;
+				return -1;
+			} catch (...) {
+				cerr << " unexpected excpetion!" << endl;
+				return -1;
+			}
+			try {
+				//create interpolating polynomials
+				cout << "test copy constructor" << endl;
+				InterpolatingPolynomial p0, p1, p2;
+				p0.xMin = 0.0;
+				p0.xMax = 1.5;
+				p0.coefficient.push_back(1.0); //c[0]
+
+				p1.xMin = 1.5;
+				p1.xMax = 2.5;
+				p1.coefficient.push_back(0.0); //c[0]
+				p1.coefficient.push_back(0.0); //c[1]
+				p1.coefficient.push_back(1.0); //c[2]
+
+				p2.xMin = 2.5;
+				p2.xMax = 3.5;
+				p2.coefficient.push_back(5.0);  //c[0]
+				p2.coefficient.push_back(-2.0); //c[1]
+				//stuff polynomial into vector
+
+				InterpolatingPolynoamialVector pvector;
+				pvector.push_back(p0);
+				pvector.push_back(p1);
+				pvector.push_back(p2);
+
+				multiPolynomial *multipoly = new multiPolynomial(pvector);
+				multiPolynomial copypoly = *multipoly;
+				doubleVector X;
+				for (int i = 0; i <= 350; i++)
+					X.push_back(i / 100.0); //create range for testing
+				doubleVector Y = multipoly->evaluate(X);
+				doubleVector Yc = copypoly.evaluate(X);
+
+				for (unsigned int i = 0; i < X.size(); i++) {
+					if (Y[i] != Yc[i])
+						cerr << "COPY ERROR: " << X[i] << " " << Y[i] << " "
+								<< Yc[i] << endl;
+				}
+				delete multipoly;
+			} catch (...) {
+				cerr << " test copy constructor: unexpected excpetion!" << endl;
+				return -1;
+			}
+		}
+		{
+			cout << "test interpolatore for constat value on simmetric range"
+					<< endl;
+			InterpolatingPolynomial p0;
+			InterpolatingPolynoamialVector pvector;
+			p0.xMin = -5.0;
+			p0.xMax = 5.0;
+			p0.coefficient.push_back(0.52); //c[0]
+			pvector.push_back(p0);
+			multiPolynomial *multipoly = new multiPolynomial(pvector);
+			double a0 = -4.99;
+			cout << "for " << a0 << " " << multipoly->evaluate(a0);
+			a0 = 4.99;
+			cout << "for " << a0 << " " << multipoly->evaluate(a0);
+			delete multipoly;
+		}
+	}
+	//################################################################
+	{
+		cout << "test of Spline interpolator class" << endl;
+		doubleVector x0, y0;
+		const int NP = 30;
+		for (int i = 0; i < NP; i++) {
+			x0.push_back(i * i * .02);
+			y0.push_back(sin(i * i * .02));
+		}
+		Spline *test_spline = new Spline(x0, y0, NAN, 0.0);
+		{
+			doubleVector a;
+			vector<double> b;
+			test_spline->get_base_points(a, b);
+			cout << "test get_base_points()" << endl;
+			for (int i = 0; i < NP; i++)
+				if ((x0[i] != a[i]) || (y0[i] != b[i])) {
+					cout << i << " " << x0[i] << " " << a[i] << " | " << y0[i]
+							<< " " << b[i] << endl;
+					return -1;
+				}
+
+		}
+		{
+			cout << "test get_range()" << endl;
+			double minx, maxx;
+			test_spline->get_range(minx, maxx);
+			if ((minx != x0[0]) || (maxx != x0[NP - 1])) {
+				cout << minx << " " << x0[0] << " | " << maxx << " "
+						<< x0[NP - 1] << endl;
+				return -1;
+			}
+		}
+		{
+			cout << "test evaluate()" << endl;
+			double xn = 0.02;
+			double yn = test_spline->evaluate(xn);
+			cout << xn << " " << yn << endl;
+			yn = test_spline->evaluate(x0[5]);
+			cout << xn << " " << yn << " " << y0[5] << endl;
+		}
+		{
+			cout << "test evaluate()" << endl;
+			double xn = 0.02;
+			double yn = test_spline->evaluate(xn);
+			cout << xn << " " << yn << endl;
+			yn = test_spline->evaluate(x0[5]);
+			cout << xn << " " << yn << " " << y0[5] << endl;
+		}
+		{
+			cout << "test evaluate()for plot" << endl;
+			doubleVector X;
+			doubleVector Y;
+			double range = x0[NP - 1];
+			double nsteps = 300;
+			for (int i = 0; i <= nsteps; i++) {
+				X.push_back((range * i) / nsteps);
+				Y.push_back(test_spline->evaluate(X[i]));
+			}
+			//print out data
+			cout << "---------------------------" << endl;
+			for (int i = 0; i < NP; i++)
+				cout << x0[i] << "\t" << y0[i] << endl;
+			cout << "---------------------------" << endl;
+			for (int i = 0; i < nsteps; i++)
+				cout << X[i] << "\t" << Y[i] << endl;
+			cout << "+++++++++++++++++++++++++++" << endl;
+		}
+		{
+			cout << "test evaluate()for doubleVector" << endl;
+			doubleVector X;
+			doubleVector Y;
+			double range = x0[NP - 1];
+			double nsteps = 300;
+			for (int i = 0; i <= nsteps; i++)
+				X.push_back((range * i) / nsteps);
+			Y = test_spline->evaluate(X);
+			//print out data
+			cout << "###########################" << endl;
+			for (int i = 0; i < nsteps; i++)
+				cout << X[i] << "\t" << Y[i] << endl;
+			cout << "***************************" << endl;
+		}
+		{
+			cout << "test range exception" << endl;
+			try {
+				test_spline->evaluate(-10.0);
+				cerr << "range_error not thrown!" << endl;
+			} catch (std::range_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "test constructor with unequal lengths" << endl;
+			try {
+				doubleVector x, y;
+				x.push_back(1.0);
+				x.push_back(2.0);
+				x.push_back(3.0);
+
+				y.push_back(4.0);
+				y.push_back(5.0);
+				Spline spl(x, y, NAN, 0.0);
+				cerr << "length_error not thrown!" << endl;
+			} catch (std::length_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "test constructor with out of order data" << endl;
+			try {
+				doubleVector x, y;
+				x.push_back(1.0);
+				x.push_back(2.0);
+				x.push_back(1.5);
+
+				y.push_back(4.0);
+				y.push_back(5.0);
+				y.push_back(6.0);
+				Spline spl(x, y, NAN, 0.0);
+				cerr << "domain_error not thrown!" << endl;
+			} catch (std::domain_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "Test copy constructor" << endl;
+			Spline copy_spline(*test_spline);
+			double minx, maxx, copyminx, copymaxx;
+			test_spline->get_range(minx, maxx);
+			copy_spline.get_range(copyminx, copymaxx);
+			if ((minx != copyminx) || (maxx != copymaxx)) {
+				cerr << "COPY FAILED!" << endl;
+				return -1;
+			}
+			double range = x0[NP - 1];
+			double nsteps = 100;
+			for (int i = 0; i < nsteps; i++) {
+				double val = (range * i) / nsteps;
+				double y, ycopy;
+				ycopy = copy_spline.evaluate(val);
+				y = test_spline->evaluate(val);
+				if (y != ycopy) {
+					cerr << "COPY FAILED " << val << " " << y << " " << ycopy
+							<< endl;
+				}
+			}
+		}
+		{
+			cout << "Test copy assignment operator" << endl;
+			Spline oper_spline = *test_spline;
+			double minx, maxx, operminx, opermaxx;
+			test_spline->get_range(minx, maxx);
+			oper_spline.get_range(operminx, opermaxx);
+			if ((minx != operminx) || (maxx != opermaxx)) {
+				cerr << "ASSIGN COPY FAILED!" << endl;
+				return -1;
+			}
+			double range = x0[NP - 1];
+			double nsteps = 100;
+			for (int i = 0; i < nsteps; i++) {
+				double val = (range * i) / nsteps;
+				double y, yoper;
+				yoper = oper_spline.evaluate(val);
+				y = test_spline->evaluate(val);
+				if (y != yoper) {
+					cerr << "COPY FAILED " << val << " " << y << " " << yoper
+							<< endl;
+				}
+			}
+		}
+		cout << "test delete" << endl;
+		delete test_spline;
+		{
+			cout << "test leaks - new/delete" << endl;
+			Spline *dynspl;
+			doubleVector x, y;
+			x.push_back(1.0);
+			x.push_back(2.0);
+			x.push_back(3.5);
+
+			y.push_back(4.0);
+			y.push_back(5.0);
+			y.push_back(6.0);
+			for (int i = 0; i < 100; i++) {
+				dynspl = new Spline(x, y, NAN, 0.0);
+				delete dynspl;
+			}
+		}
+		{
+			cout << "test leaks - stack" << endl;
+			doubleVector x, y;
+			x.push_back(1.0);
+			x.push_back(2.0);
+			x.push_back(3.5);
+
+			y.push_back(4.0);
+			y.push_back(5.0);
+			y.push_back(6.0);
+			for (int i = 0; i < 100; i++) {
+				Spline stspl(x, y, NAN, 0.0);
+			}
+		}
+
+		{
+			cout << "test end conditions" << endl;
+			std::ofstream outfile;
+			outfile.open("splineval.csv", ios::out); //CHECK success
+			if ((outfile.rdstate() & ifstream::failbit) != 0)
+				return -1;
+			doubleVector x, y;
+			x.push_back(0.0);
+			y.push_back(0.0);
+			x.push_back(1.0);
+			y.push_back(1.0);
+			x.push_back(1.5);
+			y.push_back(1.0);
+			x.push_back(2.0);
+			y.push_back(1.0);
+			x.push_back(3.0);
+			y.push_back(0.0);
+			Spline nsp(x, y); //natural spline
+			Spline zsp(x, y, 0.0, 0.0); // spline with 0 derivate start and stop
+			Spline nzsp(x, y, NAN, 0.0); // spline with 0 derivate at stop
+			Spline znsp(x, y, 0.0, NAN); // spline with 0 derivate at start
+			Spline ddsp(x, y, -0.5, 0.5); // spline with derivatives at start and stop
+			double X;
+			double Yn, Yz, Ynz, Yzn, Ydd;
+			double range = 3.0;
+			int nsteps = 300;
+			for (int i = 0; i <= nsteps; i++) {
+				X = ((range * i) / nsteps);
+				Yn = nsp.evaluate(X);
+				Yz = zsp.evaluate(X);
+				Ynz = nzsp.evaluate(X);
+				Yzn = znsp.evaluate(X);
+				Ydd = ddsp.evaluate(X);
+				outfile << X << "\t\t" << Yn << "\t\t" << Yz << "\t\t" << Ynz
+						<< "\t\t" << Yzn << "\t\t" << Ydd << std::endl;
+			}
+			outfile.close();
+		}
+	}
+	//######################################################################
+	{
+		cout << "test of Spline interpolator class" << endl;
+		doubleVector x0, y0;
+		const int NP = 30;
+		for (int i = 0; i < NP; i++) {
+			x0.push_back(i * i * .02);
+			y0.push_back(sin(i * i * .02));
+		}
+		Spline *test_spline = new Spline(x0, y0, NAN, 0.0);
+		{
+			doubleVector a;
+			vector<double> b;
+			test_spline->get_base_points(a, b);
+			cout << "test get_base_points()" << endl;
+			for (int i = 0; i < NP; i++)
+				if ((x0[i] != a[i]) || (y0[i] != b[i])) {
+					cout << i << " " << x0[i] << " " << a[i] << " | " << y0[i]
+							<< " " << b[i] << endl;
+					return -1;
+				}
+
+		}
+		{
+			cout << "test get_range()" << endl;
+			double minx, maxx;
+			test_spline->get_range(minx, maxx);
+			if ((minx != x0[0]) || (maxx != x0[NP - 1])) {
+				cout << minx << " " << x0[0] << " | " << maxx << " "
+						<< x0[NP - 1] << endl;
+				return -1;
+			}
+		}
+		{
+			cout << "test evaluate()" << endl;
+			double xn = 0.02;
+			double yn = test_spline->evaluate(xn);
+			cout << xn << " " << yn << endl;
+			yn = test_spline->evaluate(x0[5]);
+			cout << xn << " " << yn << " " << y0[5] << endl;
+		}
+		{
+			cout << "test evaluate()" << endl;
+			double xn = 0.02;
+			double yn = test_spline->evaluate(xn);
+			cout << xn << " " << yn << endl;
+			yn = test_spline->evaluate(x0[5]);
+			cout << xn << " " << yn << " " << y0[5] << endl;
+		}
+		{
+			cout << "test evaluate()for plot" << endl;
+			doubleVector X;
+			doubleVector Y;
+			double range = x0[NP - 1];
+			double nsteps = 300;
+			for (int i = 0; i <= nsteps; i++) {
+				X.push_back((range * i) / nsteps);
+				Y.push_back(test_spline->evaluate(X[i]));
+			}
+			//print out data
+			cout << "---------------------------" << endl;
+			for (int i = 0; i < NP; i++)
+				cout << x0[i] << "\t" << y0[i] << endl;
+			cout << "---------------------------" << endl;
+			for (int i = 0; i < nsteps; i++)
+				cout << X[i] << "\t" << Y[i] << endl;
+			cout << "+++++++++++++++++++++++++++" << endl;
+		}
+		{
+			cout << "test evaluate()for doubleVector" << endl;
+			doubleVector X;
+			doubleVector Y;
+			double range = x0[NP - 1];
+			double nsteps = 300;
+			for (int i = 0; i <= nsteps; i++)
+				X.push_back((range * i) / nsteps);
+			Y = test_spline->evaluate(X);
+			//print out data
+			cout << "###########################" << endl;
+			for (int i = 0; i < nsteps; i++)
+				cout << X[i] << "\t" << Y[i] << endl;
+			cout << "***************************" << endl;
+		}
+		{
+			cout << "test range exception" << endl;
+			try {
+				test_spline->evaluate(-10.0);
+				cerr << "range_error not thrown!" << endl;
+			} catch (std::range_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "test constructor with unequal lengths" << endl;
+			try {
+				doubleVector x, y;
+				x.push_back(1.0);
+				x.push_back(2.0);
+				x.push_back(3.0);
+
+				y.push_back(4.0);
+				y.push_back(5.0);
+				Spline spl(x, y, NAN, 0.0);
+				cerr << "length_error not thrown!" << endl;
+			} catch (std::length_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "test constructor with out of order data" << endl;
+			try {
+				doubleVector x, y;
+				x.push_back(1.0);
+				x.push_back(2.0);
+				x.push_back(1.5);
+
+				y.push_back(4.0);
+				y.push_back(5.0);
+				y.push_back(6.0);
+				Spline spl(x, y, NAN, 0.0);
+				cerr << "domain_error not thrown!" << endl;
+			} catch (std::domain_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "Test copy constructor" << endl;
+			Spline copy_spline(*test_spline);
+			double minx, maxx, copyminx, copymaxx;
+			test_spline->get_range(minx, maxx);
+			copy_spline.get_range(copyminx, copymaxx);
+			if ((minx != copyminx) || (maxx != copymaxx)) {
+				cerr << "COPY FAILED!" << endl;
+				return -1;
+			}
+			double range = x0[NP - 1];
+			double nsteps = 100;
+			for (int i = 0; i < nsteps; i++) {
+				double val = (range * i) / nsteps;
+				double y, ycopy;
+				ycopy = copy_spline.evaluate(val);
+				y = test_spline->evaluate(val);
+				if (y != ycopy) {
+					cerr << "COPY FAILED " << val << " " << y << " " << ycopy
+							<< endl;
+				}
+			}
+		}
+		{
+			cout << "Test copy assignment operator" << endl;
+			Spline oper_spline = *test_spline;
+			double minx, maxx, operminx, opermaxx;
+			test_spline->get_range(minx, maxx);
+			oper_spline.get_range(operminx, opermaxx);
+			if ((minx != operminx) || (maxx != opermaxx)) {
+				cerr << "ASSIGN COPY FAILED!" << endl;
+				return -1;
+			}
+			double range = x0[NP - 1];
+			double nsteps = 100;
+			for (int i = 0; i < nsteps; i++) {
+				double val = (range * i) / nsteps;
+				double y, yoper;
+				yoper = oper_spline.evaluate(val);
+				y = test_spline->evaluate(val);
+				if (y != yoper) {
+					cerr << "COPY FAILED " << val << " " << y << " " << yoper
+							<< endl;
+				}
+			}
+		}
+		cout << "test delete" << endl;
+		delete test_spline;
+		{
+			cout << "test leaks - new/delete" << endl;
+			Spline *dynspl;
+			doubleVector x, y;
+			x.push_back(1.0);
+			x.push_back(2.0);
+			x.push_back(3.5);
+
+			y.push_back(4.0);
+			y.push_back(5.0);
+			y.push_back(6.0);
+			for (int i = 0; i < 100; i++) {
+				dynspl = new Spline(x, y, NAN, 0.0);
+				delete dynspl;
+			}
+		}
+		{
+			cout << "test leaks - stack" << endl;
+			doubleVector x, y;
+			x.push_back(1.0);
+			x.push_back(2.0);
+			x.push_back(3.5);
+
+			y.push_back(4.0);
+			y.push_back(5.0);
+			y.push_back(6.0);
+			for (int i = 0; i < 100; i++) {
+				Spline stspl(x, y, NAN, 0.0);
+			}
+		}
+
+		{
+			cout << "test end conditions" << endl;
+			std::ofstream outfile;
+			outfile.open("splineval.csv", ios::out); //CHECK success
+			if ((outfile.rdstate() & ifstream::failbit) != 0)
+				return -1;
+			doubleVector x, y;
+			x.push_back(0.0);
+			y.push_back(0.0);
+			x.push_back(1.0);
+			y.push_back(1.0);
+			x.push_back(1.5);
+			y.push_back(1.0);
+			x.push_back(2.0);
+			y.push_back(1.0);
+			x.push_back(3.0);
+			y.push_back(0.0);
+			Spline nsp(x, y); //natural spline
+			Spline zsp(x, y, 0.0, 0.0); // spline with 0 derivate start and stop
+			Spline nzsp(x, y, NAN, 0.0); // spline with 0 derivate at stop
+			Spline znsp(x, y, 0.0, NAN); // spline with 0 derivate at start
+			Spline ddsp(x, y, -0.5, 0.5); // spline with derivatives at start and stop
+			double X;
+			double Yn, Yz, Ynz, Yzn, Ydd;
+			double range = 3.0;
+			int nsteps = 300;
+			for (int i = 0; i <= nsteps; i++) {
+				X = ((range * i) / nsteps);
+				Yn = nsp.evaluate(X);
+				Yz = zsp.evaluate(X);
+				Ynz = nzsp.evaluate(X);
+				Yzn = znsp.evaluate(X);
+				Ydd = ddsp.evaluate(X);
+				outfile << X << "\t\t" << Yn << "\t\t" << Yz << "\t\t" << Ynz
+						<< "\t\t" << Yzn << "\t\t" << Ydd << std::endl;
+			}
+			outfile.close();
+		}
+	}
+	//#######################################################################
+	{
+		cout << "test spline::inverse_evaluate" << endl;
+		{
+
+			doubleVector x, y;
+			x.push_back(10.0);
+			y.push_back(83.6);
+			x.push_back(12);
+			y.push_back(68.3);
+			x.push_back(14);
+			y.push_back(55.7);
+			x.push_back(16);
+			y.push_back(45.5);
+			x.push_back(18);
+			y.push_back(37.3);
+			x.push_back(20);
+			y.push_back(30.7);
+			x.push_back(22);
+			y.push_back(25.4);
+			x.push_back(24);
+			y.push_back(21.2);
+			x.push_back(26);
+			y.push_back(17.9);
+			x.push_back(28);
+			y.push_back(15.2);
+			x.push_back(30);
+			y.push_back(13.1);
+			x.push_back(32);
+			y.push_back(11.4);
+			x.push_back(34);
+			y.push_back(10.1);
+			x.push_back(36);
+			y.push_back(9);
+			x.push_back(40);
+			y.push_back(7.5);
+			x.push_back(50);
+			y.push_back(5.77);
+			Spline *lambdasplie = new Spline(x, y);
+			double gmin, gmax;
+
+			lambdasplie->get_range(gmin, gmax);
+			double max = lambdasplie->evaluate(gmin);
+			double min = lambdasplie->evaluate(gmax);
+			double initial = min + ((max - min) / 2);
+
+			double l = min;
+			double gap, linv;
+			cout << "l\tgap\tlinverse" << endl;
+			cout.precision(8);
+			while (l < max) {
+				gap = lambdasplie->inverse_evaluate(l, initial);
+				linv = lambdasplie->evaluate(gap);
+				cout << l << "\t" << gap << "\t" << linv << endl;
+				l += 0.05;
+			}
+			delete lambdasplie;
+		}
+	}
+	//###############################################################
+	{
+		cout << "test of periodicSpline interpolator class" << endl;
+		doubleVector x0, y0;
+		const int NP = 15;
+		const double k = (2 * M_PI) / NP;
+		for (int i = 0; i <= NP; i++) {
+			x0.push_back(i * k);
+			y0.push_back(sin(i * k));
+		}
+		periodicSpline *test_spline = new periodicSpline(x0, y0);
+		{
+			doubleVector a;
+			doubleVector b;
+			test_spline->get_base_points(a, b);
+			cout << "test get_base_points()" << endl;
+			for (unsigned int i = 0; i < a.size() - 1; i++)
+				if ((x0[i] != a[i]) || (y0[i] != b[i])) {
+					cout << i << " " << x0[i] << " " << a[i] << " | " << y0[i]
+							<< " " << b[i] << endl;
+					return -1;
+				}
+
+		}
+		{
+			cout << "test get_range()" << endl;
+			double minx, maxx;
+			test_spline->get_range(minx, maxx);
+			int I = x0.size() - 1;
+			if ((minx != x0[0]) || (maxx != x0[I])) {
+				cout << minx << " " << x0[0] << " | " << maxx << " " << x0[I]
+						<< endl;
+				return -1;
+			}
+		}
+		{
+			cout << "test evaluate()" << endl;
+			double xn = 0.02;
+			double yn = test_spline->evaluate(xn);
+			cout << xn << " " << yn << endl;
+			yn = test_spline->evaluate(x0[5]);
+			cout << xn << " " << yn << " " << y0[5] << endl;
+		}
+		{
+			cout << "test evaluate()" << endl;
+			double xn = 0.02;
+			double yn = test_spline->evaluate(xn);
+			cout << xn << " " << yn << endl;
+			yn = test_spline->evaluate(x0[5]);
+			cout << xn << " " << yn << " " << y0[5] << endl;
+		}
+		{
+			cout << "test evaluate()for plot" << endl;
+			doubleVector X;
+			doubleVector Y;
+			double minx;
+			double range;
+			test_spline->get_range(minx, range);
+			double nsteps = 100;
+			for (int i = 0; i <= nsteps; i++) {
+				X.push_back((range * i) / nsteps);
+				Y.push_back(test_spline->evaluate(X[i]));
+			}
+			//print out data
+			cout << "---------------------------" << endl;
+			for (unsigned int i = 0; i < x0.size(); i++)
+				cout << x0[i] << "\t" << y0[i] << endl;
+			cout << "---------------------------" << endl;
+			for (int i = 0; i <= nsteps; i++)
+				cout << X[i] << "\t" << Y[i] << endl;
+			cout << "+++++++++++++++++++++++++++" << endl;
+		}
+		{
+			cout << "test evaluate()for doubleVector" << endl;
+			doubleVector X;
+			doubleVector Y;
+			double minx;
+			double range;
+			test_spline->get_range(minx, range);
+			double nsteps = 100;
+			for (int i = 0; i <= nsteps; i++)
+				X.push_back((range * i) / nsteps);
+			Y = test_spline->evaluate(X);
+			//print out data
+			cout << "###########################" << endl;
+			for (int i = 0; i <= nsteps; i++)
+				cout << X[i] << "\t" << Y[i] << endl;
+			cout << "***************************" << endl;
+		}
+		{
+			cout << "test range exception" << endl;
+			try {
+				test_spline->evaluate(-10.0);
+				cerr << "range_error not thrown!" << endl;
+			} catch (std::range_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "test constructor with unequal lengths" << endl;
+			try {
+				doubleVector x, y;
+				x.push_back(1.0);
+				x.push_back(2.0);
+				x.push_back(3.0);
+
+				y.push_back(4.0);
+				y.push_back(5.0);
+				periodicSpline spl(x, y);
+				cerr << "length_error not thrown!" << endl;
+			} catch (std::length_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "test constructor with out of order data" << endl;
+			try {
+				doubleVector x, y;
+				x.push_back(1.0);
+				x.push_back(2.0);
+				x.push_back(1.5);
+
+				y.push_back(4.0);
+				y.push_back(5.0);
+				y.push_back(6.0);
+				periodicSpline spl(x, y);
+				cerr << "domain_error not thrown!" << endl;
+			} catch (std::domain_error &ex) {
+				cout << "OK, catched expected exception: " << ex.what() << endl;
+			} catch (...) {
+				cerr << "unexpected exception thrown!" << endl;
+			}
+		}
+		{
+			cout << "Test copy constructor" << endl;
+			periodicSpline copy_spline(*test_spline);
+			double minx, maxx, copyminx, copymaxx;
+			test_spline->get_range(minx, maxx);
+			copy_spline.get_range(copyminx, copymaxx);
+			if ((minx != copyminx) || (maxx != copymaxx)) {
+				cerr << "COPY FAILED!" << endl;
+				return -1;
+			}
+			double range;
+			test_spline->get_range(minx, range);
+			double nsteps = 100;
+			for (int i = 0; i < nsteps; i++) {
+				double val = (range * i) / nsteps;
+				double y, ycopy;
+				ycopy = copy_spline.evaluate(val);
+				y = test_spline->evaluate(val);
+				if (y != ycopy) {
+					cerr << "COPY FAILED " << val << " " << y << " " << ycopy
+							<< endl;
+				}
+			}
+		}
+		{
+			cout << "Test copy operator" << endl;
+			periodicSpline copy_spline(*test_spline);
+			copy_spline = *test_spline;
+			double minx, maxx, copyminx, copymaxx;
+			test_spline->get_range(minx, maxx);
+			copy_spline.get_range(copyminx, copymaxx);
+			if ((minx != copyminx) || (maxx != copymaxx)) {
+				cerr << "COPY FAILED!" << endl;
+				return -1;
+			}
+			double range;
+			test_spline->get_range(minx, range);
+			double nsteps = 100;
+			for (int i = 0; i < nsteps; i++) {
+				double val = (range * i) / nsteps;
+				double y, ycopy;
+				ycopy = copy_spline.evaluate(val);
+				y = test_spline->evaluate(val);
+				if (y != ycopy) {
+					cerr << "COPY FAILED " << val << " " << y << " " << ycopy
+							<< endl;
+				}
+			}
+		}
+		cout << "test delete" << endl;
+		delete test_spline;
+		{
+			cout << "test leaks - new/delete" << endl;
+			periodicSpline *dynspl;
+			doubleVector x, y;
+			x.push_back(1.0);
+			x.push_back(2.0);
+			x.push_back(3.5);
+
+			y.push_back(4.0);
+			y.push_back(5.0);
+			y.push_back(6.0);
+			for (int i = 0; i < 100; i++) {
+				dynspl = new periodicSpline(x, y);
+				delete dynspl;
+			}
+		}
+		{
+			cout << "test leaks - stack" << endl;
+			doubleVector x, y;
+			x.push_back(1.0);
+			x.push_back(2.0);
+			x.push_back(3.5);
+
+			y.push_back(4.0);
+			y.push_back(5.0);
+			y.push_back(6.0);
+			for (int i = 0; i < 100; i++) {
+				periodicSpline stspl(x, y);
+			}
+		}
+	}
+return 0;
+}
-- 
GitLab