matlab使用interp1查找索引?

时间:2012-10-08 14:32:20

标签: matlab math numerical-methods

我有一个Fa数组,其中包含我从函数中找到的值。有没有办法在Matlab中使用interp1函数来查找特定值出现的索引?我找到了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.8585 t值。

5 个答案:

答案 0 :(得分: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');

enter image description here

您应该先从val

中减去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

结果如下:

enter image description here

答案 1 :(得分:1)

您可以直接在Fa中搜索值:

idx = Fa==value_to_find;

要查找索引,请使用find函数:

find(Fa==value_to_find);

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

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

find(Fa>=value_to_find,1);

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

答案 2 :(得分:1)

Andrey's solution原则上有效,但此处提供的代码却没有。问题在于段的定义,它产生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

答案 3 :(得分: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)) x = 214.8585找到年份。这里pi&lt; x创建一个逻辑向量,用于过滤ti,仅提供p小于x的年份。然后使用max()来获取最近一年,如果假设p总是在增加,那么它也将最接近x。

答案 4 :(得分:0)

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

interp1(p,t,214.8585)

在这种情况下,您将解决特定人口已知的年份。

当有多个解决方案时,此方法不起作用。如果您使用Andrey的值进行尝试,您将只能获得问题的第一个解决方案。