www.gusucode.com > curvefit 案例源码程序 matlab代码 > curvefit/ppalldem.m

    %% Construct and Work with the PPFORM
%
% This example shows how to construct and work with the ppform of a spline in
% Curve Fitting Toolbox(TM).

% Copyright 1987-2012 The MathWorks, Inc.

%% 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)
%%
% 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)

%%
% 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')

%%
% 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 pp is efficient for _evaluation_, the _construction_
% of a pp 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 this, look at the example <spalldem.html Introduction to the B-form>.


displayEndOfDemoMessage(mfilename)