将任意值(在某个范围内)“映射”到数组的离散值的常用方法是什么?
基本上我想要做的是为一系列离散输入值x = f(x)
预先计算复杂函数x
,并将每个输出值f(x)
存储在另一个数组fx
中},所以有两个向量:
x
- 离散输入值和fx
- 相应的离散输出值现在对于范围为x
的任意值,我想从fx
得到相应的输出,e。 G。值为x1 = 42
和向量
x = [ 30, 35, 40, 45, 50];
fx = [1.3, 1.8, 2.9, 4.5, 7.3];
该功能可能会返回
fx1 = 4.5
- 以fx
作为上限x
fx1 = 2.9
- 映射到fx
从x
获取最接近的值fx1 = 3.54
- 映射到fx
进行简单的线性化
fx1 = fxa + (fxb-fxa)/(xb-xa) * (x1-xa)
fx1 = 2.9 + (4.5-2.9)/(45-40) * (42-40)
函数*应该非常快,因为它在紧密循环中替换了“真实”函数的调用。第一个尝试,用于投入案例上面的列表之一是以下:
%% GET AT
% Retrieve f(x).
%
% * Synopsis: getAt (x, input_map, output_map)
% * Input : x - function input
% : input_map - array with precomputed input values
% : output_map - array with precomputed output values
%
% * Output : fx - function output
%
function fx = getAt (x, input_map, output_map)
n = length(input_map);
jj = length(find(input_map < x));
if (jj >= n)
fx = 0;
else
fx = output_map(jj+1);
end
end
但是我更需要一个C解决方案,因为循环也将在C中。
* ..只是在语言构造中寻找的方式而不是函数。
答案 0 :(得分:1)
我会使用线性插值(您的解决方案3)进行恒定外推,即低于30的所有内容都会映射到1.3以及超过50到7.3的所有内容。时间关键部分可能会找到正确的数组索引。
确切的实现取决于采样数组的大小以及输入值的分布方式。例如:
(fxb-fxa)/(xb-xa) * (x1-xa)
。很多&#34; mays&#34;。使用您的用例分析一些实现应该可以帮助您确定如何准确地实现查找功能。
答案 1 :(得分:1)
对x
数组执行二进制搜索,以查找完全匹配或两个条目,这些条目提供包含输入的间隔。对于精确匹配,结果是与x元素对应的(具有相同索引)fx元素。对于非精确匹配,请根据输入位于x0 ... x1区间的位置进行线性插值,并将其应用于两个对应的fx元素。除了拥有两个并行数组之外,您还可以拥有一个包含x和fx值的元素数组。
网上有很多关于如何对数组进行二进制搜索的来源,例如,
如果没有完全匹配,很容易调整这些条目以产生正确的条目对。你必须要小心边界,但......输入值小于x
数组的第一个元素或大于最后一个元素。
您还可以考虑插值搜索:
而不是二分搜索,因为它无论如何都需要在低边界和高边界之间进行线性插值。一旦你只有两个x条目并且没有找到完全匹配,只需将插值应用于相应的fx值。