fmincon gets very slow after few time
20 views (last 30 days)
Show older comments
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
on 23 Nov 2021
What do you mean by "getting slower"? How are you observing changes in speed?
Also, what is samsid()? It does not seem to be a Mathworks-provided function.
Answers (2)
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.
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
See Also
Categories
Find more on Introduction to Installation and Licensing 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!