Подтвердить что ты не робот

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

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

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

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); 

и кажется медленнее.

EDIT: Победителем является этот метод.

c(:,1) = b(:,1) - a(1);
c(:,2) = b(:,2) - a(2);
c(:,3) = b(:,3) - a(3);

EDIT: дополнительные методы и результаты 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.
4b9b3361

Ответ 1

Вот мой вклад:

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.

Не так быстро, но он чист.

Ответ 2

Есть только три очевидных ответа, и вы дали два из них в своем вопросе.

Третий по строкам,

c(1,:) = b(1,:) - a; %...

но я ожидаю, что это будет медленнее, чем обработка по столбцам для больших матриц, поскольку он обращается к элементам из порядка памяти.

Если вы перевернете обработку по столбцам в цикл for в файле *.m или подфункции *, это все еще быстрее, чем версия repmat?

Еще одна вещь, которую вы могли бы проверить на скорость: попробуйте перераспределить c.

c = zeros(size(b));
c(:,1) = b(:,1) - a(1); %...