Как вычесть вектор из каждой строки матрицы?

Возможный дубликат:
Как я могу разделить каждую строку матрицы на фиксированную строку?

Я ищу элегантный способ вычитать один и тот же вектор из каждой строки матрицы. Вот не элегантный способ сделать это.

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); %...
Другие вопросы по тегам