我这样做:
>> plot(x,y1,x,y2);
>> x=0:0.001:5;
>> y1=sin(x)+cos(1+x.^2)-1;
>> y2 = ((1/2).*x)-1;
>> find (y1==y2)
得到这个:
ans =
Empty matrix: 1-by-0
作为一个答案,它只是让我发疯!我不知道为什么Matlab和Scilab没有给我相交的答案。我一直试图使间隔变小,如x = 0:0.0001:5
;但它没有改变任何东西。如何让它返回交叉点值?
谢谢。
答案 0 :(得分:1)
你必须记住Matlab用于找到问题的数值解法。您提供了一组离散的输入点x=0:0.001:5;
,并要求它计算离散输出点y1[x]
和y2[x]
。这意味着y1
和y2
不是连续的,并且不一定像它们的连续对应物那样相交。我没有Matlab,所以我没有运行你的代码,但是你的离散函数很可能不会出现问题。也就是说,a = y1[x_i]
和b = y2[x_i]
没有一对a = b
。相反,您最想要做的是查找y2-y1
在特定输入处为零的一侧的点,以及在下一次输入的零的另一侧。这意味着函数的连续conterparts会在两者之间交叉。
函数满足但不交叉的情况稍微有些棘手,但同样的想法。
编辑:
这种事情最容易用图像包裹,所以我创建了一个说明我的意思。
在这里,我使用的点少于你想要使用的点数,但这个想法是一样的。您可以看到y1和y2的连续版本在几个地方交叉,但是您要求matlab做的是在y1中找到一个点,该点等于y2中相同x值的点。在这张图片中你可以看到很多都很接近,但你的计算机存储的浮点数非常高,所以实际上它们相等的可能性非常小。
当您增加采样点数时,图像看起来更像是“连续对应物”。
答案 1 :(得分:1)
现有的两个答案解释了为什么你不能轻易找到一个确切的交叉点。但你真正需要的是回答做什么而不是以获得精确的交叉点?
在您的具体情况下,您知道要想出的交叉点的分析函数。您可以使用fzero
和(可选的匿名)函数来查找由两个原始函数的差异定义的函数的零:
y1fun = @(x) sin(x)+cos(1+x.^2)-1;
y2fun = @(x) ((1/2).*x)-1;
diff_fun = @(x) y1fun(x)-y2fun(x);
x0 = 1; % starting point for fzero's zero search
x_cross = fzero(diff_fun,x0);
现在,这将为您提供差异函数的一个零,即一个的函数交集。事实证明,找到函数的每个零是一项具有挑战性的任务。通常,您必须使用各种起点fzero
多次致电x0
。如果你怀疑你的功能是什么样的,那就完全没有希望了。
那么如果你的功能更乱,会发生什么?在一般情况下,您可以使用插值函数在上面的示例中播放y1fun
和y2fun
的部分,例如使用interp1
:
% generate data
xdata = 0:0.001:5;
y1data = sin(xdata)+cos(1+xdata.^2)-1;
y2data = ((1/2).*xdata)-1;
y1fun = @(x) interp1(xdata,y1data,x);
y2fun = @(x) interp1(xdata,y2data,x);
x0 = 1; % starting point for fzero's zero search
x_cross = fzero(@(x)y1fun(x)-y2fun(x),x0);
这导致了原来的问题。请注意,interp1
默认情况下使用线性插值,具体取决于您的函数的外观以及数据的散布方式,您可以选择其他选项。还要注意外推的选项(要避免)。
因此,在这两种情况下,每次拨打fzero
都会得到一个交叉点。通过仔细选择起点,您应该能够尽可能准确地找到所有零点。
答案 2 :(得分:0)
也许这两个向量在任何地方都没有完全相等的值。您可以尝试搜索最小的差异:
abs(y1-y2)<tolerance
其中公差= 0.001是一个小数