Как вычесть вектор из каждой строки матрицы?
Возможный дубликат:
Как я могу разделить каждую строку матрицы на фиксированную строку?
Я ищу элегантный способ вычитать один и тот же вектор из каждой строки матрицы. Вот не элегантный способ сделать это.
a = [1 2 3];
b = rand(7,3);
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
Кроме того, элегантный способ не может быть медленнее, чем этот метод.
я пробовал
c = b-repmat(a,size(b,1),1);
и кажется медленнее.
РЕДАКТИРОВАТЬ: победителем является этот метод.
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
РЕДАКТИРОВАТЬ: больше методов, и результаты Tic Toc:
n = 1e6;
m = 3;
iter = 100;
a = rand(1,m);
b = rand(n,m);
tic
c = zeros(size(b));
for i = 1:iter
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
end
toc
tic
c = zeros(size(b));
for i = 1:iter
c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);
end
toc
tic
c = zeros(size(b));
for i = 1:iter
for j = 1:3
c(:,j) = b(:,j) - a(j);
end
end
toc
tic
for i = 1:iter
c = b-repmat(a,size(b,1),1);
end
toc
tic
for i = 1:iter
c = bsxfun(@minus,b,a);
end
toc
tic
c = zeros(size(b));
for i = 1:iter
for j = 1:size(b,1)
c(j,:) = b(j,:) - a;
end
end
toc
Результаты
Elapsed time is 0.622730 seconds.
Elapsed time is 0.627321 seconds.
Elapsed time is 0.713384 seconds.
Elapsed time is 2.621642 seconds.
Elapsed time is 1.323490 seconds.
Elapsed time is 17.269901 seconds.
2 ответа
Вот мой вклад:
c = b - ones(size(b))*diag(a)
Теперь скоростное тестирование это:
tic
for i = 1:10000
c = zeros(size(b));
b = rand(7,3);
c = b - ones(size(b))*diag(a);
end
toc
Результат:
Elapsed time is 0.099979 seconds.
Не так быстро, но чисто.
Есть только три очевидных ответа, и вы дали два из них в своем вопросе.
Третий по ряду,
c(1,:) = b(1,:) - a; %...
но я ожидаю, что это будет медленнее, чем ваша обработка по столбцам для больших матриц, поскольку она обращается к элементам вне порядка памяти.
Если вы превратите обработку по столбцам в for
цикл в файле или подфункции *.m, это все еще быстрее, чем repmat
версия?
Еще одна вещь, которую вы можете проверить на скорость: попробуйте предварительно выделить c
,
c = zeros(size(b));
c(:,1) = b(:,1) - a(1); %...