c Scilab ( http://www.scilab.org/ ) - This file is part of Scilab c Copyright (C) 1988 - INRIA - F. BONNANS c c This file must be used under the terms of the CeCILL. c This source file is licensed as described in the file COPYING, which c you should have received as part of this distribution. The terms c are also available at c http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt c subroutine rlbd(indrl,n,simul,x,binf,bsup,f,hp,t,tmax,d,gn, & tproj,amd,amf,imp,io,zero,nap,napmax,xn,izs,rzs,dzs) c c!but c subroutine de recherche lineaire pour des problemes avec c contraintes de borne (traitees par projection) c le critere de retour est une extension de celui de wolfe c!methode c pour chaque valeur du parametre t , sont calcules le critere c et son gradient. c une phase d extrapolation permet d obtenir un encadrement. c l intervalle est ensuite reduit suivant les cas par une methode c de dichotomie, d interpolation lineaire sur les derivees ou c d interpolation cubique. c c!impressions c si imp > 2 , rlbd fournit les impressions suivantes : c c la premiere ligne indique : c t premiere valeur de t fournie en liste d' appel c tproj plus petit t > 0 pour lequel on bute sur une borne c dh/dt derivee en zero de h(t)=f(x+t*d)-f(x) c tmax valeur maximale de t fournie en liste d' appel c c lignes suivantes : c chaine de caracteres en debut de ligne : indique comment sera calcule c le pas de la ligne suivante ; c ic : interpolation cubique c s : saturation d une variable sur une borne c id : interpolation lineaire sur la derivee c e : extrapolation c d :interpolation cubique ayant echouee t est calcule par dichotomie c b :sauvegarde de convergence active c c!subroutines utilisees c proj et satur (bibl. modulopt) c!liste d appel c c subroutine rlbd(indrl,n,simul,proj,x,binf,bsup,f,hp,t,tmax,d,gn, c & tproj,amd,amf,imp,io,zero,nap,napmax,xn,izs,rzs,dzs) c c e;s;e,s:parametres initialises en entree,en sortie,en entree et c en sortie c indrl<0:la recherche lineaire n a pas trouve de meilleur pas(e,s) c =0:arret demande par l'utilisateur dans simul c >0:meilleur pas fourni avec f et g c >9:meilleur pas fourni avec f et sans g c =14:deltat trop petit c =13:nap=napmax c =8:toutes les variables sont saturees c =4:deltat trop petit c =3:nap=napmax c =2:t=tmax c =1:descente serieuse avec t=3:une impression par calcul de simul (e) c io:numero du fichier resultat (e) c zero:proche du zero machine (e) c nap:nombre d'appel a simul (e) c napmax:nombre maximum d'appel a simul (e) c xn:tableau de travail de dimension n (=x+t*d) c izs,rzs,dzs:cf norme modulopt (e,s) c! c parametres de l algorithme c eps1:sauvegarde de conv.dans l interpolation lineaire sur la derivee c eps:sauvegarde de conv.dans la l interpolation par saturation c d une contrainte. c epst:sauvegerde de conv.dans l interpolation cubique c extra,extrp:servent a calculer la limite sur la variation relative c de t dans l extrapolation et l interpolation lineaire sur la derivee c cofder: intervient dans le choix entre les methodes d' interpolation c c variables de travail c fn:valeur du critere en xn c hpn:derivee de f(x+t*d) par rapport a t c hpd:valeur de hpn a droite c hpg:valeur de hpn a gauche c td:pas trop grand c tg:pas trop petit c tproj:plus petit pas saturant une contrainte c tmaxp:plus grand pas saturant une contraite c ftd:valeur de f en x+td*d c ftg:valeur de f en x+tg*d c hptd:valeur de hpn en x+td*d c hptg:valeur de hpn en x+tg*d c imax=1:tmax a ete atteint c =0:tmax n a pas ete atteint c icos:indice de la variable saturee par la borne superieure c icoi:indice de la variable saturee par la borne inferieure c ico1:indice de la variable saturee en tmaxp c icop:indice de la variable saturee en tproj c implicit double precision(a-h,o-z) external simul,proj character var2*3 dimension x(n),xn(n),gn(n),d(n),binf(n),bsup(n),izs(*) double precision dzs(*) character bufstr*(4096) real rzs(*) c indrl=1 eps1=.90d+0 eps=.10d+0 epst=.10d+0 extrp=100.0d+0 extra=10.0d+0 cofder=100. var2=' ' c ta1=0.0d+0 f0=f fa1=f hpta1=hp imax=0 hptg=hp ftg=f tg=0.0d+0 td=0.0d+0 icos=0 icoi=0 icop=0 c c calcul de tproj:plus petit point de discontinuite de h'(t) tproj=0.0d+0 do 7 i=1,n CRES=d(i) if (CRES .lt. 0) then goto 4 elseif (CRES .eq. 0) then goto 7 else goto 5 endif 4 t2=(binf(i)-x(i))/d(i) go to 6 5 t2=(bsup(i)-x(i))/d(i) 6 if (t2.le.0.0d+0) go to 7 if (tproj.eq.0.0d+0) tproj=t2 if (t2.gt.tproj) go to 7 tproj=t2 icop=i 7 continue c if (imp.ge.3) then write (bufstr,14050) tproj,tmax,hp call basout(io_out ,io ,bufstr(1:lnblnk(bufstr))) endif 14050 format (' rlbd tp=',e11.4, & ' tmax=',e11.4,' dh0/dt=',e11.4 ) 15000 format (a3,' t=',e11.4,' h=',e11.4,' dh/dt=',e11.4, & ' dfh/dt=', e11.4,' dt',e8.1) 15020 format (3x,' t=',e11.4,' h=',e11.4,' dh/dt=',e11.4, & ' dfh/dt=', e11.4,' dt',e8.1) 16000 format (' rlbd : sortie du domaine : indic=',i2,' t=',e11.4) c c boucle c c calcul de xn,de fn et de gn 200 if (nap.ge.napmax) then k=3 goto 1000 end if do 230 i=1,n 230 xn(i)=x(i)+t*d(i) call proj (n,binf,bsup,xn) if (icos.gt.0) xn(icos)=bsup(icos) if (icoi.gt.0) xn(icoi)=binf(icoi) indic=4 call simul (indic,n,xn,fn,gn,izs,rzs,dzs) nap=nap+1 if (indic.lt.0) then if (imp.ge.3) then write (bufstr,16000) indic,t call basout(io_out ,io ,bufstr(1:lnblnk(bufstr))) endif if (nap.ge.napmax) go to 1000 t=tg+(t-tg)/4.0d+0 tmax=t imax=1 icoi=0 icos=0 var2='dd ' go to 800 endif if(indic.eq.0) then indrl=0 go to 1010 endif c c calcul de hpg et hpd hpg=0.0d+0 do 242 i=1,n 242 xn(i)=x(i)+t*d(i) if (icoi.gt.0) xn(icoi)=bsup(icoi) if (icos.gt.0) xn(icos)=bsup(icos) call proj(n,binf,bsup,xn) do 244 i=1,n xni=xn(i) 244 if(binf(i).lt.xni.and.xni.lt.bsup(i)) hpg=hpg + d(i)*gn(i) hpd=hpg if(icoi.gt.0) hpg=hpg + d(icoi)*gn(icoi) if(icos.gt.0) hpg=hpg + d(icos)*gn(icos) c icoi=0 icos=0 if((hpd.ne.0.0d+0).or.(hpg.ne.0.0d+0)) go to 360 c c la derivee de h est nulle c calcul du pas saturant toutes les bornes:tmaxp tmaxp=0.0d+0 ico1=0 do 350 i=1,n CRES=d(i) if (CRES .lt. 0) then goto 310 elseif (CRES .eq. 0) then goto 350 else goto 320 endif 310 t2=(binf(i)-x(i))/d(i) go to 330 320 t2=(bsup(i)-x(i))/d(i) 330 if (t2.le.0.0d+0) go to 350 if (tmaxp.eq.0.0d+0) tmaxp=t2 if (tmaxp.gt.t2)go to 350 tmaxp=t2 ico1=i 350 continue if (t.lt.tmaxp) then if(fn.le.f+amf*hp*t) goto 1010 t=t/10.0d+0 var2='d ' goto 800 end if icos=ico1 icoi=0 if (d(ico1).lt.0.0d+0) then icoi=ico1 icos=0 end if c c toutes les variables sont saturees if (imp.ge.3) then write (bufstr,3330) tmaxp call basout(io_out ,io ,bufstr(1:lnblnk(bufstr))) endif 3330 format ('toutes les variables sont saturees:tmaxp= ',e11.4) t=tmaxp if (fn.lt.f+amf*hp*tmaxp) then indrl=8 goto 1010 end if hpg=d(ico1)*gn(ico1) if ((fn.lt.f).and.(hpg.lt.0.0d+0)) then indrl=8 goto 1010 end if 360 continue c c test de wolfe c a=f+amf*hp*t if (fn.gt.a) then c le pas est trop grand c (dans le cas quadratique changer eps1 et extra si td