1

我有一个q包含200元素的行向量和另一个行向量 ,dij它是pdist具有当前48216200元素的函数的输出,但我希望能够更高。我想做的操作本质上是:

t=sum(q'*dij,2);

然而,由于它试图分配一个200x48211290数组,它抱怨这将需要 70GB 的内存。因此我这样做:

t = zeros(numel(q),1);
for i=1:numel(q)
    qi = q(i);
    factor = qi*dij;
    t(i)=sum(factor);
end

但是,这需要太多时间。太多时间,我的意思是它需要大约36s,这比pdist函数所需的时间长几个数量级。有没有一种方法可以在不显式分配这么多内存的情况下加快此操作?我在这里假设,如果第一种方法可以分配内存,(作为向量操作)它会更快。

4

2 回答 2

3

只需使用关于加法的乘法分配性质:

t = q'*sum(dij);
于 2021-09-13T20:19:52.550 回答
0

为了测试 Cris 在第一条评论中所说的内容,我创建了 3 个“.m”文件,如下所示:

vec.m:

res=sum(sin(d.*q')./(d.*q'));

forloop.m

for i=1:200
    res(i)=sum(sin(d.*q(i))./(d.*q(i)));
end

和test.m:

clc
clear all
d=rand(4e6,1);
q=rand(200,1);
res=zeros(1,200);

forloop;
vec;
forloop;
vec;
forloop;
vec;

然后我用了matlab run and time profiler,结果很惊喜!:

3 calls to forloop : ~10.5 S
3 call to vec : 15.5 S !!!

此外,当我将数据转换为单一数据时,结果是:

... forloop : 7.5 S
... vec : 8.5 S

我不知道为什么在这些情况下 for-loop 更快,但至于你的问题,你可以通过在循环中生成较少的变量并使用垂直向量来加快速度(我认为)。最后将您的数据转换为单个值:

q=single(rand(200,1)); 
...
于 2021-09-13T22:23:12.490 回答