Matlab代码优化和消除循环

发布于 2024-12-01 04:45:24 字数 445 浏览 0 评论 0原文

我无法自己删除这个循环,如果有人可以帮助我优化这段代码 - 欢迎。

M = length(w);
expt = exp(-t .* (phis * w'));
G = zeros(M, M);
for i = 1 : M
    for j = 1 : M
        last = 2 * reg_coef * eye(M);
        G(i,j) = last(i, j) + mean(expt .* t .^2 .* phis(:,i) .* phis(:,j) ./ (1 + expt) .^ 2);
    end
end
  • w - 尺寸为 (1xM)
  • phis - 尺寸为 (NxM)
  • t - 尺寸为 (Nx1)

I can't remove this loops by myself, if anybody can help me with optimization this piece of code - welcome.

M = length(w);
expt = exp(-t .* (phis * w'));
G = zeros(M, M);
for i = 1 : M
    for j = 1 : M
        last = 2 * reg_coef * eye(M);
        G(i,j) = last(i, j) + mean(expt .* t .^2 .* phis(:,i) .* phis(:,j) ./ (1 + expt) .^ 2);
    end
end
  • w - size is (1xM)
  • phis - size is (NxM)
  • t - size is (Nx1)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清风夜微凉 2024-12-08 04:45:25

通过编写更清晰的代码,您可以做得更好 - 确保正确分配,确保从循环中删除重复计算等:

编辑:您还可以看到生成的矩阵 G 是对称的,因此您通过仅计算上三角形并随后作为转置填充下三角形,即可立即获得 2x 加速。

至少在我的 MATLAB 中,通过使用临时数组对 mean() 调用进行矢量化,可以实现另一个大幅加速。

N = 100;
M = 100;

w = rand(1,M);
t = rand(N,1);
phis = rand(N,M);
reg_coeff = rand(1,1);

expt = exp(-t .* (phis * w'));

%% Initial version
tic
for i = 1 : M
   for j = 1 : M
      last = 2 * reg_coeff * eye(M,M);
      G1(i,j) = last(i,j) + mean(expt .* t .^ 2 .* phis(:,i) .* phis(:,j) ./ (1 + expt) .^ 2);
   end
end
t1 = toc;

%% Faster version
tic
coeff = expt .* t .^ 2 ./ (1 + expt) .^ 2;
G2 = zeros(M,M);
TT = zeros(M,M);
for i = 1 : M
   for j = i : M % only form upper triangle
      TT(:,j) = coeff .* phis(:,i) .* phis(:,j);
   end
   G2(i,i:M) = mean(TT(:,i:M),1); % vectorise call to mean()
end
G2 = 2 * reg_coeff * eye(M,M) + G2 + triu(G2,+1)';
t2 = toc;

%% Compare versions
speed = t1/t2
error = max(max(abs(G2 - G1)))

对于此 100x100 情况,我的计算机上的加速约为 41.0

希望这有帮助。

You can do alot better by just writing cleaner code - ensure that you allocate properly, ensure that you remove duplicate calculations from loops etc:

EDIT: You can also see that the resulting matrix G is symmetric, so you get an immediate 2x speed-up by only calculating the upper triangle and filling in the lower triangle afterwards as a transpose.

At least with my MATLAB another big speed-up is achieved by vectorising the call to mean() through the use of a temporary array.

N = 100;
M = 100;

w = rand(1,M);
t = rand(N,1);
phis = rand(N,M);
reg_coeff = rand(1,1);

expt = exp(-t .* (phis * w'));

%% Initial version
tic
for i = 1 : M
   for j = 1 : M
      last = 2 * reg_coeff * eye(M,M);
      G1(i,j) = last(i,j) + mean(expt .* t .^ 2 .* phis(:,i) .* phis(:,j) ./ (1 + expt) .^ 2);
   end
end
t1 = toc;

%% Faster version
tic
coeff = expt .* t .^ 2 ./ (1 + expt) .^ 2;
G2 = zeros(M,M);
TT = zeros(M,M);
for i = 1 : M
   for j = i : M % only form upper triangle
      TT(:,j) = coeff .* phis(:,i) .* phis(:,j);
   end
   G2(i,i:M) = mean(TT(:,i:M),1); % vectorise call to mean()
end
G2 = 2 * reg_coeff * eye(M,M) + G2 + triu(G2,+1)';
t2 = toc;

%% Compare versions
speed = t1/t2
error = max(max(abs(G2 - G1)))

For this 100x100 case the speed-up was around 41.0 on my machine.

Hope this helps.

心碎无痕… 2024-12-08 04:45:25

您至少可以从循环中取出很多术语:

last = 2 * reg_coef * eye(M);
A = expt .* t .^2;
B = (1 + expt) .^ 2;

for i = 1 : M
    X = A .* phis(:,i) ./ B;
    for j = 1 : M
        G(i,j) = mean(X .* phis(:,j));
    end
end

G = G + last;

You can, at least, take a lot of terms out of the loops:

last = 2 * reg_coef * eye(M);
A = expt .* t .^2;
B = (1 + expt) .^ 2;

for i = 1 : M
    X = A .* phis(:,i) ./ B;
    for j = 1 : M
        G(i,j) = mean(X .* phis(:,j));
    end
end

G = G + last;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文