% discesa.m
%
% test rozzo del metodo della massima discesa
%
% y=fun(x) chiama la funzione, x vettore, y numero
%
% v=grad(x) chiama il gradiente, x vettore, v vettore
%
% procedura:
% fmin=fun(xmin) e' il minimo finora trovato, da battere
% nmax e' il max numero di passi permesso
% gradmin e' il minimo valore del gradiente permesso
% xcentro raggio sono il punto di centro e il raggio della zona permessa
%
% se si supera nmax o si scende sotto gradmin o ci si allontana
% piu' di raggio da xcentro o il passo diventra troppo piccolo 
% la procedura termina.
%
% 
% mettere qui xstart, raggio, nmax, gradmin, passomin
xstart=[1,2];
raggio=10;
nmax=50;
gradmin=10^(-10);
passomin=10^(-14);
%
% inizializzazioni
%
xmin=xstart;
fmin=fun(xmin);
niter=0;
passo=raggio/1000;
xgrad=grad(xmin);
gradval=norm(xgrad);
xgrad=xgrad/gradval;
distanza=norm(xmin-xstart);
%
figure();
axis([-1 3 -1 3]);
hold on;
pause(1);
plot(xstart(1),xstart(2),'ro');
%
% inizia il ciclo
%
while ((gradval > gradmin) & (niter < nmax) & (distanza < raggio) )
% inizio while
niter=niter+1
% stampe di debug
passo
fmin
gradval
% fine stampe
x1=xmin-passo*xgrad;
m1=fun(x1);
% forse posso aumentare il passo ?
if (m1 < fmin) 
 passo2=2*passo;
 x2=xmin-passo2*xgrad;
 m2=fun(x2);
 if ((norm(x2-xstart)<raggio)&(m2<m1))
% sembra che il punto sia ok, lo tengo
    x1=x2;
    m1=m2;
    passo=passo2;
    end 
 end
% 
 while (m1 > fmin)
% che cavolo di discesa ?? devo aver oltrepassato il minimo...
 passo=2*passo/3;
 x1=xmin-passo*xgrad;
 m1=fun(x1);
 end
% a costo di aver ridotto molto il passo, ora ho un punto migliore.
% in qualche modo siamo scesi un pochino...
% ricalcoliamo il gradiente e ricominciamo
fmin=m1;
xmin=x1;
xgrad=grad(xmin);
gradval=norm(xgrad);
xgrad=xgrad/gradval;
distanza=norm(xstart-xmin);
plot(xmin(1),xmin(2),'o');
pause(1);
% fine while
end
%
% fine script
%
% scriviamo come e' andata
format long
printf("situazione:\n");
niter
gradval
distanza
passo
fmin
xmin
%%%%%%%%%%%%%%%%%%%%%
