Matrix “Zigzag” Reordering

后端 未结 6 1555
名媛妹妹
名媛妹妹 2020-11-30 04:35

I have an NxM matrix in MATLAB that I would like to reorder in similar fashion to the way JPEG reorders its subblock pixels:

6条回答
  •  心在旅途
    2020-11-30 05:25

    This approach is pretty fast:

    X = randn(500,2000); %// example input matrix
    [r, c] = size(X);
    M = bsxfun(@plus, (1:r).', 0:c-1);
    M = M + bsxfun(@times, (1:r).'/(r+c), (-1).^M);
    [~, ind] = sort(M(:));
    y = X(ind).'; %'// output row vector
    

    Benchmarking

    The following code compares running time with that of Amro's excellent answer, using timeit. It tests different combinations of matrix size (number of entries) and matrix shape (number of rows to number of columns ratio).

    %// Amro's approach
    function y = zigzag_Amro(M)
    ind = reshape(1:numel(M), size(M));
    ind = fliplr( spdiags( fliplr(ind) ) );     
    ind(:,1:2:end) = flipud( ind(:,1:2:end) );
    ind(ind==0) = [];
    y = M(ind);
    
    %// Luis' approach
    function y = zigzag_Luis(X)
    [r, c] = size(X);
    M = bsxfun(@plus, (1:r).', 0:c-1);
    M = M + bsxfun(@times, (1:r).'/(r+c), (-1).^M);
    [~, ind] = sort(M(:));
    y = X(ind).';
    
    %// Benchmarking code:
    S = [10 30 100 300 1000 3000]; %// reference to generate matrix size
    f = [1 1]; %// number of cols is S*f(1); number of rows is S*f(2)
    %// f = [0.5 2]; %// plotted with '--'
    %// f = [2 0.5]; %// plotted with ':'
    t_Amro = NaN(size(S));
    t_Luis = NaN(size(S));
    for n = 1:numel(S)
        X = rand(f(1)*S(n), f(2)*S(n));
        f_Amro = @() zigzag_Amro(X);
        f_Luis = @() zigzag_Luis(X);
        t_Amro(n) = timeit(f_Amro);
        t_Luis(n) = timeit(f_Luis);
    end
    loglog(S.^2*prod(f), t_Amro, '.b-');
    hold on
    loglog(S.^2*prod(f), t_Luis, '.r-');
    xlabel('number of matrix entries')
    ylabel('time')
    

    The figure below has been obtained with Matlab R2014b on Windows 7 64 bits. Results in R2010b are very similar. It is seen that the new approach reduces running time by a factor between 2.5 (for small matrices) and 1.4 (for large matrices). Results are seen to be almost insensitive to matrix shape, given a total number of entries.

    enter image description here

提交回复
热议问题