Оптимизация смещения столбцов больших матриц (Circshift и др.) - PullRequest
0 голосов
/ 24 сентября 2019

В настоящее время я ищу наиболее эффективный способ сдвига и перестановки больших матриц.По сути, у меня есть данные с некоторым параболическим сдвигом, которые необходимо скорректировать, чтобы сдвинуть «сигнал» к линейному событию.

В настоящее время я пробовал следующие решения и пытался синхронизировать их.Есть ли другой метод, который может оказаться более эффективным?



DATA = ones(100000,501);
DATA(10000,251) = 100;
for i=1:250
    DATA(10000+i^2-1000:10000+i^2+1000,251-i) = 100;
    DATA(10000+i^2-1000:10000+i^2+1000,251+i) = 100;
end
k = abs(-250:1:250).^2;
d = size(DATA,1);
figure(99)
imagesc(DATA)


t_INDEX = timeit(@()fun_INDEX(DATA,k))

t_SNIPPET = timeit(@()fun_SNIPPET(DATA,k))

t_CIRCSHIFT = timeit(@()fun_CIRCSHIFT(DATA,k))

t_INDEX_clean = timeit(@()fun_INDEX_clean(DATA,k))

t_SPARSE = timeit(@()fun_SPARSE(DATA,k))

t_BSXFUN = timeit(@()fun_BSXFUN(DATA,k))


function fun_INDEX(DATA,k)
    DATA_1 = zeros(size(DATA));
    for i=1:size(DATA,2)
       DATA_1(:,i) = DATA([k(i)+1:end 1:k(i)],i);
    end
    figure(1)
    imagesc(DATA_1)
end

function fun_SNIPPET(DATA,k)
    kmax = max(k);
    DATA_2 = zeros(size(DATA,1)-kmax,size(DATA,2));
    for i=1:size(DATA,2)
       DATA_2(:,i) = DATA(k(i)+1:end-kmax+k(i),i);
    end
    figure(2)
    imagesc(DATA_2)
end

function fun_CIRCSHIFT(DATA,k)
    DATA_3 = zeros(size(DATA));
    for i=1:size(DATA,2)
        DATA_3(:,i) = circshift(DATA(:,i),-k(i),1);
    end
    figure(3)
    imagesc(DATA_3)
end

function fun_INDEX_clean(DATA,k)
    [m, n] = size(DATA);
    k = size(DATA,1)-k;
    DATA_4 = zeros(m, n);
    for i = (1 : n)
        DATA_4(:, i) = [DATA((m - k(i) + 1 : m), i); DATA((1 : m - k(i) ), i)];
    end
    figure(4)
    imagesc(DATA_4)
end

function fun_SPARSE(DATA,k)
    [m,n] = size(DATA);
    k = -k;
    S = full(sparse(mod(k,m)+1,1:n,1,m,n));
    DATA_5 = ifft(fft(DATA).*fft(S),'symmetric');
    figure(5)
    imagesc(DATA_5)
end


function fun_BSXFUN(DATA,k)
    DATA = DATA';
    k = -k;
    [m,n] = size(DATA);
    idx0 = mod(bsxfun(@plus,n-k(:),1:n)-1,n);
    DATA_6 = DATA(bsxfun(@plus,(idx0*m),(1:m)'));
    figure(6)
    imagesc(DATA_6)
end

Есть ли способ уменьшить время вычислений для такого рода проблем?

Заранее спасибо за любые советы!

1 Ответ

0 голосов
/ 25 сентября 2019

Одним из вариантов будет использование функций графического процессора MATLAB, если на вашей рабочей станции установлен графический процессор.В зависимости от того, помещаются ли все данные на графический процессор одновременно, он начинает опережать циклическое смещение ЦП при размере матрицы 1000 X 1000.

Реализация требует, чтобы вы только копировали свои данные в графический процессор с помощью одного оператора,а затем включите circshift для вновь созданного массива you.

Небольшое обсуждение его производительности можно найти здесь: https://www.mathworks.com/matlabcentral/answers/274619-circshift-slower-on-gpu.В частности, в последнем посте описывается гораздо более быстрая реализация графического процессора, если вам на самом деле не требуется циклическое смещение, но вы можете избежать нуля с одной стороны, что может иметь значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...