【问题标题】:Matlab/Octave: how to write n-dimensional zero padding algorithm without evalMatlab/Octave:如何在没有 eval 的情况下编写 n 维零填充算法
【发布时间】:2017-05-08 07:06:20
【问题描述】:

我想编写一个“语法糖”Octave 或 Matlab 零填充函数,用户向其发送一个 n 维对象和一个

y = simplepad(X, [128 128 128]);

因此将前三个维度填充为 2 的幂以进行小波分析(实际上我使用单独的函数 nextpwr2 来查找这些维度),而保留其他维度。

我已经绞尽脑汁想如何编写这种方法来避免可怕的 eval,但到目前为止还没有找到方法。任何人都可以提出解决方案吗?这或多或少是我所拥有的:

function y = simplepad(x, pad)
szx = size(x);
n_pad = numel(pad);
szy = [pad szx(n_pad+1:end)];
y = zeros(szy);
indices_string = '(';
for n = 1:numel(szx)
    indices_string = [indices_string, '1:', num2str(szx(n))];
    if n < numel(szx)
        indices_string = [indices_string, ','];
    else
        indices_string = [indices_string, ')'];
    end
end
command = ['y',indices_string,'=x;'];
eval(command);
end

【问题讨论】:

    标签: matlab octave n-dimensional


    【解决方案1】:

    据我了解,您只想将一些动态参数传递给函数。 您可以通过将这些参数转换为单元格并通过传递单元格内容调用您的函数来做到这一点。因此,您的函数将如下所示:

    function y = simplepad(x, pad)
        szx = size(x);
        n_pad = numel(pad);
        szy = [pad szx(n_pad+1:end)];
        y = x;
        szyc = num2cell(szy);
        y(szyc{:}) = 0; % warning: assume x array only grows
    end
    

    【讨论】:

    • 是的,最后一行只是将 n-dim 数组的最后一个元素设置为零。
    • 一个小问题:如果维度已经等于pad,您将用零覆盖现有值。
    • 正如您在 cmets 中看到的:% 警告:假设 x 数组只会增长
    • @gnovice 只有当 last 指定维度的大小相等时才有问题,对吧?如果以前的尺寸相等,我认为它根本不会填充它们。
    • @beaker:如果pad 中的所有值都小于或等于size(x) 中的值,这只是一个问题。
    【解决方案2】:

    这是一个可以处理所有小问题的解决方案:

    function A = simplepad(A, pad)
    
      % Add singleton dimensions (i.e. ones) to the ends of the old size of A 
      %   or pad as needed so they can be compared directly to one another:
    
      oldSize = size(A);
      dimChange = numel(pad)-numel(oldSize);
      oldSize = [oldSize ones(1, dimChange)];
      pad = [pad ones(1, -dimChange)];
    
      % If all of the sizes in pad are less than or equal to the sizes in
      %   oldSize, there is no padding done:
    
      if all(pad <= oldSize)
        return
      end
    
      % Use implicit zero expansion to pad:
    
      pad = num2cell(pad);
      A(pad{:}) = 0;
    
    end
    

    还有一些测试用例:

    >> M = magic(3)
    M =
         8     1     6
         3     5     7
         4     9     2
    >> simplepad(M, [1 1])    % No change, since the all values are smaller
    ans =
         8     1     6
         3     5     7
         4     9     2
    >> simplepad(M, [1 4])    % Ignore the 1, pad the rows
    ans =
         8     1     6     0
         3     5     7     0
         4     9     2     0
    >> simplepad(M, [4 4])    % Pad rows and columns
    ans =
         8     1     6     0
         3     5     7     0
         4     9     2     0
         0     0     0     0
    >> simplepad(M, [4 4 2])  % Pad rows and columns and add a third dimension
    ans(:,:,1) =
         8     1     6     0
         3     5     7     0
         4     9     2     0
         0     0     0     0
    ans(:,:,2) =
         0     0     0     0
         0     0     0     0
         0     0     0     0
         0     0     0     0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 2015-12-02
      • 2023-01-10
      • 1970-01-01
      相关资源
      最近更新 更多