# How to fit a sine curve with only the maximum and minimum values

조회 수: 12 (최근 30일)
Patricia Hauser 2024년 4월 8일
댓글: Alexander 2024년 4월 9일
Hi, I am trying to plot a sine wave through the high and low water points from a measuring station in the North Sea.
The image shows the first few data points. I've tried fitting a curve, filling the gaps etc. but I can't get Matlab to acknowledge the oscillating signal.
Help will be appreciated, thank you!
this is the goal:
##### 댓글 수: 2없음 표시없음 숨기기
Mann Baidi 2024년 4월 8일
Hi,
What type of 'fitType' are you passing in the 'fit' function?
Sam Chak 2024년 4월 8일
It might be easier to fit a custom sinusoidal waveform if the data is converted to the unit of 'seconds'. However, it is important to note that the time step in the t vector is not uniform.
where and are the time-varying amplitude and the time-varying period of the sine wave, respectively.
T = 58x2 table
t_datetime t_datenum ____________________ _________ 01-Jan-2022 03:05:00 -1.3 01-Jan-2022 09:02:00 1.5 01-Jan-2022 15:32:00 -1.4 01-Jan-2022 21:34:00 1.4 02-Jan-2022 04:08:00 -1.4 02-Jan-2022 10:06:00 1.5 02-Jan-2022 16:31:00 -1.4 02-Jan-2022 22:29:00 1.5 03-Jan-2022 05:03:00 -1.6 03-Jan-2022 11:04:00 1.5 03-Jan-2022 17:24:00 -1.4 03-Jan-2022 23:20:00 1.6 04-Jan-2022 05:56:00 -1.6 04-Jan-2022 11:59:00 1.5 04-Jan-2022 18:16:00 -1.4 05-Jan-2022 00:09:00 1.7
x = T{:,1}; % datetime data
t = seconds(x - x(1)); % convert to seconds
A = T{:,2}; % high and low points of the sea level
stem(t, A), grid on, xlabel('Time (sec)'), ylabel('Sea level')
title('Sea level around the North Sea from 1st to 15th, Jan 2022')

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

### 답변 (2개)

Bruno Luong 2024년 4월 8일
편집: Bruno Luong 2024년 4월 8일
piecewise (co)sine interpolation (not fitting).
I don't think you have extra DOF to play with if you restrict data to be local extrema and model follows a sinusoidal law.
t=datenum(data.t_datetime);
dt = t-t(1);
y = data.t_datenum;
dti = linspace(min(dt),max(dt),1025);
yi = sininterp(dt, y, dti); % function defined below
% Ploy check result
figure
subplot(2,1,1)
dtfun = @(dt) datetime(dt+t(1),'ConvertFrom','datenum');
h = plot(dtfun(dt),y,"ob",dtfun(dti),yi,"r");
% zoom plot
ax2 = subplot(2,1,2);
h = plot(dtfun(dt),y,"ob",dtfun(dti),yi,"r");
xlim(ax2, dtfun([8 11]))
%%
function yi = sininterp(t, y, ti)
ti = ti(:);
i = discretize(ti, t);
yi = nan(size(ti));
valid = i>=1 & i<numel(ti);
i = i(valid);
y1 = y(i);
y2 = y(i+1);
ym = (y1+y2)/2;
A = (y1-y2)/2;
alpha = (ti(valid) - t(i)) .* (pi./(t(i+1)-t(i)));
yi(valid) = ym + A.*cos(alpha);
end
##### 댓글 수: 1이전 댓글 -1개 표시이전 댓글 -1개 숨기기
Alexander 2024년 4월 9일
Perfect. I'll put it in my stock for special purposes.

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

R 2024년 4월 8일
Hi Particia,
Fitting a piecewise cubic Hermite ("pchip") curve might help with this use case. Here is an example of the same
% Read data from Excel file
% Convert first column to string array for time labels
time = string(table2array(data(:, 1)));
% Extract water level data from second column
waterLevel = table2array(data(:, 2));
% Create index array for plotting
x=(1:58)'; % Ensure x is a column vector
% Plot water level data
plot(x,waterLevel,".");
title('Water Level vs. Time');
xticklabels(time) % Set custom x-axis tick labels
% Fit a piecewise cubic Hermite interpolating polynomial
[curve,gof,output] = fit(x,waterLevel,"pchipinterp");
% Overlay fitted curve on the plot
hold on
plot(curve)
hold off
Here is the plot I get after executing the above code:
You can also find a list of curve fitting models that MATLAB supports in the following documentation:

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

### 카테고리

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

### Community Treasure Hunt

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

Start Hunting!

Translated by