Zero crossing for a curve fitting function(smoothing spline)

Hello,
I want find the zero-crossings of a smoothing spline function that I got using the Curve Fitting toolbox and plot the points were this occurs. The function code is the following:
%% Fit: 'Jan 2012'.
[xData, yData] = prepareCurveData( x_jan_12_s, Price_jan_12_s );
% Set up fittype and options.
ft = fittype( 'smoothingspline' );
excludedPoints = excludedata( xData, yData, 'Indices', [2 276] );
opts = fitoptions( 'Method', 'SmoothingSpline' );
opts.SmoothingParam = 8.24530273269464e-08;
opts.Exclude = excludedPoints;
% Fit model to data.
[fitresult{2}, gof(2)] = fit( xData, yData, ft, opts );
% Plot fit with data.
figure( 'Name', 'Jan 2012 Supply France Peak' );
plot( fitresult{2}, 'k');
% Label axes
xlabel( 'Volume [MWh]', 'Interpreter', 'none' );
ylabel( 'Price', 'Interpreter', 'none' );
However with his code, you need to define the y, which is not available for my fit curve (y is contained in fitresult{2}):
t = [1:0.01:5]; % Time Vector
y = sin(2*pi*t); % Signal
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Zero-Crossing Indices Of Argument Vector
zx = zci(y); % Approximate Zero-Crossing Indices
figure(1)
plot(t, y, '-r')
hold on
plot(t(zx), y(zx), 'bp')
hold off
grid
legend('Signal', 'Approximate Zero-Crossings')
How can I solve the problem?
Thanks in advance!

 Réponse acceptée

I don’t have the Curve Fitting Toolbox. (I only need it to reply to Answers Questions, and that’s not enough justification for me to buy it.) However from the documentation, the cfit function is likely what you need to recover the fitted values from the ‘fitresult{2}’ output:
y = cfit(fitresult{2}, xData);
I have no idea what the curve or data look like. It may be necessary to subtract the mean of the cfit output from the rest of it so that it has the necessary zero-crossings to use with my code. If you want the exact zero-crossings (my code returns the closest indices to them), it will be necessary to interpolate them. This is not difficult, however it will require your data to demonstrate it.

5 commentaires

I read the cfit help and the second input should be the Parameter, that means for my example:
y = cfit(fitresult{2}, 8.24530273269464e-08);
However, this gives me 1*1 cfit with this note:
val =
Smoothing spline:
val(x) = piecewise polynomial computed from p
Coefficients:
p = coefficient structure
Looking around a little bit more I found that
y=feval(fitresult{2},xData)
Should work, however when I apply it to your function like this:
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0);
zx = zci(y);
figure(1)
plot(fitresult{2}, 'k')
hold on
plot(xData(zx), yData(zx), 'bp')
hold off
grid
legend('Signal', 'Approximate Zero-Crossings')
I got the following graph:
Any idea of what went wrong? Why the first start is not in the graph? why the second start is not even in the y=0 line?
Thanks!
Is this because of the mean problem that @Star Strider mentioned? I attach here my orignal data, so you can take a look.
I do not if you need to have the cftool to use the following command,
f = fit(xData, yData,'smoothingspline','SmoothingParam',8.24530273269464e-08)
[f,gof,out] = fit(xData, yData,'smooth',options);
That gives you the same result as what cftool provides.
Thanks in advance!
As I mentioned, I do not have the Curve Fitting Toolbox, so I cannot do the smoothing splline. You are quoting my code, so I can help with that part.
The spline appears to be causing problems. If you simply want to find the zero-crossings in your original data:
D1 = readmatrix('data.xlsx');
xData = D1(:,1);
yData = D1(:,2);
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0);
zx = zci(yData);
if yData(1) * yData(end) < 0 % Remove Spurious Result
zx = zx(1:end-1);
end
for k = 1:numel(zx)
exact_x(k) = interp1(yData(zx(k))+[-1 1]/1E+4, xData(zx(k))+[-1 1]/1E+4, 0); % Interpolate To Find ‘x’ Values At Zero-Crossing Indices
end
figure
plot(xData, yData)
hold on
% plot(xData(zx), yData(zx), '+r') % Identified Indices
plot(exact_x, zeros(size(exact_x)), 'xr') % Interpolated Values
hold off
grid
axis([4740 4875 -1 1]) % Zoom Region (Delete)
There is one actual zero crossing. My code detects two and calculates one appropriately and attempts to extrapolate another and so returns NaN. The one it returns is correct.
My ‘zci’ function will return a spurious zero-crossing if the beginning and end of the vector have opposite signs. The if block that I added corrects for that problem.
This works amazing! thank you!
My pleasure!
If my Answer helped you solve your problem, please Accept it!

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Get Started with Curve Fitting Toolbox dans Centre d'aide et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by