3

我想编写一个“语法糖”Octave 或 Matlab 零填充函数,用户向其发送一个 n 维对象和一个 <= n 条目的向量。向量包含对象的新的、相等的或更大的维度,并且对象被零填充以匹配这些维度。任何未指定的尺寸都将单独保留。一种预期用途是,例如,给定 3d 医学图像体积的 5d 块 X,我可以调用

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

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

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

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
4

2 回答 2

4

这是一个应该处理所有小角落情况的解决方案:

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
于 2016-12-22T17:31:13.210 回答
2

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

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
于 2016-12-22T16:11:29.860 回答