How to improve speed of calculating trace in a script?
Mostra commenti meno recenti
Hi all,
In my project I have to calculate the trace of some matrix products, I have the following script to demonstrate the purpose:
clear; clc;
% number of total tests.
nTest = 500;
% part 1. generate nTest*2 random matrices.
nd = 1000;
nt = 100;
dis = cell(nTest, 2);
dis = cellfun(@(v) rand(nd, nt), dis, 'un', 0);
% part 2. perform truncated-SVD on each matrix,
% only leave nRem singular vectors and values.
nRem = 50;
disSVD = cell(nTest, 2);
for isvd = 1:nTest
for jsvd = 1:2
[u, s, v] = svd(dis{isvd, jsvd}, 0);
disSVD{isvd, jsvd} = {u(:, 1:nRem), s(1:nRem, 1:nRem), v(:, 1:nRem)};
end
end
% part 3. for each SVD result, perform trace to obtain disTrans. disTrans is
% non-symmetric, thus jtr needs to start from 1.
disTrans = zeros(nTest);
for itr = 1:nTest
u1 = disSVD{itr, 1};
for jtr = 1:nTest
u2 = disSVD{jtr, 2};
disTrans(itr, jtr) = ...
trace(u1{3} * u1{2}' * u1{1}' * u2{1} * u2{2} * u2{3}');
end
end
I ran profile to find out which part is the slowest, it turns out it's calculating the trace in part 3 due to the large number. Unfortunately in my project the number of calculating trace is also very large. So any idea of how to improve the speed of calculating the trace? The profile is shown here:

Many thanks!
8 Commenti
Geoff Hayes
il 3 Apr 2018
Xiaohan - in your call to trace
trace(u1{3} * u1{2}' * u1{1}' * u2{1} * u2{2} * u2{3}');
note how for every iteration of the inner loop, you are always repeating the product
u1{3} * u1{2}' * u1{1}'
I suppose you could put that in the outer loop to see if that improves your processing time.
disTrans = zeros(nTest);
for itr = 1:nTest
u1 = disSVD{itr, 1};
z = u1{3} * u1{2}' * u1{1}';
for jtr = 1:nTest
u2 = disSVD{jtr, 2};
disTrans(itr, jtr) = ...
trace(z * u2{1} * u2{2} * u2{3}');
end
end
Xiaohan Du
il 3 Apr 2018
Geoff Hayes
il 3 Apr 2018
Hi Xiaohan - my understanding is that trace is called 250000 times and spends a total of 2.533 seconds for all of the 250000 calls.
The total time spent in testuiTujSortImprove is 64.596 seconds of which 2.5333 is spent in trace. The self time is the time spent in that function. That is why when we made the above change to perform that multiplication in the outer loop, we improved the self time of your main function.
Xiaohan Du
il 3 Apr 2018
Modificato: Xiaohan Du
il 3 Apr 2018
Geoff Hayes
il 3 Apr 2018
well the 61.062 seconds should be the time spent in the testuiTujSortImprove function itself and does not include the time spent in any function (like trace) that it calls.
64.596 - 61.062 ~= 3.53 should be the time spent in all of the other functions.
Xiaohan Du
il 3 Apr 2018
Steven Lord
il 3 Apr 2018
Note that built-in functions like svd, cellfun, rand, etc. don't show up in your Profiler report but they do take time. If you open the entry for testuiTujSortImprove I believe you'll see a line in the Children table where the time spent in built-in functions will be reported, and given how many times you called svd in particular I think that will account for the "missing" time.
Xiaohan Du
il 4 Apr 2018
Risposta accettata
Più risposte (0)
Categorie
Scopri di più su Whos in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


