Matlab 与FFT求极值的区别

Matlab 与FFT求极值的区别,matlab,differentiation,Matlab,Differentiation,我试图找到一个函数的零点。请参阅下面的代码 因为fft需要一个数字数组,所以我没有定义使用fzero的符号函数 但是,这种方法不准确,取决于步骤。你有更好的主意吗 step=2000; x=0:pi/step:2*pi; y= 4+5*cos(10*x)+20*cos(40*x)+cos(100*x); fy = fft(y'); fy(1:8) =0; fy(12:end-10)=0; fy(end-6:end)=0; ffy = ifft(fy); t=diff(ffy); x=0:pi/

我试图找到一个函数的零点。请参阅下面的代码

因为
fft
需要一个数字数组,所以我没有定义使用
fzero
的符号函数

但是,这种方法不准确,取决于
步骤
。你有更好的主意吗

step=2000;
x=0:pi/step:2*pi;
y= 4+5*cos(10*x)+20*cos(40*x)+cos(100*x);
fy = fft(y');
fy(1:8) =0;
fy(12:end-10)=0; 
fy(end-6:end)=0;
ffy = ifft(fy);
t=diff(ffy);
x=0:pi/step:2*pi-pi/step;
plot(x,t)
indices= find(t<5e-4 & t>-5e-4);
step=2000;
x=0:pi/步进:2*pi;
y=4+5*cos(10*x)+20*cos(40*x)+cos(100*x);
fy=fft(y');
fy(1:8)=0;
财政年度(12:10月底)=0;
fy(结束-6:结束)=0;
ffy=ifft(fy);
t=diff(ffy);
x=0:pi/步:2*pi/步;
图(x,t)
指数=find(t-5e-4);

您可以沿着数组
t
继续查找值改变符号的点。这将表明零的存在

实际上,MATLAB的
fzero
函数使用了类似的方法。你说你没有使用它是因为你需要一个数组,而不是一个匿名函数,但是你可以使用简单的线性插值将数组转换成匿名函数,如下所示:

func = @(k) interp1(x,t,k);  % value of t(x) interpolated at x=k
fzero(func,initial_value);

编辑:只是为了澄清我的意思。如果你有一个数组
t
,你想找到它的零

f = 5;                            % frequency of wave in Hz
x = 0:0.01:1;                     % time index
t = cos( 2*pi*f*x );              % cosine wave of frequency f

zeroList = [];                    % start with an empty list of zeros
for i = 2:length(t)               % loop through the array t

    current_t = t(i);             % current value of t
    previous_t = t(i-1);          % previous value of t

    if current_t == 0                  % the case where the zero is exact
        newZero = x(i);
        zeroList = [zeroList,newZero];
    elseif current_t*previous_t < 0    % a and b have opposite sign if a*b is -ve
        % do a linear interpolation to find the zero (solve y=mx+b)
        slope = (current_t-previous_t)/(x(i)-x(i-1));
        newZero = x(i) - current_t/slope;
        zeroList = [zeroList,newZero];
    end

end

figure(1); hold on;
axis([ min(x) max(x) -(max(abs(t))) (max(abs(t))) ]); 
plot(x,t,'b');
plot(x,zeros(length(x)),'k-.');
scatter(zeroList,zeros(size(zeroList)),'ro');
f=5;%波的频率(单位:Hz)
x=0:0.01:1;%时间索引
t=cos(2*pi*f*x);%频率f的余弦波
零列表=[];%从零的空列表开始
对于i=2:长度(t)%通过数组t循环
电流t=t(i);%t的当前值
以前的t=t(i-1);%t的先前值
如果当前_t==0%,则零是精确的
newZero=x(i);
zeroList=[zeroList,newZero];
如果a*b为-ve,则a和b具有相反的符号
%进行线性插值以找到零点(解算y=mx+b)
斜率=(当前值-先前值)/(x(i)-x(i-1));
newZero=x(i)-电流/斜率;
zeroList=[zeroList,newZero];
结束
结束
图(1);等等
轴([min(x)max(x)-(max(abs(t)))(max(abs(t)))]);
图(x,t,'b');
绘图(x,零(长度(x)),'k-'。);
散布(零列表,零(大小(零列表)),'ro');
我得到的零是正确的:


很好,很有效。是否有任何方法可以找到给定间隔内的所有零,如[0 2pi]?或者我应该做一个循环,并尝试不同的子间隔?我将循环数组中的所有元素,并有一个变量来记住前一个元素。如果当前元素和以前的元素符号不同,则您已找到零元素。是否保存索引?在不同的零中改变符号?克里斯:非常感谢。