代码之家  ›  专栏  ›  技术社区  ›  pschulz

多维数据存储和插值

  •  3
  • pschulz  · 技术社区  · 7 年前

    我有一个带有一个变量的函数(也就是说,我实际上有具有这个特征的数据) x 和几个参数 a , b c 所以 y = f(x, a, b, c) . 现在,我想在参数族内插值(例如,对于

    我目前正在用一个参数(这里, y 是数据矩阵)

    % generate variable and data
    x = linspace(0, 1, 100);
    a = [0, 1]; % parameter
    for i = 1:length(a)
        y(:, i) = x.^2 + a(i);
    end
    % interpolate:
    yi = interp1(a, y.', 0.5);
    

    这很好,但如何将其扩展到更多维度?

    我当前的数据格式如下:我的数据矩阵的每一列代表一组特定的参数,例如:

    0 0 0 0
    1 1 1 1
    2 2 2 2
    3 3 3 3
    

    其中第一列表示 a = 0, b = 0 ,第二个 a = 1, b = 0 ,第三个 a = 0, b = 1 最后一个 a = 1, b = 1 (值只是为了澄清,这不是故意的二进制。此外,数据列明显不同)。

    这种数据格式只是我的数据获取方案的结果,但我很高兴将其更改为更有用的内容。只要有用。

    2 回复  |  直到 7 年前
        1
  •  1
  •   zlon    7 年前

    对我来说效果很好:

    % generate variable and data
    x = linspace(0, 1, 100);
    a = [0, 1, 2]; % parameter
    b = [3, 4, 5]; % parameter
    c = [6, 7, 8]; % parameter
    
    % Create grid
    [X,A,B,C]=ndgrid(x,a,b,c);
    
    % define function
    foo = @(x,p1,p2,p3) p1.*x.^2 + p2.*x + p3;
    
    % evaluate function
    Y = foo(X,A,B,C);
    
    % interpolate:
    yi = interpn(X,A,B,C,Y,x,1,4,6);
    
        2
  •  0
  •   pschulz    7 年前

    @zlon的回答对插值部分很有效,这里我想展示如何将数据从我提供的格式转换为插值所需的格式。

    二维矩阵必须转换为N维矩阵。由于列不一定按顺序排列,我们需要找到正确的列。这就是我所做的:

    首先,我们需要知道每列的参数集:

    a = [ 2, 2, 1, 0, 0, 1 ];
    b = [ 1, 0, 0, 1, 0, 1 ];
    

    这些向量的长度与数据矩阵中的列数匹配。例如,第一列现在包含 a = 2 b = 1 .

    现在我们可以生成新表:

    A = -Inf;
    i = 1;
    while true
        A = min(a(a > A)); % find next a
        if isempty(A)
            break
        end
        idxa = find(a == A); % store possible indices
        B = -Inf;
        j = 1;
        while true
            B = min(b(b > B))); % find next b
            if isempty(B)
                break
            end
            idxb = find(b == B); % store possible indices
            % combine both indices
            idx = intersect(idxa, idxb);
            % save column in new data table
            data(:, i, j) = olddata(:, idx);
            % advance
            j = j + 1;
        end
        i = i + 1;
    end