适合正弦波,扭曲的时基

时间:2014-05-27 21:43:03

标签: matlab time curve-fitting distortion sine

我想知道在Matlab中使用扭曲的时基来拟合正弦波的最佳方法。

时间失真由n阶多项式(n~10)给出,形式为t_distort = P(t)

例如,考虑失真t_distort = 8 + 12t + 6t^2 + t^3(这只是(t-2)^3的幂级数展开。)

这会扭曲正弦波,如下所示:

IMG http://i59.tinypic.com/67ukcy.png

我希望能够在失真的正弦波下找到失真。 (即我想找到函数t = G(t_distort),但t_distort = P(t)未知。)

2 个答案:

答案 0 :(得分:4)

如果你的分辨率足够高,那么这基本上是一个角度解调问题。解调角度调制信号的标准方法是采用导数,然后是包络检波器,然后是积分器。

由于我不知道你正在使用的确切数字,我将以自己的数字显示一个例子。假设我的原始时基从0到100有1000万个点:

t = 0:0.00001:100;

然后我得到扭曲的时基并计算失真的正弦波:

td = 0.02*(t+2).^3;
yd = sin(td);

现在我可以解调它了。采取"衍生物"使用近似差异除以之前的步长:

ydot = diff(yd)/0.00001;

信封可以是easily detected

envelope = abs(hilbert(ydot));

这给出了P(t)的导数的近似值。最后一步是积分器,我可以使用累积和来近似(我们必须按步长再次缩放):

tdguess = cumsum(envelope)*0.00001;

这给出了与原始失真时基几乎相同的曲线(因此,它给出了P(t)的良好近似值):

enter image description here

因为我们从它的导数中得出了近似值,所以你不可能得到多项式的常数项,这当然会消除常数项。你甚至无法从yd以数学方式找到一个唯一的常数项,因为无限多的值会产生相同的失真正弦波。如果你知道P(t)的程度(忽略最后一个数字,它是常数项),你可以使用polyfit得到P(t)的其他三个系数:

>> polyfit(t(1:10000000), tdguess, 3)

ans =

    0.0200    0.1201    0.2358    0.4915

除了常数项外,这与原始值非常接近:0.02 *(t + 2)^ 3 = 0.02t ^ 3 + 0.12t ^ 2 + 0.24t + 0.16。

你想要逆映射Q(t)。知道到目前为止发现的P(t)的近似值,你能做到吗?

答案 1 :(得分:1)

这是一条分析驱动路线,通过正确展开角度来获取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))))]);

enter image description here

p =

    0.0200    0.1200    0.2400    0.1600

我预先分配NaN并避免在不连续点(locs)处取asin的原因是为了减少拟合的误差。如您所见,对于0,10之间的100个点,平均误差是浮点精度的顺序,并且多项式系数与您可以得到的一样精确。

你没有采用衍生物(如在非常优雅的希尔伯特变换中)这一事实允许在数值上精确。对于相同的条件,希尔伯特变换解决方案将具有更大的平均误差(统一级别对1e-15)。

这种方法的唯一限制是你需要在asin翻转方向的区域内有足够的点,并且sin内的函数表现良好。如果存在采样问题,您可以截断数据并仅保持较小的范围接近零,这样就足以表征sin内的函数。毕竟,您不需要数百万个操作点来适应3参数功能。