这是一个分析驱动的路径,它采用信号的asin 并正确展开角度。然后您可以在角度上使用polyfit 或使用其他拟合方法拟合多项式(搜索fit 并查看)。最后,对拟合函数取一个罪,并将信号与拟合函数进行比较......请参阅这个教学示例:
% generate data
t=linspace(0,10,1e2);
x=0.02*(t+2).^3;
y=sin(x);
% take asin^2 to obtain points of "discontinuity" where then asin hits +-1
da=(asin(y).^2);
[val locs]=findpeaks(da); % this can be done in many other ways too...
% construct the asin according to the proper phase unwrapping
an=NaN(size(y));
an(1:locs(1)-1)=asin(y(1:locs(1)-1));
for n=2:numel(locs)
an(locs(n-1)+1:locs(n)-1)=(n-1)*pi+(-1)^(n-1)*asin(y(locs(n-1)+1:locs(n)-1));
end
an(locs(n)+1:end)=n*pi+(-1)^(n)*asin(y(locs(n)+1:end));
r=~isnan(an);
p=polyfit(t(r),an(r),3);
figure;
subplot(2,1,1); plot(t,y,'.',t,sin(polyval(p,t)),'r-');
subplot(2,1,2); plot(t,x,'.',t,(polyval(p,t)),'r-');
title(['mean error ' num2str(mean(abs(x-polyval(p,t))))]);
p =
0.0200 0.1200 0.2400 0.1600
我使用NaN 预先分配并避免在不连续点(位置)使用asin 的原因是为了减少以后拟合的错误。如您所见,对于 0,10 之间的 100 个点,平均误差是浮点精度的数量级,并且多项式系数尽可能精确。
您不采用导数这一事实(如在非常优雅的希尔伯特变换中)允许在数值上精确。在相同条件下,希尔伯特变换解决方案的平均误差会大得多(单位阶与 1e-15 的阶数)。
此方法的唯一限制是您需要在 asin 翻转方向的机制中有足够的点,并且 sin 内的函数表现良好。如果存在采样问题,您可以截断数据并仅保持更接近零的范围,这样就足以表征sin 中的函数。毕竟,您不需要数百万个操作点来适应 3 参数函数。