How to sum over indices i+j=k without using a for loop?

14 ビュー (過去 30 日間)
Jackie Taylor
Jackie Taylor 2021 年 6 月 16 日
コメント済み: Jackie Taylor 2021 年 6 月 22 日
I have an matrix β and a vector n. I am trying to compute two sums:
(k is an integer). So I should have answers for and . Is there a way to compute these sums without using for loops or computationally expensive Matlab matrix manipulation functions? The first sum in particular is giving me a headache. Thanks!
  4 件のコメント
Jan
Jan 2021 年 6 月 18 日
編集済み: Jan 2021 年 6 月 18 日
@Jackie Taylor: What is vmax and nold? I try:
vol = 1:delv:kmax; % Instead of vmax
n = rand(p, r); % nold -> n
Jackie Taylor
Jackie Taylor 2021 年 6 月 18 日
Good catch, vmax = kmax. I'm going to try your suggested inner loop edits and get back to you on the results. Thanks for all the help!

サインインしてコメントする。

採用された回答

Jan
Jan 2021 年 6 月 18 日
編集済み: Jan 2021 年 6 月 18 日
Because beta is determined inside the for i and for j loops, we can improve only the inner loops:
r = 501;
kmax = 501;
p = 60;
beta = rand(r, r);
n = rand(p, r);
qin = zeros(p, r);
qout = zeros(p, r);
i = 1;
tic
for rep = 1:100 % Only to get a more accurate time measurement, remove in real code!
for k = 1:kmax
for s = 1:k-1
qin(i,k) = qin(i,k) + beta(s,k-s) * n(i,s) * n(i,k-s);
end
for s = 1:r-k
qout(i,k) = qout(i,k) + beta(s,k) * n(i,s) * n(i,k);
end
end
end
toc
Elapsed time is 0.449715 seconds.
qin = zeros(p, r);
qout = zeros(p, r);
tic
ni = n(i, :);
for rep = 1:100
for k = 1:kmax
a = 0;
for s = 1:k-1
a = a + beta(s, k-s) * ni(s) * ni(k-s);
end
qin(i, k) = qin(i, k) + a;
a = 0;
for s = 1:r-k
a = a + beta(s, k) * ni(s);
end
qout(i, k) = qout(i, k) + a * ni(k);
end
end
toc
Elapsed time is 0.220807 seconds.
Almost 2 times faster with just avoiding some indexing. Because this is a part of the problem only the total speedup will be smaler. My trials to vectorize this are about 10 times slower. In addition the timings measure in the online version differ from a local version. So please check and post, if the modified version is faster at all.
  1 件のコメント
Jackie Taylor
Jackie Taylor 2021 年 6 月 22 日
This works much better than what I had in mind. Thanks!

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2021 年 6 月 18 日
If you have i+j = k, then you start at row k-1, column 1 as the first point (if k >= the number of rows). The next point would be row k-2, column 2. The third point would be row k-3, column 3. And so on.
In terms of linear indices, the first one is (k-1) + rows*(1-1); the second one is (k-2)+rows*(2-1), the third is (k-3)+rows*(3-1) and so on. Those are k-1, k-2+rows, k-3+2*rows, k-4+3*rows and so on. The difference between those is [rows-1], [rows-1], [rows-1], [rows-1] and so on.
Therefore the linear indices are k-1:rows-1:SOME_ENDPOINT . And that can be implemented as a vector without using a loop.
You will need some logic for the case where k is less than the number of rows or columns.

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

製品


リリース

R2017b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by