%% Mínimos locales (fminunc) vs. globales (ga)
% © 2019, A. Sala. Universitat Politècnica de València. Todos los derechos reservados.
% Presentación en vídeo: http://personales.upv.es/asala/YT/V/optimfmga.html
% *Este código ejecutó sin errores en Matlab R2019b
% Objetivo: Comparar la optimización local (gradiente, hessiano, ...) de fminunc (Optimization Toolbox) con la global de los algoritmos genéticos (ga, Global Optimization Toolbox) que usan búsqueda aleatoria dirigida.
% Función a minimizar:

f=@(x) 0.1*x.^2-4*cos(x)+1;
rango_x=-14:.02:14;
plot(rango_x,f(rango_x)), grid on, axis tight

%% Optimización local

x_inicial=-5;
tic, xopt=fminunc(f,x_inicial), toc
plot(rango_x,f(rango_x)), grid on, axis tight, hold on
plot(x_inicial,f(x_inicial),'x','LineWidth',12), plot(xopt,f(xopt),'og','LineWidth',9),hold off
x_inicial=1
tic, xopt2=fminunc(f,x_inicial), toc
plot(rango_x,f(rango_x)), grid on, axis tight, hold on
plot(x_inicial,f(x_inicial),'x','LineWidth',12), plot(xopt2,f(xopt2),'og','LineWidth',9),hold off

%% Optimización global

x_min=-8; x_max=8; %zona de búsqueda
opts=optimoptions('ga','MaxTime',120,'FunctionTolerance',5e-4,'Display','iter');
% dos minutos máximo tiempo de ejecución (aprox.)
NumParamsAOptimizar=1;
tic
[xopt_ga]=ga(f, NumParamsAOptimizar,[],[],[],[],x_min,x_max,[],opts)
toc
plot(rango_x,f(rango_x)), grid on, axis tight, hold on
plot(xopt_ga,f(xopt_ga),'og','LineWidth',9),hold off

%% Opción intermedia: multistart

F_MejorPorAhora=1e9;
xopt=NaN;
for i=1:6
    x_inicial=rand()*(x_max-x_min)+x_min;
    [xopt_tmp,fval]=fminunc(f,x_inicial);
    if(fval<F_MejorPorAhora)
        xopt=xopt_tmp;
        F_MejorPorAhora=fval;
    end
end
xopt
F_MejorPorAhora

%% Conclusiones
% La optimización "local" es más rápida pero su resultado puede ser subóptimo. La búsqueda global tiene más probabilidades de obtener el óptimo global, pero es  costosa computacionalmente si el número de parámetros a buscar es elevado.