Suggestions to improve script performance?

This is the result of my script, graphically :
It's not a DaVinci but it's 'working'. I tried to use what I thought was Matlab "good" techniques but I'm sure I'm light years behind what good programmers would do... I suspect there are lot's of opportunities for improvements in my code and I would be grateful if you could point out the way. Just a few tips, I'm sure, will go a long way towards getting the improvements I'm looking for. It's not the end of the world, as it is, but you'll see, when you try out the code, that each 'presses' on the Slider takes a long time to execute :
clc
global Axe_a_b;
fig=figure('Name','Roger Breton sRGB CIE ab diagram');
Test = fig.Position;
fig.Position = [1600 500 700 700];
ax = axes(fig);
axis([-128 128 -128 128]);
xticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
yticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
hold on;
CIE_a = 128;
CIE_b = 65; % 128 / 65, Steps of 4
% Algorithm :
% Each call to the function calculates a new colormap
% using a lower b* value
% Keeping L* range constant, between each function call :
% Slice L* = 50
Axe_L = transpose(linspace(50, 50, 65));
% Create one Column vector of 65 constant a* values,
% to fill the diagram, columns by columns,
% from Left (a* = -128) to right (a* = 128)
Axe_a_b = transpose(linspace(-128, 128, 65));
% MarkerSize = 100
for row = 1:65
Col = linspace(CIE_a, CIE_a, 65)';
RowX=[Axe_a_b, Col];
colorListAB = CalculateColorList(CIE_a, CIE_b, Axe_L)
scatter(RowX(:,1),RowX(:,2),100, colorListAB, 'filled', 's');
CIE_a = CIE_a - 4;
end
uicontrol('Style', 'Slider', 'Position',[655 500 20 150], 'Value', 0.5, 'Callback', {@sliderCB});
global txt_ctrl;
txt_ctrl = uicontrol('Style', 'text', 'Position',[640 450 50 50], 'String', ['50']);
set(txt_ctrl, 'FontSize', 20);
function [colorListAB] = CalculateColorList(CIE_a,CIE_b, Axe_L)
% CIE_a = Row
% CIE_b = Col
global Axe_a_b;
% Create one Column vector of 65 constant a* values
% 1st call = a* 128
% 2nd call = a* 124
% 3rd call = a* 120 ...
Axe_L_ROW = transpose(linspace(CIE_a, CIE_a, CIE_b));
Lab_Axe_AB = [Axe_L, Axe_a_b, Axe_L_ROW];
RGB_Axe_AB = lab2rgb(Lab_Axe_AB)
[row,col] = size(RGB_Axe_AB);
% Process Green/Magenta axis first
for ROW = 1:row
if RGB_Axe_AB(ROW,1) < 0
RGB_Axe_AB(ROW,1) = 0;
% Show white color for out of gamut colors
RGB_Axe_AB(ROW,1) = 0.5;
RGB_Axe_AB(ROW,2) = 0.5;
RGB_Axe_AB(ROW,3) = 0.5;
end
if RGB_Axe_AB(ROW,1) > 1
RGB_Axe_AB(ROW,1) = 1;
% Show white color for out of gamut colors
RGB_Axe_AB(ROW,1) = 0.5;
RGB_Axe_AB(ROW,2) = 0.5;
RGB_Axe_AB(ROW,3) = 0.5;
end
if RGB_Axe_AB(ROW,2) < 0
RGB_Axe_AB(ROW,2) = 0;
% Show white color for out of gamut colors
RGB_Axe_AB(ROW,1) = 0.5;
RGB_Axe_AB(ROW,2) = 0.5;
RGB_Axe_AB(ROW,3) = 0.5;
end
if RGB_Axe_AB(ROW,2) > 1
RGB_Axe_AB(ROW,2) = 1;
% Show white color for out of gamut colors
RGB_Axe_AB(ROW,1) = 0.5;
RGB_Axe_AB(ROW,2) = 0.5;
RGB_Axe_AB(ROW,3) = 0.5;
end
if RGB_Axe_AB(ROW,3) < 0
RGB_Axe_AB(ROW,3) = 0;
% Show white color for out of gamut colors
RGB_Axe_AB(ROW,1) = 0.5;
RGB_Axe_AB(ROW,2) = 0.5;
RGB_Axe_AB(ROW,3) = 0.5;
end
if RGB_Axe_AB(ROW,3) > 1
RGB_Axe_AB(ROW,3) = 1;
% Show white color for out of gamut colors
RGB_Axe_AB(ROW,1) = 0.5;
RGB_Axe_AB(ROW,2) = 0.5;
RGB_Axe_AB(ROW,3) = 0.5;
end
end
RGB_Axe_AB_ColorMap = colormap(RGB_Axe_AB)
colormapAB = RGB_Axe_AB_ColorMap;
colorListAB = colormapAB;
end
function sliderCB(SliderH, EventData)
global txt_ctrl;
global Axe_a_b;
CIE_a = 128;
CIE_b = 65;
% Retrieve slider current value of
Slider_L_New = SliderH.Value * 100;
set(txt_ctrl,'String',num2str(round(Slider_L_New)));
Axe_L_New = transpose(linspace(Slider_L_New, Slider_L_New, 65));
for row = 1:65
Col = linspace(CIE_a, CIE_a, 65)';
RowX=[Axe_a_b, Col];
colorListAB = CalculateColorList(CIE_a, CIE_b, Axe_L_New)
scatter(RowX(:,1),RowX(:,2),100, colorListAB, 'filled', 's');
CIE_a = CIE_a - 4;
end
end
Any help is appreciated.

7 Kommentare

Cris LaPierre
Cris LaPierre am 24 Jan. 2022
What are the improvements you are looking for? The more specific you are, the easier it is to provide help.
Roger Breton
Roger Breton am 25 Jan. 2022
I wish I did not have to use a loop? I wonder if there are constructs that are far more optimed than manually iterating rows after rows, from top to bottom, calculating a new colormap each time?
@Roger Breton: Can you verify that your usage of linspace() is correct everywhere? For instance, the expressions
Col = linspace(CIE_a, CIE_a, 65)';
Axe_L_ROW = transpose(linspace(CIE_a, CIE_a, CIE_b));
Axe_L_New = transpose(linspace(Slider_L_New, Slider_L_New, 65));
all have the first and second arguments to linspace() the same, which will produce a vector of repeated scalars, e.g.:
linspace(45,45,10)
ans = 1×10
45 45 45 45 45 45 45 45 45 45
Is this what you intend?
(This is not directly related to speed, but it is useful to understand what the code is supposed to be doing.)
Roger Breton
Roger Breton am 26 Jan. 2022
Yes, this is what I intended. I just did not know any other function to generate a vector of constant values?
@Roger Breton: You can use ones() and multiply by the value you want (or use zeros() and add the value you want), or use repelem() or repmat(), e.g.:
Col = CIE_a*ones(65,1);
Axe_L_ROW = repelem(CIE_a,CIE_b,1);
Axe_L_New = repmat(Slider_L_New,65,1);
To generate a vector of constant values you can use repmat, ones, or zeros.
v1 = repmat(42, 1, 5)
v1 = 1×5
42 42 42 42 42
v2 = 42 + zeros(1, 5)
v2 = 1×5
42 42 42 42 42
v3 = 42 * ones(1, 5)
v3 = 1×5
42 42 42 42 42
You can also look at the functions listed in the See Also section on the documentation pages for those functions for other related functions.
Roger Breton
Roger Breton am 28 Jan. 2022
Ah! So many little "details" to learn....... Thanks!!!!!!

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Cris LaPierre
Cris LaPierre am 25 Jan. 2022
Bearbeitet: Cris LaPierre am 26 Jan. 2022
You can get around using for loops if you meshgrid your X and Y vectors. I don't love the globals, either. Another way to speed up your code is minimize what gets printed to the screen. Here is what I had time to put together for you.
Note that the control code works, but I had to comment it out to get the code to run in this platform.
fig=figure('Name','Roger Breton sRGB CIE ab diagram');
Test = fig.Position;
fig.Position = [1600 500 700 700];
ax = axes(fig);
axis([-128 128 -128 128]);
xticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
yticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
CIE_a = 128;
CIE_b = 65; % 128 / 65, Steps of 4
% Algorithm :
Axe_L = 50;
Axe_a_b = linspace(-128, 128, 65);
[X,Y] = meshgrid(Axe_a_b,Axe_a_b);
colorListAB = CalculateColorList(X, Y, Axe_L);
scatter(Y(:),X(:),100, colorListAB, 'filled', 's');
%% Works, but commenting out because can't be used in this platform
% txt_ctrl = uicontrol('Style', 'text', 'Position',[640 450 50 50], 'String', ['50']);
% set(txt_ctrl, 'FontSize', 20);
%
% uicontrol('Style', 'Slider', 'Position',[655 500 20 150], 'Value', 0.5, 'Callback', {@sliderCB,txt_ctrl});
function [colorListAB] = CalculateColorList(X,Y, Axe_L)
Axe_L = ones(size(X))*Axe_L;
Lab_Axe_AB = [Axe_L(:), Y(:), X(:)];
RGB_Axe_AB = lab2rgb(Lab_Axe_AB);
ind1 = min(RGB_Axe_AB,[],2);
ind2 = max(RGB_Axe_AB,[],2);
RGB_Axe_AB(ind1<0,:) = 0.5;
RGB_Axe_AB(ind2>1,:) = 0.5;
colorListAB = colormap(RGB_Axe_AB);
end
function sliderCB(SliderH, EventData,txt_ctrl)
CIE_a = 128;
CIE_b = 65;
% Retrieve slider current value of
Slider_L_New = SliderH.Value * 100;
set(txt_ctrl,'String',num2str(round(Slider_L_New)));
Axe_L_New = Slider_L_New;
Axe_a_b = linspace(-128, 128, 65);
[X,Y] = meshgrid(Axe_a_b,Axe_a_b);
colorListAB = CalculateColorList(X, Y, Axe_L_New);
scatter(Y(:),X(:),100, colorListAB, 'filled', 's');
end

9 Kommentare

Roger Breton
Roger Breton am 26 Jan. 2022
You have no idea how much meshgridding I have tried!!!! It just did not work? I will look at your code, Chris, and report -- thank you so very much!
Roger Breton
Roger Breton am 26 Jan. 2022
Wow! Your code executes instantly!!!
Roger Breton
Roger Breton am 26 Jan. 2022
Bearbeitet: Roger Breton am 26 Jan. 2022
I commented out your UI code and it worked perfect!
Wow!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
I owe you a 'pint', as they say :-)
'This' platform = running the code here (in Answers code block)
See the error message below.
fig=figure('Name','Roger Breton sRGB CIE ab diagram');
Test = fig.Position;
fig.Position = [1600 500 700 700];
ax = axes(fig);
axis([-128 128 -128 128]);
xticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
yticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
CIE_a = 128;
CIE_b = 65; % 128 / 65, Steps of 4
% Algorithm :
Axe_L = 50;
Axe_a_b = linspace(-128, 128, 65);
[X,Y] = meshgrid(Axe_a_b,Axe_a_b);
colorListAB = CalculateColorList(X, Y, Axe_L);
scatter(Y(:),X(:),100, colorListAB, 'filled', 's');
%% Works, but commenting out because can't be used in this platform
txt_ctrl = uicontrol('Style', 'text', 'Position',[640 450 50 50], 'String', ['50']);
Error using uicontrol
This functionality is not available on remote platforms.
set(txt_ctrl, 'FontSize', 20);
uicontrol('Style', 'Slider', 'Position',[655 500 20 150], 'Value', 0.5, 'Callback', {@sliderCB,txt_ctrl});
function [colorListAB] = CalculateColorList(X,Y, Axe_L)
Axe_L = ones(size(X))*Axe_L;
Lab_Axe_AB = [Axe_L(:), Y(:), X(:)];
RGB_Axe_AB = lab2rgb(Lab_Axe_AB);
ind1 = min(RGB_Axe_AB,[],2);
ind2 = max(RGB_Axe_AB,[],2);
RGB_Axe_AB(ind1<0,:) = 0.5;
RGB_Axe_AB(ind2>1,:) = 0.5;
colorListAB = colormap(RGB_Axe_AB);
end
function sliderCB(SliderH, EventData,txt_ctrl)
CIE_a = 128;
CIE_b = 65;
% Retrieve slider current value of
Slider_L_New = SliderH.Value * 100;
set(txt_ctrl,'String',num2str(round(Slider_L_New)));
Axe_L_New = Slider_L_New;
Axe_a_b = linspace(-128, 128, 65);
[X,Y] = meshgrid(Axe_a_b,Axe_a_b);
colorListAB = CalculateColorList(X, Y, Axe_L_New);
scatter(Y(:),X(:),100, colorListAB, 'filled', 's');
end
Stephen makes a great suggestion. If you make your scatter figure full screen, you see dots. However, that doesn't happen with an image. You need to do some reshaping of the array, and I'm sure with more time you could clean things up, but here's a rough first pass.
Note that, in images, (0,0) is the top left, not botton left, so axis xy is used to make the output the same as what you had before.
fig=figure('Name','Roger Breton sRGB CIE ab diagram');
Test = fig.Position;
fig.Position = [1600 500 700 700];
ax = axes(fig);
axis([-128 128 -128 128]);
xticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
yticks([-128 -112 -96 -80 -64 -48 -32 -16 0 16 32 48 64 80 96 112 128]);
CIE_a = 128;
CIE_b = 65; % 128 / 65, Steps of 4
% Algorithm :
Axe_L = 50;
Axe_a_b = linspace(-128, 128, 65);
[X,Y] = meshgrid(Axe_a_b,Axe_a_b);
% colorListAB = CalculateColorList(X, Y, Axe_L);
% scatter(Y(:),X(:),100, colorListAB, 'filled', 's');
colorListAB = CalculateColorList(Y,X,Axe_L);
colorListAB = reshape(colorListAB,CIE_b,CIE_b,3);
image(X(1,:),Y(:,1),colorListAB)
axis xy
%% Works, but commenting out because can't be used in this platform
% txt_ctrl = uicontrol('Style', 'text', 'Position',[640 450 50 50], 'String', ['50']);
% set(txt_ctrl, 'FontSize', 20);
%
% uicontrol('Style', 'Slider', 'Position',[655 500 20 150], 'Value', 0.5, 'Callback', {@sliderCB,txt_ctrl});
function [colorListAB] = CalculateColorList(X,Y, Axe_L)
Axe_L = ones(size(X))*Axe_L;
Lab_Axe_AB = [Axe_L(:), Y(:), X(:)];
RGB_Axe_AB = lab2rgb(Lab_Axe_AB);
ind1 = min(RGB_Axe_AB,[],2);
ind2 = max(RGB_Axe_AB,[],2);
RGB_Axe_AB(ind1<0,:) = 0.5;
RGB_Axe_AB(ind2>1,:) = 0.5;
colorListAB = colormap(RGB_Axe_AB);
end
function sliderCB(SliderH, EventData,txt_ctrl)
CIE_a = 128;
CIE_b = 65;
% Retrieve slider current value of
Slider_L_New = SliderH.Value * 100;
set(txt_ctrl,'String',num2str(round(Slider_L_New)));
Axe_L_New = Slider_L_New;
Axe_a_b = linspace(-128, 128, 65);
[X,Y] = meshgrid(Axe_a_b,Axe_a_b);
% colorListAB = CalculateColorList(X, Y, Axe_L_New);
% scatter(Y(:),X(:),100, colorListAB, 'filled', 's');
colorListAB = CalculateColorList(Y,X,Axe_L_New);
colorListAB = reshape(colorListAB,CIE_b,CIE_b,3);
image(X(1,:),Y(:,1),colorListAB)
axis xy
end
Roger Breton
Roger Breton am 26 Jan. 2022
I got it! "Remote platform".
BTW, your code is phenomenal. I don't think I'll ever be able to write code this good...
I had the intuition of some of your solutions... but I lacked the knowledge...
Thank you so much, once again!!
Roger Breton
Roger Breton am 27 Jan. 2022
I never understood what mesgrid did? I should have tried with small vectors, like I just did now. The fact I was dealing with rather large vectors (-128 to 128 step of 4) kind of did not lend itself well to abstract understanding or visualization. This morning, thinking about your code, I had the (how clever!) idea to create smaller meshgrid :
Axe_a_b = linspace(-5, 5, 11);
[X,Y] = meshgrid(Axe_a_b,Axe_a_b);
This is the result :
I always understood that the command would give me a 'one piece' grid of X by Y, and all the intersections would be calculated. But that's not AT ALL what meshgrid does. Now, with this smaller example, I'm finally able to follow. Thank you for helping me better understand Matlab.
I was able to figure out the workings of most instructions but not this one :
RGB_Axe_AB(ind1<0,:) = 0.5;
As far as I can tell, this is using the ind1 array to change all values in RGB_Axe_AB that are below Zero, to 0.5 but I confess I'm struggling with the 'notation' : the colon operator represents all rows? In other words, this is changing all rows values to 0.5 for the elements that are less than Zero?
I'll try to generate a dataset where I can witness the behavior of this operation...
Cris LaPierre
Cris LaPierre am 28 Jan. 2022
Bearbeitet: Cris LaPierre am 28 Jan. 2022
This replaced all your if statements for when any value in a row was <0. The colon here indicates all columns, not rows.
There are two steps to doing this.
ind1 = min(RGB_Axe_AB,[],2); % returns the min value in each row
ind2 = max(RGB_Axe_AB,[],2); % returns the max value in each row
% identifies each row where the min is <0.
% Changes all values in the corresponding row of RGB_Axe_AB to 0.5
RGB_Axe_AB(ind1<0,:) = 0.5;
% identifies each row where the max is >1.
% Changes all values in the corresponding row of RGB_Axe_AB to 0.5
RGB_Axe_AB(ind2>1,:) = 0.5;

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Benjamin Thompson
Benjamin Thompson am 25 Jan. 2022

0 Stimmen

The MATLAB editor has some helpful suggestions, removing unnecessary output and so on. Have you tried using the Profile button in the editor to run it and find the places where the most time is spent?

4 Kommentare

Benjamin Thompson
Benjamin Thompson am 25 Jan. 2022
It seems to me you might rather construct your output in a matrix and display it as an image once, using imshow, rather than then 65 separate scatter plot calls. You are plotting all these filled squares which are basically the same as pixels right?
Roger Breton
Roger Breton am 26 Jan. 2022
Good observation! First of all, I am unable to visualize abstractly what this 'matrix' would look like? It would have to be 128 x 128 elements, but then, each element would have to store 3 values : that would be a 128 x 128 x 3? As simple as that? I can't believe it would be this easy?
Stephen23
Stephen23 am 26 Jan. 2022
Updating a IMAGE graphics object would be much more efficient than what you are doing now:
Roger Breton
Roger Breton am 26 Jan. 2022
I have no hesitation to believe you!!

Melden Sie sich an, um zu kommentieren.

Kategorien

Produkte

Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by