3

我有一个 Fa 数组,其中包含我从函数中找到的值。有没有办法interp1在 Matlab 中使用函数来查找特定值出现的索引?我找到了一些教程,通过了解相应的索引值interp1,我可以在数组中找到一个特定的值。interp1

来自http://www.mathworks.com/help/matlab/ref/interp1.html的示例:

这里有两个向量代表从 1900 年到 1990 年的人口普查年份以及相应的美国人口(以百万计)。

t = 1900:10:1990;
p = [75.995  91.972  105.711  123.203  131.669...
    150.697  179.323  203.212  226.505  249.633];

该表达式interp1(t,p,1975)在人口普查数据中插值以估计 1975 年的人口。结果是

ans =
    214.8585

- 但我想找到214.8585t的值。

4

5 回答 5

2

从某种意义上说,你想找到一个函数的根——

f(x)-val

首先,可能有几个答案。其次,由于该函数是分段线性的,您可以通过求解相关的线性方程来检查每个段。

例如,假设您有以下数据:

t = 1900:10:1990;
p = [75.995  91.972  105.711  123.203  131.669...
    150.697  179.323  70.212  226.505  249.633];

你想找到值 140

val = 140;    
figure;plot(t,p);hold on;
plot( [min(t),max(t)], [val val],'r');

在此处输入图像描述

您应该首先减去valfrom的值p

p1 = p - val;

现在您只需要p1符号更改的段,或者从+-> -,反之亦然。

segments = abs(diff(sign(p1)==1));

在这些段中的每一个中,您都可以求解相关的线性方程a*x+b==0,并找到根。那是你价值的指数。

for i=1:numel(segments)
    x(1) = t(segments(i));
    x(2) = t(segments(i)+1);
    y(1) = p1(segments(i));
    y(2) = p1(segments(i)+1);
    m = (y(2)-y(1))/(x(2)-x(1));
    n = y(2) - m * x(2);
    index = -n/m;
    scatter(index, val ,'g');
end

结果如下:

在此处输入图像描述

于 2012-10-08T14:36:58.920 回答
1

Andrey 的解决方案原则上有效,但此处提供的代码无效。问题在于段的定义,它产生一个 0 和 1 的向量,然后对“t(segments(i))”的调用导致错误(我试图复制和粘贴代码 - 我希望我做到了不会在那个简单的任务中失败)。

我对段的定义做了一个小改动。它可能会做得更优雅。这里是:

t = 1900:10:1990;
p = [75.995  91.972  105.711  123.203  131.669...
    150.697  179.323  70.212  226.505  249.633];

val = 140;    
figure;plot(t,p,'.-');hold on;
plot( [min(t),max(t)], [val val],'r');

p1 = p - val;

tn = 1:length(t);
segments = tn([abs(diff(sign(p1)==1)) 0].*tn>0);

for i=1:numel(segments)
    x(1) = t(segments(i));
    x(2) = t(segments(i)+1);
    y(1) = p1(segments(i));
    y(2) = p1(segments(i)+1);
    m = (y(2)-y(1))/(x(2)-x(1));
    n = y(2) - m * x(2);
    index = -n/m;
    scatter(index, val ,'g');
end
于 2014-10-12T07:36:22.627 回答
1

可以Fa直接在里面搜索值:

idx = Fa==value_to_find;

查找索引使用find函数:

find(Fa==value_to_find);

当然,这仅在value_to_find中存在时才有效Fa。但据我了解,这就是你想要的。你不需要interp那个。

另一方面,如果该值可能不存在于 中Fa,但Fa已排序,则可以搜索大于 的值value_to_find并获取第一个此类索引:

find(Fa>=value_to_find,1);

如果您的问题比这更复杂,请查看 Andreys 的答案。

于 2012-10-08T14:38:13.960 回答
0

安德烈在上面给出了最一般情况的答案,我同意。对于您所说的示例,一个简单的特定解决方案是:

interp1(p,t,214.8585)

在这种情况下,您正在求解给定人口已知的年份。

当有多个解决方案时,这种方法将不起作用。如果你用安德烈的价值观来尝试这个,你只会得到问题的第一个解决方案。

于 2012-10-08T18:52:23.890 回答
0

将整个函数内插到更高的精度。然后搜索。

t = 1900:10:1990;
p = [75.995  91.972  105.711  123.203  131.669...
    150.697  179.323  203.212  226.505  249.633];

precision = 0.5;
ti = 1900:precision:1990;

pi = interp1(t,p,ti);

现在 pi 每半年保存一次所有 pi 值。假设值总是增加,您可以通过max(ti(pi < x))where找到年份x = 214.8585。这里 pi < x 创建了一个逻辑向量,用于过滤 ti 以仅提供 p 小于 x 的年份。然后 max() 用于获取最近的一年,如果 p 总是增加的假设成立,这也将最接近 x。

于 2012-10-08T14:43:30.677 回答