Back to November Calendar            ←Previous Entry                             Next Entry→

November 12, 2005

Spline Representations IV

 

 

Any road, the NLib example program 4.4.2: Cubic Spline Fit finally produces the spline plot shown here:

Let’s compare this curve with the more well-known 8th degree interpolating polynomial whose coefficients c are obtained by solving the system

                                                                             

Where V is the Vandermonde matrix,

                                                               

whose elements are powers of xi.  In MatLab, you can then use the backslash operator, \, to solve the least squares problem as c = y\V.

 

More simply, you can use the m-file polyfit.  This is shown here:

 

Define the domain of the control points:

>> t = [-4:1:4]

t =

    -4    -3    -2    -1     0     1     2     3     4

 

Define the range of the control points:

>> y=1./(1+t.*t)

y =

  Columns 1 through 6

    0.0588    0.1000    0.2000    0.5000    1.0000    0.5000

  Columns 7 through 9

    0.2000    0.1000    0.0588

 

Define the domain x and range f of the polynomial fit points and plot the control points and the interpolating polynomial together. Note that p will contain just the coefficients of the fitting polynomial:

>> x = (-4: 0.1: 4)';

>> p = polyfit(t,y,8);

>> f = polyval(p,x);

>> plot(t,y,'o',x,f,'-')

Happily, this is corroborated by the Scientific Notebook result (using its Maple engine) to enter

 

 the 8th degree interpolating polynomial

 

 

How about computing and comparing the measure of total curvature for the interpolating polynomial and the spline? 

 

Here’s some nice commentary from the MatLab help on integration:

The area beneath a section of a function F(x) can be determined by numerically integrating F(x), a process referred to as quadrature. The MATLAB quadrature functions are:

 

     quad        Use adaptive Simpson quadrature
     quadl       Use adaptive  Lobatto quadrature

     dblquad     Numerically evaluate double integral
     triplequad  Numerically evaluate triple integral

 

To integrate the function defined by humps.m from 0 to 1, use q = quad(@humps,0,1)

 

q =

    29.8583

 

Both quad and quadl operate recursively. If either method detects a possible singularity, it prints a warning. You can include a fourth argument for quad or quadl that specifies a relative error tolerance for the integration. If a nonzero fifth argument is passed to quad or quadl, the function evaluations are traced.

 

I should note that I tried to use an m-file to define a polynomial function from its coefficient array, which I succeeded in doing (just a for loop that does pretty much what polyval does) but quad rejected it…I don’t know why.  Perhaps it’ll die. 

 

Anyroad, it got under my hat and between my ears to try using MatLab’s quad for integrating (aka quadrature) to compute the total curvature .   It’s taken much more time than I had anticipated!  Firstly, I wondered whether   might be a better measure of the curvature.  Curvature is usually defined as the rate of change of direction per change in arc length:

                                                               

where r(s) is the curve parameterized by the arc length, s, and T is the tangent vector.

 

For another parameterization parameter, say, t, (arc length is often tricky, if not completely impracticable) the formula can be worked this way:

 

Differentiating dr/dt we get

                       

This allows the following formation of the cross product of first and second derivatives of the position vector per parameter t:

                                        

Equating the norms,

                                                     

I wonder if this derivation for k came about through mere luck and that’s why the justification  seems to start with an object out of the blue and end in a formula for curvature we can savor:

 

This formula works for 3-D space curves with x, y and z parameterized by t, but a planar (2-D) curve with z=0 (the xy plane) is a special case worthy of simplification.  In this case,

                                                              

My worry at this juncture, is that, if I am to develop an integral for the accumulated curvature over some length of curve I’ll need to integrate something like

                                                                      

which strikes me as an intractable unwieldliness of no low order.  However, it would seem to suffice to measure the total curvature as the area under the curvature curve (heh) and since

 

a more convenient measure might be , which is what H/B claimed in the first place.  Here’s the m-file I wrote to compute these

function y = polyCurveFunk(a,b)

% [a,b] is the interval over which we'll sample

% x at integer inputs and

% y as the corresponding 1/(1+x^2) function values

x = [a:1:b];

y = 1./(1.+x.^2);

% n is the number of subintervals in this sampling

n = length(x)-1;

% p is the interpolating polynomial

p = polyfit(x,y,n);

% resample x for high resolution

x = [a:(b-a)/10000:b];

% generate interpolating polynomial y-values for this higher resolution

pv = polyval(p,x);

% p1 has coefficients for the derivative function of p

p1 = polyder(p);

% these are the coefficients of the polynomial for p1^2

p1square = conv(p1,p1);

% p2 has the coefficients for the derivative of p1

p2 = polyder(p1);

% generate values for terms in curvature function and generate

p1squarevals = polyval(p1square,x);

p2absvals = abs(polyval(p2,x));

curvature = p2absvals./(1.+p1squarevals).^1.5;

% plots

plot(x,pv,x,curvature)

% zero out left endpoint to get  right-endpoint sum of integral

curvature(1) = 0;

sum(curvature)*(b-a)/10000

% compute simpler measure for comparison

sum(p2absvals.*p2absvals)*(b-a)/10000

 

Here’s calling the function:

 

>> polyCurveFunk(-4,4);

ans =

   8.54760869196934

ans =

   2.404317873342450e+002

 

So the  measure of the total curvature is about 8.5476 while the simpler  measure is about 240.43 .

 

 

 

compare that with the sum of the total curvatures of the 8 cubic splines.

To compute the equivalent measures of total curvature for the spline, I think we’ll somehow have to get the actual cubics, rather than just do the magic function call!  For me, this has meant commandeering the whole MatLab/NLib into the land of c++.  I see three good reasons for this approach:

  • C++ compilers are free and more basic…given that MatLab is probably written in C++.
  • There are no mystery boxes; all the code is under your control.
  • You can modify pieces if you like.  For instance, you can ask it to tell you the coefficients of the cubic splines.