TRANSPOSE(.') / RESHAPE too much TIME CONSUMING--> Looking for ALTERNATIVE

8 views (last 30 days)
HI guys,
I wrote a function that uses th sum of a raw and the transpose of a colomn in a triple loop.
As my data is quite large, this line alone consume 904s (I did a run and time) or 75% of the total time.
I am looking for an alternative. Here is the code:
for t = 1:24
for i = 1:1858
for j = 1:1858
if i == j
D(i,j) = 0;
else
C = A(i,:) + permute(B(:,j),[2,1]); % 904 s or 75% of the total (I removed part of the code) <---------
end
end
end
end
I tried the transpose function .' and the permute function. Both gave high running time which is a real problem in my study.
I really don't understand how a sum and a transpose consume so much time.
Please help me :)
  2 Comments
madhan ravi
madhan ravi on 27 Mar 2019
Please provide a simple example and the desired output , you seem to be mixing loop and permute (havn't examined thoroughly).
Adam
Adam on 27 Mar 2019
Can you not permute your entire DistPT array just once before the loops?

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 28 Mar 2019
I fund it really weird that, for a computer, selecting a simple raw from a matrix is that time consuming
It's always a lot slower than accessing columns in a loop, particularly on modern processors.
Elements of a column are stored together in memory, so accessing a single column is just a straight contiguous memory access. With modern processors, it will be even more optimised as the processor will guess that you'll want to access the next column and prefetch the data before you even request it (read up on processor caches to learn more). With a row access, the elements are scattered across memory. That's not cacheable and each element has to be fetched one by one. Repeat that on a lot of rows, and yes, you're wasting time.
  1 Comment
Habib
Habib on 1 Apr 2019
You are so right! Thanks, I didn't know that Matlab has some confusions if you talk raws instead of columns.

Sign in to comment.

More Answers (1)

Jan
Jan on 27 Mar 2019
Edited: Jan on 27 Mar 2019
Is D pre-allocated? This is an important detail if runtime matters.
permute(DistPT(:,j),[2,1]) ?! What about: DistPT(:,j).' ?
nDist = size(DistRoad, 1); % Nicer to do this once
D = zeros(nDist, nDist); % Pre-allocate!!!
E_roadPT = zeros(nDist, timeSteps); % Pre-allocate!!!
for t = 1:timeSteps
for i = 1:nDist
Ai = A(i, :);
for j = 1:nDist
if i ~= j
D(i,j) = min(Ai + DistPT(:,j).');
end
end
end
add = DistFF ./ D;
E_roadPT(:,t) = sum(add, 1) / (size(DistFF,1) - 1);
end
If you provide some input values, e.g. created by rand, we could test the suggested improvements.
[EDITED] You have modified your question. The new code is not as meaningful as the original one was. The pre-allocation problem is still existing. C = A(i,:) + B(:,j).' consumes some time, because it creates a (I guess!) 1858x1858 matrix in each iteration, which needs 28 MB. Doing this 3.4 millions of times must need some time.
Prefer to post a minimal working example, which includes input data (e.g. created by rand) and which creates the wanted output data. The current example is too much simplified to see, what you want to achieve.
Do you have the parallel processing toolbox? Then parfor might be an elegant option.
Do you have a C compiler installed? Then a tiny C function might save some time.
  8 Comments
Habib
Habib on 28 Mar 2019
Edited: Habib on 28 Mar 2019
Actually I tried all this stuff and the problem is stil in selecting this raw in the DistPTpermuted matrix.
@Adam: I can't add both matrices because I need to add only specific raws which are not essencially in the same position.
@Jan: Thanks for the:
centr(t,p) = centr(t,p);
which is clearly useless.
But the:
add2 = Ai + DistPT(:,j).';
Isn't efficient as it does a transpose at each loop, and if I do it at the beginning, I don't need to transpose anymore, juste call the concerned raw (which takes too much time).
I fund it really weird that, for a computer, selecting a simple raw from a matrix is that time consuming, even if it has to do it 24x1800x1800 times (3 loops). I really think there is a solution to that.
Please help me :)
Jan
Jan on 1 Apr 2019
DistPT(:,j).' is efficient, because the input of the transposition is a vector. Then transposing is equivalent to reshaping, which does not modify the contents of the RAM. But of course tranposing the array before the loops is a good idea also, as long as you do not access row-vectors from the marix afterwards.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!