26

可能重复:
如何将矩阵的每一行除以固定行?

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

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.
4

2 回答 2

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.

没那么快,但很干净。

于 2011-03-17T19:52:30.400 回答
1

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

第三个是按行,

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

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

如果您将逐列处理变成for*.m 文件或子函数中的循环,它是否仍然比repmat版本快?

您可能会测试速度的另一件事:尝试预分配c.

c = zeros(size(b));
c(:,1) = b(:,1) - a(1); %...
于 2011-03-17T17:43:26.467 回答