我设置了一个测试信号如下:
fs = 50;
N = 10000;
Ts = 1/fs;
t = (0:N-1)*Ts;
x = 3*cos(2*pi*0.4*t)+0.1*randn(size(t));'
然后希望利用fminsearch来做正弦参数估计,能够在有一定噪声的情况下估计出幅度频率和相位
global fun2
fun2 = x;
g0 = [0,0,0];
fun = @rss;
[g,fval] = fminsearch(fun,g0);
目标函数是RSS,设置了一个全局变量来储存原始信号
function f = rss(g)
global fun2
ti = (0:9999)*0.05;
fun1 = g(1)*cos(2*pi*g(2)*ti+g(3));
f = sum((fun1-fun2).^2);
end
可是运行出来的结果非常接近0,按理说应该分别接近3 0.4 0,不知道哪里出现了问题,改变初始值也没有用
虽然通过options作图收敛了,可是最终目标函数最小值仍有e+04
根据你的代码,我复现了一下,发现最终目标函数值的确非常小,但是估计值与真实值偏差很大。我看到你的代码中使用了全局变量 fun2 来储存原始信号,在目标函数 rss 中使用。这种方式存在很大的风险,因为在多线程或者多个函数之间共享全局变量时可能会出现互相干扰的情况。
我建议你将原始信号 x 作为目标函数的参数,而不是使用全局变量。此外,你可以尝试增加 fminsearch 的迭代次数,或者使用其他更高级的优化方法。以下是修改后的代码示例:
fs = 50;
N = 10000;
Ts = 1/fs;
t = (0:N-1)*Ts;
x = 3*cos(2*pi*0.4*t)+0.1*randn(size(t));
g0 = [0, 0.4, 0];
fun = @(g) rss(g, t, x);
options = optimset('MaxIter', 1000);
[g, fval] = fminsearch(fun, g0, options);
function f = rss(g, t, x)
fun1 = g(1)*cos(2*pi*g(2)*t + g(3));
f = sum((fun1 - x).^2);
end