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

时间:2022-12-20 21:32:02

Possible Duplicate:
How can I divide each row of a matrix by a fixed row?

可能的重复:我怎样才能将矩阵的每一行除以一个固定的行?

I'm looking for an elegant way to subtract the same vector from each row of a matrix. Here is a non elegant way of doing it.

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

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

Also, the elegant way can't be slower than this method.

而且,优雅的方法也不能比这种方法慢。

I've tried

我试过了

c = b-repmat(a,size(b,1),1); 

and it seems slower.

它似乎更慢。

EDIT: The winner is this method.

编辑:获胜者是这个方法。

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

EDIT: More methods, and tic toc results:

编辑:更多的方法和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

results

结果

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 个解决方案

#1


6  

Here is my contribution:

这是我的贡献:

c = b - ones(size(b))*diag(a)

c = b - 1 (size(b))*diag(a)

Now speed testing it:

现在速度测试:

tic
for i = 1:10000
    c = zeros(size(b));
    b = rand(7,3);
    c = b - ones(size(b))*diag(a);
end
toc

The result:

结果:

Elapsed time is 0.099979 seconds.

运行时间是0.099979秒。

Not quite as fast, but it is clean.

没有那么快,但是很干净。

#2


1  

There are only three obvious answers, and you gave two of them in your question.

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

The third is by row,

第三个是逐行,

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

but I'd expect that to be slower than your by-column processing for large matrixes since it accesses elements out of memory order.

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

If you turn your by-column processing into a for loop in a *.m file or subfunction, is it still faster than the repmat version?

如果你将你的副列处理变成一个for循环在一个*。m文件或子功能,它比repmat版本还快吗?

One other thing you might test for speed: Try preallocating c.

还有一件事你可能会测试速度:尝试预分配c。

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

#1


6  

Here is my contribution:

这是我的贡献:

c = b - ones(size(b))*diag(a)

c = b - 1 (size(b))*diag(a)

Now speed testing it:

现在速度测试:

tic
for i = 1:10000
    c = zeros(size(b));
    b = rand(7,3);
    c = b - ones(size(b))*diag(a);
end
toc

The result:

结果:

Elapsed time is 0.099979 seconds.

运行时间是0.099979秒。

Not quite as fast, but it is clean.

没有那么快,但是很干净。

#2


1  

There are only three obvious answers, and you gave two of them in your question.

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

The third is by row,

第三个是逐行,

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

but I'd expect that to be slower than your by-column processing for large matrixes since it accesses elements out of memory order.

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

If you turn your by-column processing into a for loop in a *.m file or subfunction, is it still faster than the repmat version?

如果你将你的副列处理变成一个for循环在一个*。m文件或子功能,它比repmat版本还快吗?

One other thing you might test for speed: Try preallocating c.

还有一件事你可能会测试速度:尝试预分配c。

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