2016-12-22 47 views
3

我想寫一個「語法糖」Octave或Matlab的零填充函數,用戶向其發送一個n維對象和向量< = n個條目。矢量包含對象的新的,相等或更大的尺寸,並且該對象被零填充以匹配這些尺寸。任何未指定的尺寸都保留。一個預期的用途是,例如給定的3D醫學圖像體積的5D塊X,我可以調用Matlab/Octave:如何編寫不含eval的n維零填充算法

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

,因此墊的前三個維度的兩個用於小波分析的功率(實際上我使用一個單獨功能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 

回答

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 
+0

很不錯的。我不得不重讀這幾次。 :) – beaker

+0

是的,最後一行只是將n-dim數組的最後一個元素設置爲零。 –

+2

一個小問題:如果尺寸已經等於'pad',那麼將用零覆蓋現有值。 – gnovice

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