Construct and Work with the PPFORM
This example shows how to construct and work with the ppform of a spline in Curve Fitting Toolbox™.
Introduction
A (univariate) piecewise polynomial, or pp for short, is characterized by its break sequence, breaks
say, and its coefficient array, coefs
say, of the local power form of its polynomial pieces. The break sequence is assumed to be strictly increasing,
breaks(1) < breaks(2) < ... < breaks(l+1),
with l
the number of polynomial pieces that make up the pp. In the figure below, breaks
is [0,1,4,6], hence l
is 3.
While these polynomials may be of varying degrees, they are all recorded as polynomials of the same order k
, i.e., the coefficient array coefs
is of size [l,k]
, with coefs(j,:)
containing the k
coefficients in the local power form for the j
-th polynomial piece.
Here is an example of a pp made up of three quadratic polynomials, i.e., l
= k
= 3. The breaks are marked in red.
sp = spmak([0 1 4 4 6],[2 -1]); pp = fn2fm(sp,'pp') ; breaks = fnbrk(pp,'b'); coefs = fnbrk(pp,'c'); coefs(3,[1 2]) = [0 1]; pp = ppmak(breaks,coefs,1); fnplt(pp,[breaks(1)-1 breaks(2)],'g',1.8) hold on fnplt(pp, breaks([2 3]),'b',1.8) fnplt(pp,[breaks(3),breaks(4)+1],'m',1.8) lp1 = length(breaks); xb = repmat(breaks,3,1); yb = repmat([2;-2.2;NaN],1,lp1); plot(xb(:),yb(:),'r') axis([-1 7 -2.5 2.3]) hold off
The precise description of the pp in terms of the break sequence breaks
and the coefficient array coefs
is
pp(t) = polyval(coefs(j,:), t-breaks(j))
for breaks(j) <= t < breaks(j+1)
where, to recall,
polyval(a,x) = a(1)*x^(k-1) + a(2)*x^(k-2) + ... + a(k)*x^0.
For the pp in the figure above, breaks(1)
is 0, and coefs(1,:)
is [-1/2 0 0], while breaks(3)
is 4, and coefs(3,:)
is [0 1 -1]. For t
not in [breaks(1) .. breaks(l+1)]
, pp(t)
is defined by extending the first or last polynomial piece.
A pp is usually constructed through a process of interpolation or approximation. But it is also possible to make one up in ppform from scratch, using the command ppmak
. For example, the pp above can be obtained as
breaks = [0 1 4 6]; coefs = [1/2 0 0 -1/2 1 1/2 0 1 -1]; fn = ppmak(breaks,coefs)
fn = struct with fields: form: 'pp' breaks: [0 1 4 6] coefs: [3x3 double] pieces: 3 order: 3 dim: 1
This returns, in fn
, a complete description of this pp function in the so-called ppform.
Various commands in Curve Fitting Toolbox can operate on this form. The remaining sections show some examples.
Operating on Piecewise Polynomials
To evaluate a pp, use the fnval
command.
fnval(fn, -1:7)
ans = Columns 1 through 7 0.5000 0 0.5000 1.0000 0.5000 -1.0000 0 Columns 8 through 9 1.0000 2.0000
To differentiate a pp, use the fnder
command.
dfn = fnder ( fn ); hold on fnplt(dfn, 'jumps','y', 3) hold off h1 = findobj(gca,'Color','y'); legend(h1,{'First Derivative'},'location','SW')
Note that the derivative of the example pp is continuous at 1 but discontinuous at 4. Also note that, by default, fnplt
plots a ppform on its basic interval, i.e., on the interval [breaks(1) .. breaks(end)]
.
You can also use fnder
to take the second derivative of a pp.
ddfn = fnder(fn, 2); hold on fnplt( ddfn ,'j', 'k', 1.6) hold off h2 = findobj(gca,'Color','k'); legend([h1 h2],{'First Derivative' 'Second Derivative'},'location','SW')
The second derivative is piecewise constant.
Note that differentiation via fnder
is done separately for each polynomial piece. For example, although the first derivative has a jump discontinuity across 4, the second derivative is not infinite there. This has consequences when we integrate the second derivative.
To integrate a pp, use the fnint
command.
iddfn = fnint(ddfn); hold on fnplt(iddfn, 'b', .5) hold off h3 = findobj(gca,'Color','b', 'LineWidth',.5); legend([h1 h2 h3],{'First Derivative' 'Second Derivative' ... 'Integral of Second Derivative'},'location','SW')
Note that integration of the second derivative does recover the first derivative, except for the jump across 4, which cannot be recovered, since the integral of any pp function is continuous.
You can obtain parts with the aid of the command fnbrk
. For example
breaks = fnbrk(fn, 'breaks')
breaks = 0 1 4 6
recovers the break sequence of the pp in fn
, while
piece2 = fnbrk(fn, 2);
recovers the second polynomial piece, as this plot confirms.
fnplt(pp,[breaks(1)-1 breaks(2)],'g',1.8) hold on fnplt(piece2, 'b', 2.5, breaks([2 3])+[-1 .5]) fnplt(pp,[breaks(3),breaks(4)+1],'m',1.8) plot(xb(:),yb(:),'r') title('The Polynomial that Supplies the Second Polynomial Piece') hold off axis([-1 7 -2.5 2.3])
Vector-Valued Piecewise Polynomials
A pp can also be vector-valued, to describe a curve, in 2-space or 3-space. In that case, each local polynomial coefficient is a vector rather than a number, but nothing else about the ppform changes. There is one additional part of the ppform to record this, the dimension of its target.
For example, here is a 2-vector-valued pp describing the unit square, as its plot shows. It is a 2D-curve, hence its dimension is 2.
square = ppmak(0:4, [1 0 0 1 -1 1 0 0 ; 0 0 1 0 0 1 -1 1]); fnplt(square,'r',2) axis([-.5 1.5 -.5 1.5]) axis equal title('A Vector-Valued PP that Describes a Square')
Multivariate Piecewise Polynomials
A pp in Curve Fitting Toolbox can also be multivariate, namely, a tensor product of univariate pp functions. The ppform of such a multivariate pp is only slightly more complicated, with breaks
now a cell array containing the break sequence for each variable, and coefs
now a multidimensional array. It is much harder to make up a non-random such function from scratch, so we won't try that here, particularly since the toolbox is meant to help with the construction of pp functions from some conditions about them. For example, the sphere in this figure is constructed with the aid of csape
.
x = 0:4; y = -2:2; s2 = 1/sqrt(2); v = zeros(3,7,5); v(3,:,:) = [0 1 s2 0 -s2 -1 0].'*[1 1 1 1 1]; v(2,:,:) = [1 0 s2 1 s2 0 -1].'*[0 1 0 -1 0]; v(1,:,:) = [1 0 s2 1 s2 0 -1].'*[1 0 -1 0 1]; sph = csape({x,y},v,{'clamped','periodic'}); fnplt(sph) axis equal axis off title('A Sphere Described by a Bicubic 3-Vector-Valued Spline')
While the ppform of a spline is efficient for evaluation, the construction of a spline from some data is usually handled more efficiently by first determining its B-form, i.e., its representation as a linear combination of B-splines. For more information, see Construct and Work with the B-form.