fmincon gets very slow after few time

3 views (last 30 days)
Miguel Ángel
Miguel Ángel on 23 Nov 2021
Edited: Matt J on 30 Nov 2021
Hi all,
I am using fmincon for finding endmembers in each pixel of an image. I have a double for loop which goes pixel by pixel applying fmincon. When the code starts, each pixel optimization is pretty fast (miliseconds), but as the run advances it starts getting slower and slower. It does not have to do with memory allocation issues since I do it. Also, if I close Matlab and reopen it, if I continue in the last pixel it gets fast again for the first pixels, but again slower and slower until it takes lime one minute per pixel.
Here the example of code I am using:
maps = single(zeros(rows,columns,3)); % Create empty maps.
cont = 0;
for row = 1:rows
for col = 1:columns
cont = cont + 1;
C_MSE_subt = fmincon( @(x)SAMSID_subtractive(double(squeeze(cube(row,col,:))),E,x'), init_point, [-1 0 0; 0 -1 0; 0 0 -1 ], [0; 0; 0], [1 1 1], 1, [0 0 0], [1 1 1],[],options);
maps(row,col,:) = reshape(C_MSE_subt,1,1,3);
end
end
The optimizatiob function is pretty simple, just calculating a spectrum and comparing it against the one passed as input:
function SAMSID = SAMSID_subtractive(spectra1,E,C)
spectra2 = subtractive_model(E,C);
[~,~,SAMSID]=samsid(spectra1,spectra2);
It would seem normal to me if every pixel behaved slow. But the few first pixels very fast and then get slower and slower... Also I checked RAM and CPU and none of them are busy.
If I change the optimization function it does not get slow. For instance, using MSE instead of SAMSID metric, it is fast from the beggining to the end:
function MSE = mean_squared_error_subtractive(spectra1,E,C)
spectra2 = subtractive_model(E,C);
MSE = sum((spectra1-spectra2).^2) / size(spectra1,1);
Any ideas of why this could happen?
Thanks in advance!
  2 Comments
Matt J
Matt J on 23 Nov 2021
Incidentally, you should get rid of your inequality constraints,
A=[-1 0 0; 0 -1 0; 0 0 -1 ]; b= [0; 0; 0];
They are redundant with your explicit lower bounds lb=[0 0 0] and are just slowing things down.

Sign in to comment.

Answers (2)

Matt J
Matt J on 23 Nov 2021
I suspect samsid() is just not as smooth or well-conditioned as mse() for some pixels, and therefore takes more iterations to terminate. You can check the fmincon output to see how many iterations are being performed in each pixel and see if it correlates with the slow-down you are observing.
  8 Comments
Matt J
Matt J on 30 Nov 2021
Functions are local. They are not nested in the same Matlab script, but they are all as .m files in the same folder of the main code.
If so, they are neither local nor nested.

Sign in to comment.


Matt J
Matt J on 23 Nov 2021
A few more performance optimizations that you should consider:
maps = zeros(rows,columns,3,'single'); %<------ post conversion to single is unnecessary
cube=double(cube); %<----pre-cast the whole array to double
cont = 0;
for row = 1:rows
for col = 1:columns
cont = cont + 1;
tmp=squeeze(cube(row,col,:)); %<------ avoid doing this in every function call
C_MSE_subt = fmincon( @(x)SAMSID_subtractive(tmp,E,x'), init_point, [], [], [1 1 1], 1, [0 0 0], [1 1 1],[],options);
maps(row,col,:) = reshape(C_MSE_subt,1,1,3);
init_point(:)=C_MSE_subt(:); %<----- the previous solution might be very close to the next one
end
end
  1 Comment
Miguel Ángel
Miguel Ángel on 26 Nov 2021
Thanks for all valuable tips. I implemented them all:
cube = double(cube);
SAMSID = zeros(rows,columns,'single'); % Create empty SAMSID map.
ti = SAMSID; % Create empty optimization time map.
flag = SAMSID;
iter = SAMSID;
cont = 0;
for row = 1:rows
for col = 1:columns
cont = cont + 1;
clc, disp(['Generating pigments map: ' num2str(cont/num_pixels*100) '%...'])
tmp = squeeze(cube(row,col,:));
tic
[C_SAMSID_subt,SAMSID(row,col),flag(row,col),output] = fmincon( @(x)SAMSID_subtractive(tmp,E,x'), init_point, [], [], [1 1 1], 1, [0 0 0], [1 1 1],[],options);
ti(row,col) = toc;
iter(row,col) = output.iterations;
maps(row,col,:) = reshape(C_SAMSID_subt,1,1,3);
init_pont(:) = C_SAMSID_subt(:);
end
end

Sign in to comment.

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by