How to recreate a piecewise polynomial from polyfit to values in each interval?
Show older comments
I need to recreate the piecewise polynomial coefficients from values of the evaluated piecewise polynomial. I want to create an equivalent pp struct.
The pp has been stored as values sampled to enable a unique fit of each polynomial segment (i.e. values at the break times, and 4 internal points for each 6th order polynomial segment: 6 values, 6 polynomial coefficients to solve).
I thought I could use polyfit() on each break interval of samples to get each segment's polynomial coefficients, then use mkpp(). Scaled and centred, or not, the polyfit() coefficients in pp form do not reproduce the original samples, but evaluating polyval(polyfit()) for each segment does. I'm not clear why there's a difference.
What have I missed? Can it be done without the Curve Fitting Tool box?
An example for a single 6th order polynomial, split into 3 segments shows the discrepancy:
% Define polynomial coefs, x and y
p = [1, 2, 3, 4, 5, 6];
x = -5:10;
y = polyval(p, x);
% Define a pp form with knots at -5, 0, 5, 10
d = 1;
knotInterval = 5;
breaks = -5:knotInterval:10;
pieces = length(breaks)-1;
coefs = nan(pieces*d, length(p));
coefsScaled = nan(pieces*d, length(p));
mu = nan(pieces*d, 2);
yPolyval = nan(pieces, knotInterval+1);
% For the 6 (x,y) values in each pp break interval, fit an order 6
% polynomial, centered and scaled polynomial, and evaluate the standard
% fitted polynomial.
for nPiece = 1:pieces
idxPiece = x >= breaks(nPiece) & x <= breaks(nPiece+1);
coefs(nPiece, :) = polyfit(x(idxPiece), y(idxPiece), length(p)-1);
[coefsScaled(nPiece, :), ~, mu(nPiece, :)] = polyfit(x(idxPiece), y(idxPiece), length(p)-1);
yPolyval(nPiece,:) = polyval(coefs(nPiece, :), x(idxPiece));
end
% Build pp for the coefs and scaled coefs
pp = mkpp(breaks, coefs, d);
ppScaled = mkpp(breaks, coefsScaled, d);
% Plot the original data, and the fitted pp and polynomials
xPolyval = [-5:0; 0:5; 5:10];
plot(x, y, 'x-', x, ppval(pp, x), 'o--', x, ppval(ppScaled, x), '^--', ...
xPolyval(1, :), yPolyval(1, :), 'sq-.', xPolyval(2, :), yPolyval(2, :), 'sq-.', ...
xPolyval(3, :), yPolyval(3, :), 'sq-.')
ylim(1e5*[-1, 3])
legend({'True data', 'pp', 'ppScaled', ...
'Recovered polyval 1', 'Recovered polyval 2', 'Recovered polyval 3'})

Accepted Answer
More Answers (0)
Categories
Find more on Polynomials in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!