TABLE OF CONTENTS
ABINIT/brent [ Functions ]
NAME
brent
FUNCTION
minimizes a function along a line
COPYRIGHT
Copyright (C) 1998-2018 ABINIT group (DCA, XG, MT) This file is distributed under the terms of the GNU General Public License, see ~ABINIT/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~ABINIT/Infos/contributors .
INPUTS
dp_dum_vdp: function to be minimized (return a dp from a vector of dp) vdp_dum_vdp: derivative of the function (return a vector of dp from a vector of dp) itmax: number of iterations allowed tol: tolerance on error. It depend on the precision of the numbers (usualy chosen as sqrt(max precision available with your floating point reresentation)) ax,xx,bx: a bracketing triplet around the minimum to be find
OUTPUT
xmin: value such that dp_dum_vdp(v(:)+xmin*grad(:)) is minimum brent: dp_dum_vdp(v(:)+xmin*grad(:))
SIDE EFFECTS
grad(:): direction along which the minimization is performed v(:): starting and ending point of the minimization
PARENTS
linmin
CHILDREN
dotproduct
SOURCE
39 #if defined HAVE_CONFIG_H 40 #include "config.h" 41 #endif 42 43 #include "abi_common.h" 44 45 46 function brent(nv1,nv2,dp_dum_v2dp,v2dp_dum_v2dp,sub_dum_dp_v2dp_v2dp,itmax,v,grad,ax,xx,bx,tol,xmin) 47 48 use defs_basis 49 50 !This section has been created automatically by the script Abilint (TD). 51 !Do not modify the following lines by hand. 52 #undef ABI_FUNC 53 #define ABI_FUNC 'brent' 54 use interfaces_62_cg_noabirule, except_this_one => brent 55 !End of the abilint section 56 57 implicit none 58 59 !Arguments ------------------------------------ 60 include "dummy_functions.inc" 61 !scalars 62 integer,intent(in) :: itmax,nv1,nv2 63 real(dp) :: brent 64 real(dp),intent(in) :: ax,bx,tol,xx 65 real(dp),intent(out) :: xmin 66 !arrays 67 real(dp),intent(inout) :: grad(nv1,nv2),v(nv1,nv2) 68 69 !Local variables------------------------------- 70 !scalars 71 integer :: iter 72 real(dp) :: a,b,d,d1,d2,du,dv,dw,dx,e,fu,fv,fw,fx,olde,tol1,tol2,u,u1,u2,vv,w 73 real(dp) :: x,xm,zeps 74 logical :: ok1,ok2,ok3,ok4 75 76 !************************************************************************ 77 zeps=epsilon(ax*real(1e-2,dp)) 78 a=min(ax,bx) 79 b=max(ax,bx) 80 vv=xx 81 w=xx 82 x=xx 83 e=zero 84 fx=dp_dum_v2dp(nv1,nv2,x*grad(:,:)+v(:,:)) 85 fv=fx 86 fw=fx 87 !the function sub_dum_dp_v2dp_v2dp must do the equivalent of 88 !v(:,:)=v(:,:)+(grad(:,:)*x) 89 !but for instance renormilizing the density if brent is used on a density... 90 !vp(:,:) = v(:,:) 91 !sub_dum_dp_v2dp_v2dp(x,grad(:,:),vp(:,:) 92 !dx=dotproduct(v2dp_dum_v2dp(vp(:,:)),grad(:,:)) 93 dx=dotproduct(nv1,nv2,v2dp_dum_v2dp(nv1,nv2,v(:,:)+x*grad(:,:)),grad(:,:)) 94 dv=dx 95 dw=dx 96 do iter=1,itmax 97 xm=half*(a+b) 98 tol1=tol*abs(x)+zeps 99 tol2=two*tol1 100 if(abs(x-xm) <= (tol2-half*(b-a))) then 101 exit 102 end if 103 if(abs(e) > tol1) then 104 d1=two*(b-a) 105 d2=d1 106 if(dw /= dx) d1=(w-x)*dx/(dx-dw) 107 if(dv /= dx) d2=(vv-x)*dx/(dx-dv) 108 u1=x+d1 109 u2=x+d2 110 ok1=((a-u1)*(u1-b)>zero).and.(dx*d1<=zero) 111 ok2=((a-u2)*(u2-b)>zero).and.(dx*d2<=zero) 112 olde=e 113 e=d 114 if(ok1.or.ok2) then 115 if(ok1.and.ok2) then 116 d=merge(d1,d2,abs(d1)<abs(d2)) 117 else 118 d=merge(d1,d2,ok1) 119 end if 120 if(abs(d)<=abs(half*olde)) then 121 u=x+d 122 if(((u-a)<tol2).or.((b-u)<tol2)) d=sign(tol1,xm-x) 123 else 124 e=merge(a,b,dx>=zero)-x 125 d=half*e 126 end if 127 else 128 e=merge(a,b,dx>=zero)-x 129 d=half*e 130 end if 131 else 132 e=merge(a,b,dx>=zero)-x 133 d=half*e 134 end if 135 136 if(abs(d) >=tol1)then 137 u=x+d 138 fu=dp_dum_v2dp(nv1,nv2,(u*grad(:,:))+v(:,:)) 139 else 140 u=x+sign(tol1,d) 141 fu=dp_dum_v2dp(nv1,nv2,(u*grad(:,:))+v(:,:)) 142 if(fu>fx) then 143 exit 144 end if 145 end if 146 du=dotproduct(nv1,nv2,v2dp_dum_v2dp(nv1,nv2,(u*grad(:,:))+v(:,:)),grad(:,:)) 147 if(fu<=fx)then 148 if(u>=x)then 149 a=x 150 else 151 b=x 152 end if 153 vv=w 154 fv=fw 155 dv=dw 156 w=x 157 fw=fx 158 dw=dx 159 x=u 160 dx=du 161 fx=fu 162 else 163 if(u<x) then 164 a=u 165 else 166 b=u 167 end if 168 ok3=(w==x).or.(fu.le.fw) 169 ok4=(vv==w).or.(vv==x).or.(fu.lt.fv) 170 if(ok3) then 171 vv=w 172 fv=fw 173 dv=dw 174 w=u 175 fw=fu 176 dw=du 177 else if( ok4 ) then 178 vv=u 179 fv=fu 180 dv=du 181 end if 182 end if 183 end do 184 xmin=x 185 !the function sub_dum_dp_v2dp_v2dp must do the equivalent of 186 !v(:,:)=v(:,:)+(grad(:,:)*x) 187 !but for instance renormilizing the density if brent is used on a density... 188 call sub_dum_dp_v2dp_v2dp(nv1,nv2,x,grad(:,:),v(:,:)) 189 brent=fx 190 end function brent