MATLAB Answers

Zero crossing for a curve fitting function(smoothing spline)

8 views (last 30 days)
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
plot(t, y, '-r')
hold on
plot(t(zx), y(zx), 'bp')
hold off
legend('Signal', 'Approximate Zero-Crossings')
How can I solve the problem?
Thanks in advance!


Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 3 Apr 2020
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.


Show 2 older comments
Star Strider
Star Strider on 3 Apr 2020
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);
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
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
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.
Star Strider
Star Strider on 3 Apr 2020
My pleasure!
If my Answer helped you solve your problem, please Accept it!

Sign in to comment.

More Answers (0)

Sign in to answer this question.