C 将值映射到数组的通用解决方案

C 将值映射到数组的通用解决方案,c,arrays,matlab,C,Arrays,Matlab,将任意值(在一定范围内)映射到数组的离散值的常用方法是什么 基本上,我想做的是为一系列离散输入值预先计算一个复杂函数,并将每个输出值存储在另一个数组中,这样就有两个向量: 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-将x作为上限映射到fx fx1=2.9

将任意值(在一定范围内)映射到数组的离散值的常用方法是什么

基本上,我想做的是为一系列离散输入值预先计算一个复杂函数,并将每个输出值存储在另一个数组中,这样就有两个向量:

  • 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
    -将
    x
    作为上限映射到
    fx
  • 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)
  • 函数*应该非常快,因为它在一个紧密的循环中替代了对“real”函数的调用。第一次尝试用于实践上面列出的案例之一,如下所示:

    %% 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
    
    %%获取
    %检索f(x)。
    %
    %*简介:getAt(x,输入映射,输出映射)
    %*输入:x-功能输入
    %:input_map-具有预计算输入值的数组
    %:output_map-具有预计算输出值的数组
    %
    %*输出:fx-功能输出
    %                   
    函数fx=getAt(x,输入映射,输出映射)
    n=长度(输入图);
    jj=长度(查找(输入_映射=n)
    fx=0;
    其他的
    fx=输出图(jj+1);
    结束
    结束
    
    然而,我更倾向于寻找C解决方案,因为循环也将在C中


    *。。我只是想寻找一种方法来实现它,而不是像语言构造中的函数。

    我会使用线性插值(你的解决方案3)和常数外推,即所有低于30的映射到1.3,所有超过50的映射到7.3。时间关键的部分可能是找到正确的数组索引

    具体实现取决于采样数组的大小以及输入值的分布方式。例如:

    • 如果数组很小,或者希望在输入范围的低端有很多值,那么线性搜索可能足够快
    • 如果您的数组很大,并且输入在整个范围内均匀分布,则二进制搜索可能会更好
    • 如果您的输入样本是等距的,那么查找只需要一个带floor函数或整数转换的除法,因此这可能是最好的方法
    • 您可以预先计算每个段的斜率,这样就不必每次都计算常数
      (fxb fxa)/(xb xa)*(x1 xa)

    很多“可能”。使用您的用例分析一些实现应该有助于您决定如何准确地实现查找功能。

    x
    数组进行二进制搜索,以找到精确匹配项或两个提供包含输入的间隔的条目。对于精确匹配,结果是与x元素对应的(具有相同索引)fx元素。对于非精确匹配,根据输入位于x0中的位置进行线性插值。。。x1间隔,并将其应用于两个相应的fx元素。除了有两个并行数组外,还可以有一个包含x和fx值的元素数组

    关于如何对数组进行二进制搜索,web上有许多来源,例如

    在没有精确匹配的情况下,很容易调整这些条目以生成正确的条目对。但是你必须小心边界。。。输入值小于
    x
    数组的第一个元素或大于最后一个元素

    也可以考虑插值搜索:


    而不是二进制搜索,因为它需要在下限和上限之间进行线性插值。一旦你只找到了两个x项,并且没有找到精确的匹配,只需将插值应用于相应的fx值。

    google“二进制搜索”+“插值”。你试过Matlab的
    interp1
    ?注意:IMO的等效数学形式是
    =(fxa*xb-fxb*xa+(fxb fxa)*x1/(xb xa)
    fxa+(fxb fxa)/(xb-xa)*(x1-xa)
    (方法#3)在计算上更加稳定。为了使“函数*应该非常快”,代码可以添加两个预先计算的字段:斜率
    (fxb-fxa)/(xb-xa)
    和偏移量
    (fxa*xb-fxb*xa)/(xb-xa)
    ,然后使用
    fx1=slope*x1+offset
    @chux为什么它更稳定?虽然我还没有完全弄清楚是怎么做的,但预计算是有效的。@luismendo I'did。对于一般用途的interp1很好,但是对于特定任务,即使在matlab中实现,自制函数也可以显著更快。获取二进制的最简单方法ry search启动可能只是为了使用实现它的C库函数,
    bsearch
    @JensGustedt Er,不。除了效率极低之外,OP追求速度,当没有精确匹配时,它不会给出任何结果。你似乎没有努力阅读或理解我写的内容:“在没有精确匹配的情况下,很容易调整它们以生成正确的条目对”……显然,使用bsearch无法做到这一点。这里的目标不是“开始二进制搜索”“,这是为了解决OP的问题。我在matlab中编写了一个二进制和插值搜索,并在均匀分布的数组
    x
    上使用均匀分布的查询进行了测试。插值平均为8倍。”