How to specify breaks for spline fitting?

조회 수: 8 (최근 30일)
lilythefirst
lilythefirst 2022년 7월 28일
편집: Matt J 2022년 7월 28일
Hello,
I want to fit piecewise, but continous functions to a given data and get the corresponding polynomial coefficients.
This can be done by pp = spline(x,y) , however, the spline function returns a fixed number of polynomials on uniformly distributed break points. How can I fit my data to a user defined number of pieces and specify the breaks for each polynomial?
With s = spline(x,y,xq) it's not possible to get the polynomial coefficients.
  댓글 수: 1
Bruno Luong
Bruno Luong 2022년 7월 28일
편집: Bruno Luong 2022년 7월 28일
"This can be done by pp = spline(x,y) , however, the spline function returns a fixed number of polynomials on uniformly distributed break points."
This statement is plain wrong, it returns the piecewise 3rd order polynomial on the x data you specify.
x=cumsum(rand(1,5))
x = 1×5
0.1903 0.3395 0.4592 0.9220 1.2917
y=rand(size(x))
y = 1×5
0.8196 0.0271 0.5946 0.5382 0.6362
pp=spline(x,y)
pp = struct with fields:
form: 'pp' breaks: [0.1903 0.3395 0.4592 0.9220 1.2917] coefs: [4×4 double] pieces: 4 order: 4 dim: 1
You see that the "breaks" or knots are exactly the x vector and it is not uniform.
And spline functions return the interpolation function, not the fit.
As you use wrong mathematical vocabulary and claim statement, it is hard to know what is your aim.

댓글을 달려면 로그인하십시오.

답변 (2개)

Matt J
Matt J 2022년 7월 28일
편집: Matt J 2022년 7월 28일
One way,
xknots=... %specify the break points
fun=@(y,xdata)spline(xknots,y,xdata);
y0=zeros(1,numel(xknots));
y=lsqcurvefit(fun,y0,xdata,ydata);
out=@(x) fun(y,x); %Fitted function

Bruno Luong
Bruno Luong 2022년 7월 28일
It seems I iedit again a wrong post that is not mine ! Sorry that happens for people who is distracted like me, probably age is not helping.
I put here my comment followed Matt's answer, and I would like to point out that a simple linear algebra is enough because spline function is linear with repect to fit y-value:
% Generate test data
xdata = rand(1,200);
ydata = sin(10*xdata); % whatever the model
ydata = ydata + 0.1*randn(size(ydata));
xknots = linspace(0,1,10); % The vector of knots that you want it to be
% Find out y vector at xknots such that the spline will fit the data
nknots = length(xknots);
ndata = length(xdata);
M = zeros(ndata,nknots);
for k=1:nknots
byk = accumarray(k,1,[nknots,1]);
M(:,k) = spline(xknots,byk,xdata);
end
y = M\ydata(:);
% Check the spline model
xq = linspace(0,1,100);
yq = spline(xknots,y,xq);
plot(xdata, ydata, '.', xq, yq, 'r')
  댓글 수: 3
Matt J
Matt J 2022년 7월 28일
편집: Matt J 2022년 7월 28일
A more direct way to generate M would be to use func2mat from the File Exchange,
fun=@(yknots)spline(xknots,yknots,xdata);
M=func2mat(fun, xknots);
Bruno Luong
Bruno Luong 2022년 7월 28일
편집: Bruno Luong 2022년 7월 28일
"Is this also true if there are end-slopes specified in y?"
Once x, y values are specified, the cubic spline function still has 2 DOFs. Most of the time if one select a homogenuous boundary condition such as
  • f'''(left) = f''(right) = 0, (natural spline)
  • f'(left) = f'(right) = 0
  • not-a-knot bc (MATLAB spline)
  • f(left) = f(right) and f'(left) = f'(right) (periodic spline)
then yes it is linear.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Spline Postprocessing에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by