qspline_build) that
builds an interpolation function for a given set of points; and a function
(e.g. qspline_evaluate) that evaluates the interpolation
function at a given point. For the linear spline there is not much to
build, so one function (e.g. linear_spline) should suffice.
Using different styles of programming the exercise can be solved as follows,
Procedural programming (C,Pascal,Fortran-77,...):
struct qspline {int n; double *x,*y,*b,*c};
Alternatively, you can define a new type qspline
typedef struct {int n; double *x, *y, *b, *c;} qspline;
and then in the following instead of struct qspline simply
use qspline.
Implement a routine which allocates the necessary memory, calculates
the spline coefficients c and returns the (pointer to the)
properly filled qspline structure:
struct qspline* qspline_construct(int n, double* x,double* y);
Implement a routine which—given the precalculated
qspline structure—computes the spline interpolation
function at a given point z:
double qspline_evaluate(struct qslpine* my_qspline, double z);
qspline_free, which frees
the memory occupied by structure qspline.
void qspline_free(struct qslpine* my_qspline);
Object
oriented programming (C++, Java, Python, C#, ...): the structure (or
class) holds not only data but also all the appropriate
functions (called member functions) which have direct access to the data
in the structure:
qspline which holds all the
data for spline; the construction function becomes the constructor
method; the evaluation function becomes the member function; the
qspline_free function becomes the destructor method which
is defined automatically (I think):
struct qspline {
vector<double> x,y,c; // the data for the spline
qspline(vector<double> x, vector<double> y); // constructor
double evaluate(double z); // evaluates the interpolation function
};
std::vector<double>
is a useful container in C++.
Functional programming (C++11, Lisp, Haskell, Python, JavaScript, ...): only the function for spline-evaluation is created and returned. This function captures all the needed information in itself (in its environment, to be precise):
function<double(double)> construct_qspline_evaluation_function(vector<double> x, vector<double> y);
double linterp(int n, double *x, double *y, double z);
struct qspline *qspline_construct(int n, double *x, double *y);
double qspline_evaluate(struct qspline *S, double z);
void qspline_free(struct qspline *S);
for(int i = 0; i < 10; i++)
{ x[i] = i + 0.5 * sin (i); y[i] = i + cos (i * i); }
and plot the two interpolating functions (together with the data points).
Hints:
graph utility from
plotutils; an example of using it can be found here.
Implement a function which estimates the derivative and the anti-derivative (indefinite integral) of a tabulated function by building a quadratic spline and then differentiating and integrating the spline (analytically!).
Check your implementation e.g. on the following data (or better some other indicative data of your choice):
for(int i = 0;i<10;i++) { x[i] = i*M_PI/9; y[i] = sin (x[i]); }
Hint: for the integral the routine should return
∫x0z S(x) dx
Implement cubic spline with derivative and anti-derivative. Compare with quadratic spline.
For C,C++: check that the GSL cubic spline functions give the same result as your cubic spline.
For C++: make a C++ wrapper for the GSL cubic spline functions and check that they give the same result as your cubic spline.
For languages with available libraries: check that library implementation of cubic spline gives the same result as your spline.
For languages without good libraries: check that Octave cubic
spline routine gives the same result as your implementation. On molveno
Octave is simple octave, on lifa Octave is
/usr/users/fedorov/bin/octave.