More efficient way than a loop for this particular example

I code but I am never trained for it, so every once in a while I get suspicious of the possibility to do something more efficiently. Bottleneck there is the ConvertColors in-house function I use, but I think there is a better way to do the j loop. Thanks in advance.
EDIT: for some reason the editor won't indent, so see screenshot for better readibility.
referenceAchromaticGrating=zeros(screenHeight_px,spatialFrequency_px,3);
for i=0:spatialFrequency_px-1
luminance = meanLuminance+4*sin(2*pi*(1/spatialFrequency_px)*i);
RGB_array = ConvertColors('MWLRGB',[0,0,luminance],colorInfo);
for j=1:3
referenceAchromaticGrating(:,i+1,j)=RGB_array(j);
end
end

 Risposta accettata

DGM
DGM il 15 Feb 2022
Modificato: DGM il 15 Feb 2022
What size is RGB_array? I'm guessing it's a 1x3 tuple, and the LHS of the output assignment is a Mx1x3 region in the output array.
I doubt that trying to expand RGB_array to allow direct output assignment without the per-channel loop would really save more time.
However, it might be better to have the outer loop collect a Nx3 matrix of all values of RGB_array. At that point, once you're outside the loop, this array can be reshaped into the output.
RGB_array = zeros(spatialFrequency_px,3);
for i = 0:spatialFrequency_px-1
luminance = meanLuminance+4*sin(2*pi*(1/spatialFrequency_px)*i);
RGB_array(i+1,:) = ConvertColors('MWLRGB',[0,0,luminance],colorInfo);
end
referenceAchromaticGrating = repmat(permute(RGB_array,[3 1 2]),screenHeight_px,1);
This also avoids the need to preallocate the output array
I don't know if this is any faster than what you had. That's something you'll need to test.
EDIT:
I timed it (with ConvertColors() replaced with rand(1,3)). The above method is approximately twice as fast for a 1000x1000 output. It's slightly faster yet for smaller outputs. Including the functions that I omitted will only reduce the effective difference between the two.

4 Commenti

Both of your initial assumptions are correct. I ran the code, it works just as well, but to my surprise (as yours looks tidier and more proper to me) it ran slightly slower. However, I learned two functions that I have never used before (and certainly not in conjunction with each other).
You were absolutely correct when rand is used (at least within my system).
Elapsed time is 0.010750 seconds. (yours)
Elapsed time is 0.012222 seconds. (mine)
So I tried with the ConvertColors function multiple times. My code fluctuated wildly (anywhere from 0.4 to 0.7 seconds) and yours remained consistent at around 0.5. This is so interesting.
Take the results from tic/toc with a grain of salt -- the profiler even more.
This is what I used, though even version and environment differences can sway things.
spatialFrequency_px = 1000;
screenHeight_px = 1000;
% original method
a = timeit(@() testA(spatialFrequency_px,screenHeight_px))
a = 0.0050
% collect color table, permute, expand (faster)
b = timeit(@() testB(spatialFrequency_px,screenHeight_px))
b = 0.0022
% modified original with direct output assignment (slower)
c = timeit(@() testC(spatialFrequency_px,screenHeight_px))
c = 0.0150
% time ratios
[a/b a/c]
ans = 1×2
2.2055 0.3299
function testA(spatialFrequency_px,screenHeight_px)
referenceAchromaticGrating=zeros(screenHeight_px,spatialFrequency_px,3);
for i=0:spatialFrequency_px-1
RGB_array = rand(1,3);
for j=1:3
referenceAchromaticGrating(:,i+1,j)=RGB_array(j);
end
end
end
function testB(spatialFrequency_px,screenHeight_px)
RGB_array = zeros(spatialFrequency_px,3);
for i = 0:spatialFrequency_px-1
RGB_array(i+1,:) = rand(1,3);
end
referenceAchromaticGrating = repmat(permute(RGB_array,[3 1 2]),screenHeight_px,1);
end
function testC(spatialFrequency_px,screenHeight_px)
referenceAchromaticGrating=zeros(screenHeight_px,spatialFrequency_px,3);
for i=0:spatialFrequency_px-1
RGB_array = rand(1,3);
for j=1:3
referenceAchromaticGrating(:,i+1,:)= repmat(permute(RGB_array,[3 1 2]),[screenHeight_px 1]);
end
end
end
If ConvertColors() can be vectorized, there maybe more time to shave off.
Thank you, this is marvelous!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Loops and Conditional Statements in Centro assistenza e File Exchange

Prodotti

Release

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by