如何从矩阵的每一行中减去一个向量?

时间:2011-03-17 17:30:22

标签: matlab vector matrix subtraction

  

可能重复:
  How can I divide each row of a matrix by a fixed row?

我正在寻找一种优雅的方法来从矩阵的每一行中减去相同的向量。这是一种非常优雅的方式。

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 个答案:

答案 0 :(得分:6)

这是我的贡献:

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.

不是那么快,但很干净。

答案 1 :(得分:1)

只有三个明显的答案,你在问题中给出了两个答案。

第三个是按行,

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

但我希望它比大型矩阵的逐列处理要慢,因为它会按内存顺序访问元素。

如果您将旁列处理转换为* .m文件或​​子函数中的for循环,它是否仍然比repmat版本更快?

您可以测试速度的另一件事:尝试预先分配c

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