Усредняющая матрица Матлаба - PullRequest
0 голосов
/ 06 августа 2011

В программах Matlab, которые я использую, мне часто приходится усреднять в матрице (интерполяция). Самый простой способ - добавить матрицу и сдвинутую (avg). Однако вы можете сделать ту же операцию, используя матричное умножение (avg2). Я заметил значительное увеличение скорости в случае использования умножения матриц в случае больших матриц.

Может ли кто-нибудь объяснить, почему Matlab способен обрабатывать это умножение быстрее, чем добавление той же матрицы? Также, каковы возможные недостатки использования avg2 () по отношению к avg ()?

Разница во времени выполнения составляла ~ 6 для этого случая (n = 500).

function [] = speed()
%Speed test for averaging a matrix
n = 500;
A = rand(n,n);
tic
for i=1:100
    avg(A);
end
toc

tic
for i=1:100
    avg2(A);
end
toc

end

function B = avg(A,k)
if nargin<2, k = 1; end
if size(A,1)==1, A = A'; end
if k<2, B = (A(2:end,:)+A(1:end-1,:))/2; else B = avg(A,k-1); end
if size(A,2)==1, B = B'; end
end

function B = avg2(A,k)
if nargin<2, k = 1; end
if size(A,1)==1, A = A'; end
if k<2,
   m = size(A,1);
   e = ones(m,1);
   S = spdiags(e*[1 1],-1:0,m,m-1)'/2;
   B = S*A; else B = avg2(A,k-1); end
if size(A,2)==1, B = B'; end
end

1 Ответ

3 голосов
/ 06 августа 2011

Боюсь, я не могу дать вам ответ на внутреннюю работу функций, которые вы используете. Однако, поскольку они кажутся слишком сложными, я чувствовал, что должен рассказать вам о более простом (и немного более быстром) способе усреднения.

Вместо этого вы можете использовать conv2 с ядром [0.5; 0.5]. Я расширил ваш код ниже:

function [A, T1, T2 T3] = speed()
%Speed test for averaging a matrix
n = 900;
A = rand(n,n);
tic
for i=1:100
    T1 = avg(A);
end
toc

tic
for i=1:100
 T2 = avg2(A);
end
toc

tic
for i=1:100
   T3 = conv2(A,[1;1]/2,'valid'); 
end
toc

if sum(sum(abs(T3-T2))) > 0
    warning('Method 3 not equal the other methods')
end
end

function B = avg(A,k)
if nargin<2, k = 1; end
if size(A,1)==1, A = A'; end
if k<2, B = (A(2:end,:)+A(1:end-1,:))/2; else B = avg(A,k-1); end
if size(A,2)==1, B = B'; end
end

function B = avg2(A,k)
if nargin<2, k = 1; end
if size(A,1)==1, A = A'; end
if k<2,
   m = size(A,1);
   e = ones(m,1);
   S = spdiags(e*[1 1],-1:0,m,m-1)'/2;
   B = S*A; else B = avg2(A,k-1); end
if size(A,2)==1, B = B'; end
end

Результаты:

Истекшее время составляет 10.201399 секунд.

Истекшее время составляет 1,088003 секунды.

Истекшее время составляет 1,040471 секунды.

Извиняюсь, если вы уже знали это.

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