1DTupleInterpolation
VTKExamples/Cxx/Math/1DTupleInterpolation
Description¶
Contributed by: Lars Friedrich
A simple example that shows how to use vtkTupleInterpolator for the purpose of interpolating 1D functions. Internally the program investigates two functions: sine and Runge function with sparsely distributed supporting points. The application uses different interpolation modes: '''linear''', '''cardinal spline''' and '''Kochanek spline'''. Moreover, the example offers the "--csv-output" (or "-co") option which causes the program to generate CSV-sheets reflecting the interpolated data. In order to demonstrate the spline interpolation behavior at the edge regions, we use the '''open''' and '''closed''' interval spline options as well. For example, a Kochanek-interpolation of the Runge function:
Program Usage¶
./1DTupleInterpolation [](options) -h or --help ... print this short help -nv or --no-verbose ... no verbose messages to std::cout -co or --csv-output ... CSV (comma separated values) file outputs
Note
optional arguments are case-sensitive!
Code¶
1DTupleInterpolation.cxx
// #include <cstdlib> #include <iostream> #include <string> #include <fstream> #include <cmath> #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #include <ctime> #include <vtkSmartPointer.h> #include <vtkTupleInterpolator.h> #include <vtkCardinalSpline.h> #include <vtkKochanekSpline.h> #define VERBOSE(x) \ { \ if (Verbose) \ {\ std::cout x; \ std::cout.flush(); \ }\ } // verbose flag bool Verbose = true; // CSV output flag bool CSVOutput = false; /** * Print example usage information. **/ void PrintUsage(char *binname) { std::string progname = "<binary-name>"; if (binname) progname = std::string(binname); std::cout << "\n"; std::cout << " *** E X A M P L E U S A G E ***\n"; std::cout << "\n"; std::cout << progname << " [options]\n"; std::cout << "\n"; std::cout << " -h or --help ... print this short help\n"; std::cout << " -nv or --no-verbose ... no verbose messages to std::cout\n"; std::cout << " -co or --csv-output ... CSV (comma separated values) file outputs\n"; std::cout << "\n"; std::cout << " NOTE: optional arguments are case-sensitive!\n"; std::cout << "\n"; std::cout << " Author: ---\n"; std::cout << " Affiliation: ---\n"; std::cout << "\n"; } /** Runge function. **/ double FRunge(double x) { return 1.0 / (1.0 + x * x); } /** Sine function. **/ double FSin(double x) { return sin(x); } /** Execute a specific tuple interpolation method with pre-initialized tuple interpolator. **/ bool TestInterpolation(vtkSmartPointer<vtkTupleInterpolator> tupInt, double tolerance, const char *csvFileName, double (*mathFunc)(double), double *x, double *y, double N, double symmetricIntervalWidth) { bool ok = true; std::ofstream csvint; if (CSVOutput) { csvint.open(csvFileName, std::ios::out); if (csvint.is_open()) csvint << "x;y;e\n"; else ok = false; } double yt[1]; for (int i = 0; i < N; i++) // re-define supporting points { yt[0] = y[i]; tupInt->AddTuple(x[i], yt); } // draw random samples from interval and test against mathFunc: for (int i = 0; i < 1000; i++) { double f = (double) (rand() % 100001) / 100000.; double xi = (f * 2.0 - 1.0) * symmetricIntervalWidth; double yi[1]; tupInt->InterpolateTuple(xi, yi); double ei = std::abs(yi[0] - mathFunc(xi)); // we have a tolerance within [-PI;+PI] - empirical! if (xi >= -symmetricIntervalWidth && xi <= symmetricIntervalWidth && ei > tolerance) ok = false; if (CSVOutput && csvint.is_open()) csvint << xi << ";" << yi[0] << ";" << ei << "\n"; } if (CSVOutput && csvint.is_open()) csvint.close(); return ok; } /** \brief Demonstrate base functionality of VTK-based tuple interpolation (1D). * Demonstrate base functionality of VTK-based tuple interpolation (1D). * * Application result is 0 if SUCCESSFUL. * * Arguments: <br> * -h or --help ... print short help <br> * -nv or --no-verbose ... message output (verbose) <br> * -co or --csv-output ... CSV (comma separated values) file outputs <br> * * @author --- * @version 1.2 */ int main(int argc, char *argv[]) { // arguments check for (int i = 1; i < argc; i++) { if (std::string(argv[i]) == "-nv" || std::string(argv[i]) == "--no-verbose") Verbose = false; if (std::string(argv[i]) == "-h" || std::string(argv[i]) == "--help") { if (argc > 0) PrintUsage(argv[0]); else PrintUsage(NULL); return EXIT_FAILURE; } if (std::string(argv[i]) == "-co" || std::string(argv[i]) == "--csv-output") CSVOutput = true; } VERBOSE(<< "\nDemonstrating VTK-based 1-tuple interpolation capabilities.\n") bool ok = true; VERBOSE(<< " * Generate supporting points ... ") bool lok = true; // local OK // - SINE - const int N1 = 13; double *xs = new double[N1]; double *ys = new double[N1]; std::ofstream csv; if (CSVOutput) { csv.open("sine.csv", std::ios::out); if (csv.is_open()) csv << "x;y\n"; else lok = false; } // prepare the supporting points (sine): for (int i = 0; i < N1; i++) { xs[i] = -M_PI + (double) i / (double) (N1 - 1) * (2. * M_PI); ys[i] = FSin(xs[i]); if (CSVOutput && csv.is_open()) csv << xs[i] << ";" << ys[i] << "\n"; } if (CSVOutput && csv.is_open()) csv.close(); // - RUNGE - const int N2 = 10; double *xr = new double[N2]; double *yr = new double[N2]; if (CSVOutput) { csv.open("runge.csv", std::ios::out); if (csv.is_open()) csv << "x;y\n"; else lok = false; } // prepare the supporting points (sine): for (int i = 0; i < N2; i++) { xr[i] = -5.0 + (double) i / (double) (N2 - 1) * (2. * 5.0); yr[i] = FRunge(xr[i]); if (CSVOutput && csv.is_open()) csv << xr[i] << ";" << yr[i] << "\n"; } if (CSVOutput && csv.is_open()) csv.close(); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of sine using linear method ... ") // initialize the tuple interpolator (1D): vtkSmartPointer<vtkTupleInterpolator> tupInt = vtkSmartPointer<vtkTupleInterpolator>::New(); tupInt->SetInterpolationTypeToLinear(); // linear tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.04, "sin_linear_int.csv", FSin, xs, ys, N1, M_PI); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of sine using cardinal spline method (open interval) ... ") // initialize the tuple interpolator (1D): tupInt->SetInterpolationTypeToSpline(); // spline (implicit reset!) vtkSmartPointer<vtkCardinalSpline> cardSpline = vtkSmartPointer<vtkCardinalSpline>::New(); cardSpline->SetClosed(false); tupInt->SetInterpolatingSpline(cardSpline); tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.1, "sin_card_spline_open_int.csv", FSin, xs, ys, N1, M_PI); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of sine using cardinal spline method (closed interval) ... ") // initialize the tuple interpolator (1D): tupInt->Initialize(); // reset tupInt->SetInterpolationTypeToSpline(); // spline cardSpline->SetClosed(true); tupInt->SetInterpolatingSpline(cardSpline); tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.05, "sin_card_spline_closed_int.csv", FSin, xs, ys, N1, M_PI); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of sine using Kochanek spline (default setup) method (open interval) ... ") // initialize the tuple interpolator (1D): tupInt->Initialize(); // reset tupInt->SetInterpolationTypeToSpline(); // spline vtkSmartPointer<vtkKochanekSpline> kochSpline = vtkSmartPointer<vtkKochanekSpline>::New(); kochSpline->SetClosed(false); tupInt->SetInterpolatingSpline(kochSpline); tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.1, "sin_koch_spline_open_int.csv", FSin, xs, ys, N1, M_PI); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of sine using Kochanek spline (default setup) method (closed interval) ... ") // initialize the tuple interpolator (1D): tupInt->Initialize(); // reset tupInt->SetInterpolationTypeToSpline(); // spline kochSpline->SetClosed(true); tupInt->SetInterpolatingSpline(kochSpline); tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.06, "sin_koch_spline_closed_int.csv", FSin, xs, ys, N1, M_PI); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of Runge using linear method ... ") // initialize the tuple interpolator (1D): tupInt->Initialize(); tupInt->SetInterpolationTypeToLinear(); // linear tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.25 /* around 0! */, "runge_linear_int.csv", FRunge, xr, yr, N2, 5.0); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of Runge using cardinal spline method ... ") // initialize the tuple interpolator (1D): tupInt->SetInterpolationTypeToSpline(); // spline (implicit reset!) cardSpline->SetClosed(false); tupInt->SetInterpolatingSpline(cardSpline); tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.15 /* around 0! */, "runge_card_spline_int.csv", FRunge, xr, yr, N2, 5.0); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") VERBOSE(<< " * Interpolation of Runge using Kochanek spline method ... ") // initialize the tuple interpolator (1D): tupInt->Initialize(); // reset tupInt->SetInterpolationTypeToSpline(); // spline (implicit reset!) kochSpline->SetClosed(false); tupInt->SetInterpolatingSpline(kochSpline); tupInt->SetNumberOfComponents(1); // 1D (NOTE: set #components AFTER interpolation-type!) lok = TestInterpolation(tupInt, 0.18 /* around 0! */, "runge_koch_spline_int.csv", FRunge, xr, yr, N2, 5.0); ok = ok && lok; VERBOSE(<< (lok ? "OK" : "FAILURE") << "\n") delete[] xs; delete[] ys; delete[] xr; delete[] yr; cardSpline = NULL; kochSpline = NULL; tupInt = NULL; VERBOSE(<< "Application result: ") if (ok) { VERBOSE(<< "OK\n\n") return EXIT_SUCCESS; } else { VERBOSE(<< "FAILURE\n\n") return EXIT_FAILURE; } }
CMakeLists.txt¶
cmake_minimum_required(VERSION 2.8) PROJECT(1DTupleInterpolation) find_package(VTK REQUIRED) include(${VTK_USE_FILE}) add_executable(1DTupleInterpolation MACOSX_BUNDLE 1DTupleInterpolation.cxx) target_link_libraries(1DTupleInterpolation ${VTK_LIBRARIES})
Download and Build 1DTupleInterpolation¶
Danger
The generation of tar files has not been ported to the new VTKExamples. Some tarballs may be missing or out-of-date.
Click here to download 1DTupleInterpolation and its CMakeLists.txt file. Once the tarball 1DTupleInterpolation.tar has been downloaded and extracted,
cd 1DTupleInterpolation/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./1DTupleInterpolation
WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.