简体   繁体   中英

Finding faster way to compute a matrix using MATLAB

I am looking for a faster way to compute a matrix using MATLAB:

Given an m-by-n matrix A , I would like to return a matrix B with the additions of all i th and the j th rows such that j >= i . Eg, Let A=[1 2 3 4; 2 3 4 5; 3 4 5 6] A=[1 2 3 4; 2 3 4 5; 3 4 5 6] A=[1 2 3 4; 2 3 4 5; 3 4 5 6] , then B can be computed as

idx=1;
nbrows=size(A,1);
B=zeros(nbrows*(nbrows+1)/2,size(A,2)); % the size of B can be determined
for i = 1:nbrows
  for j = i:nbrows
    B(idx,:) = A(i,:) + A(j,:);
    idx = idx + 1;
  end
end

Now, I have a very large A , and I would like to know how to compute the matrix B in a more efficient way.

How can this computation be sped-up?

Instead of iterating over rows you can precompute indexes of rows and iterate over columns:

nbcols = size(A, 2);

[r, c] = find(tril(true(nbrows)));

rc = [r c];

for i = 1:nbcols
    B(:, i) = sum(reshape(A(rc, i), [], 2), 2);
end

Equivalent possibly less efficient solution:

for i = 1:nbcols
    B(:, i) = A(r, i) + A(c, i);
end

As A is very large the completely vectorized solution:

B = A(r,:) + A(c,:);

shouldn't be more efficient than the loop version.

Based on the suggestion of @rahnema1 here is a test result about three possible ways. Let us generate matrix A as A=rand(1e4,20);

Method 1: using indexes and vectorization

tic
nbrows = size(A,1);
[r, c] = find(tril(true(nbrows)));
B = A(r,:) + A(c,:);
toc

Terminate in 12.8 seconds.

Method 2: using indexes and loops

tic
nbrows = size(A,1);
nbcols = size(A, 2);
[r, c] = find(tril(true(nbrows)));
rc = [r c];
B=zeros(nbrows*(nbrows+1)/2,size(A,2)); 
for i = 1:nbcols
    B(:, i) = sum(reshape(A(rc, i), [], 2), 2);
end
toc

Terminate in 34.8 seconds.

Method 3: using loops only

tic
idx=1;
nbrows=size(A,1);
B=zeros(nbrows*(nbrows+1)/2,size(A,2)); 
for i = 1:nbrows
  for j = i:nbrows
    B(idx,:) = A(i,:) + A(j,:);
    idx = idx + 1;
  end
end
toc

Terminate in 85.1 seconds.

As a conclusion, Method 1 (using indexes and vectorization) is the fastest one. Thanks again for the nice answer! If anyone finds better way than method 1, I will be very happy to see that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM