![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
Successive use of smart_interp is implemented in twod_intp, which is useful for interpolating data presented on a two-dimensional grid (though the spacings between grid points need not be equal). An example demonstrating the use of twod_intp is given in ex_twod_intp_sect. Also, one can compute contour lines from data represented on a grid using the contour class.
If data is arranged without a grid, then planar_intp can be used. At present, the only way to compute contour lines on data which is not defined on a grid is to use planar_intp to recast the data on a grid and then use contour afterwards.
Higher-dimensional interpolation is possible with tensor_grid.
/* Example: ex_twod_intp.cpp ------------------------------------------------------------------- A simple example for two-dimensional interpolation using the twod_intp class. */ #include <o2scl/twod_intp.h> #include <o2scl/test_mgr.h> using namespace std; using namespace o2scl; // A function for filling the data and comparing results double f(double x, double y) { return pow(sin(0.1*x+0.3*y),2.0); } int main(void) { int i,j; test_mgr t; t.set_output_level(1); // Create the sample data ovector x(3), y(3); omatrix data(3,3); cout.setf(ios::scientific); // Set the grid x[0]=0.0; x[1]=1.0; x[2]=2.0; y[0]=3.0; y[1]=2.0; y[2]=1.0; // Set and print out the data cout << endl; cout << "Data: " << endl; cout << " x | "; for(i=0;i<3;i++) cout << x[i] << " "; cout << endl; cout << " y |" << endl; cout << "-------------|-"; for(i=0;i<3;i++) cout << "-------------"; cout << endl; for(i=0;i<3;i++) { cout << y[i] << " | "; for(j=0;j<3;j++) { data[i][j]=f(x[j],y[i]); cout << data[i][j] << " "; } cout << endl; } cout << endl; // Perform the interpolation cout << "x y Calc. Exact" << endl; twod_intp ti; // Interpolation, x-first double tol=0.05; double tol2=0.4; ti.set_data(3,3,x,y,data,true); double x0, y0, x1, y1; x0=0.5; y0=1.5; cout << x0 << " " << y0 << " " << ti.interp(x0,y0) << " " << f(x0,y0) << endl; x0=0.99; y0=1.99; cout << x0 << " " << y0 << " " << ti.interp(x0,y0) << " " << f(x0,y0) << endl; x0=1.0; y0=2.0; cout << x0 << " " << y0 << " " << ti.interp(x0,y0) << " " << f(x0,y0) << endl; cout << endl; // Interpolation, y-first ti.set_data(3,3,x,y,data,false); x0=0.5; y0=1.5; cout << x0 << " " << y0 << " " << ti.interp(x0,y0) << " " << f(x0,y0) << endl; x0=0.99; y0=1.99; cout << x0 << " " << y0 << " " << ti.interp(x0,y0) << " " << f(x0,y0) << endl; x0=1.0; y0=2.0; cout << x0 << " " << y0 << " " << ti.interp(x0,y0) << " " << f(x0,y0) << endl; cout << endl; t.report(); return 0; } // End of example
This example creates a sample 3 by 3 grid of data with the function and performs some interpolations and compares them with the exact result.
Data: x | 0.000000e+00 1.000000e+00 2.000000e+00 y | -------------|---------------------------------------- 3.000000e+00 | 6.136010e-01 7.080734e-01 7.942506e-01 2.000000e+00 | 3.188211e-01 4.150164e-01 5.145998e-01 1.000000e+00 | 8.733219e-02 1.516466e-01 2.298488e-01 x y Calc. Exact 5.000000e-01 1.500000e+00 2.380255e-01 2.298488e-01 9.900000e-01 1.990000e+00 4.112589e-01 4.110774e-01 1.000000e+00 2.000000e+00 4.150164e-01 4.150164e-01 5.000000e-01 1.500000e+00 2.380255e-01 2.298488e-01 9.900000e-01 1.990000e+00 4.112589e-01 4.110774e-01 1.000000e+00 2.000000e+00 4.150164e-01 4.150164e-01
This example generates contour lines of the function
/* Example: ex_contour.cpp ------------------------------------------------------------------- Example for generating contour lines */ #include <iostream> #include <o2scl/test_mgr.h> #include <o2scl/contour.h> #include <o2scl/ovector_tlate.h> using namespace std; using namespace o2scl; // A function defining the three-dimensional surface // for which we want to compute contour levels double fun(double x, double y) { return 15.0*exp(-pow(x-20.0,2.0)/400.0-pow(y-5.0,2.0)/25.0) +40.0*exp(-pow(x-70.0,2.0)/500.0-pow(y-2.0,2.0)/4.0); } // A function for outputting the data to cout int print_data(int nx, int ny, ovector_base &x, ovector_base &y, omatrix_base &data); // A function for printing the contour information to a file int file_out(vector<contour_line> &conts, vector<contour_line> &conts2); int main(void) { test_mgr t; t.set_output_level(1); cout.setf(ios::scientific); contour co; // Initialize the data ovector x(12), y(10); omatrix data(10,12); for(size_t i=0;i<10;i++) { y[i]=((double)i); } for(size_t i=0;i<12;i++) { x[i]=((double)i)*((double)i); } for(size_t j=0;j<12;j++) { for(size_t k=0;k<10;k++) { data[k][j]=fun(x[j],y[k]); } } co.set_data(12,10,x,y,data); // Print out the data print_data(12,10,x,y,data); // Set the contour levels ovector levels(7); levels[0]=5.0; levels[1]=10.0; levels[2]=0.002; levels[3]=20.0; levels[4]=0.2; levels[5]=30.0; levels[6]=2.0; co.set_levels(7,levels); // Compute the contours vector<contour_line> conts; co.calc_contours(conts); // Print the contours to the screen and test to make sure // that they match the requested level size_t nc=conts.size(); for(size_t i=0;i<nc;i++) { cout << "Contour " << i << " at level " << conts[i].level << ":" << endl; size_t cs=conts[i].x.size(); for(size_t j=0;j<cs;j++) { cout << "(" << conts[i].x[j] << ", " << conts[i].y[j] << ") " << fun(conts[i].x[j],conts[i].y[j]) << endl; t.test_rel(fun(conts[i].x[j],conts[i].y[j]),conts[i].level, 1.0,"curve"); } cout << endl; } // Refine the data using cubic spline interpolation def_interp_mgr<ovector_const_view,cspline_interp> dim1; def_interp_mgr<ovector_const_subvector,cspline_interp> dim2; co.regrid_data(5,5,dim1,dim2); // Recompute the contours vector<contour_line> conts2; co.calc_contours(conts2); // Output the contour information to a file for the documentation file_out(conts,conts2); t.report(); return 0; } // End of example
The figure below shows contour lines in the region . The data grid is represented by plus signs, and the associated generated contours. The figure clearly shows the obvious peaks at
and
.
The contour class can also use interpolation to attempt to refine the data grid. The new contours after a refinement of a factor of 5 is given in the figure below.
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).