首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用畸变时基拟合正弦波

用畸变时基拟合正弦波
EN

Stack Overflow用户
提问于 2014-05-27 21:43:02
回答 2查看 1.1K关注 0票数 6

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

时间畸变由t_distort = P(t)形式的n阶多项式(n~10)给出.

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

这将扭曲正弦波如下:

我想找出这种扭曲的正弦波的畸变。(也就是说,我想找到函数t = G(t_distort),但是t_distort = P(t)是未知的。)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-28 01:14:11

这是一条分析驱动的路径,它利用asin信号的适当的展开角度。然后,您可以在角度上使用polyfit对多项式进行拟合,也可以使用其他的拟合方法(搜索fit并查看)。最后,以拟合函数为例,将信号与拟合函数进行比较。见本教学实例:

代码语言:javascript
运行
复制
% 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))))]);

代码语言:javascript
运行
复制
p =

    0.0200    0.1200    0.2400    0.1600

我使用NaN预先分配并避免在不连续点(locs)取asin的原因是为了减少以后拟合的误差。正如你所看到的,对于0,10之间的100个点,平均误差是浮点精度的数量级,多项式系数和它们一样精确。

事实上,你没有接受导数(如在非常优雅的希尔伯特变换)允许数字精确。在相同的条件下,Hilbert变换解的平均误差要大得多(单位阶比为1e-15)。

这种方法的唯一限制是,您需要足够多的点,在这个范围内,asin翻转方向,并且sin中的函数表现良好。如果存在抽样问题,您可以截断数据,并且只能保持较小的接近于零的范围,这样就足以描述sin中的函数了。毕竟,您不需要数百万运算点来适应一个3参数函数。

票数 1
EN

Stack Overflow用户

发布于 2014-05-28 15:47:59

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

因为我不知道你所用的确切数字,所以我将用我自己的数字给出一个例子。假设我最初的时间基数从0到100有1000万点:

代码语言:javascript
运行
复制
t = 0:0.00001:100;

然后,我得到扭曲的时间基,并计算出扭曲的正弦波:

代码语言:javascript
运行
复制
td = 0.02*(t+2).^3;
yd = sin(td);

现在我可以解调了。以使用近似差分除以前的步长的“导数”为例:

代码语言:javascript
运行
复制
ydot = diff(yd)/0.00001;

信封可以是easily detected

代码语言:javascript
运行
复制
envelope = abs(hilbert(ydot));

这给出了P(t)的导数的一个逼近。最后一步是积分器,我可以使用累积和进行近似(我们必须再次按步骤大小进行缩放):

代码语言:javascript
运行
复制
tdguess = cumsum(envelope)*0.00001;

这给出了一条与原始扭曲的时间基几乎完全相同的曲线(因此,它给出了P(T)的一个很好的近似):

你不可能得到多项式的常量项,因为我们用它的导数作了逼近,这当然消除了常数项。你甚至不可能在数学上从yd中找到一个唯一的常数项,因为无限多的值会产生相同的畸变正弦波。如果你知道P(t)的程度(忽略最后一个数,它是常数),你可以用多元拟合得到P(t)的其他三个系数:

代码语言:javascript
运行
复制
>> 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)的近似值吗?

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23899473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档