Statistiques
| Révision :

root / src / Hinvup_DFP.f90 @ 4

Historique | Voir | Annoter | Télécharger (4,01 ko)

1 4 pfleura2
SUBROUTINE Hinvup_DFP(Nfree,ds,dgrad,Hess)
2 4 pfleura2
3 4 pfleura2
  IMPLICIT NONE
4 4 pfleura2
5 4 pfleura2
  INTEGER, PARAMETER :: KINT=KIND(1)
6 4 pfleura2
  INTEGER, PARAMETER :: KREAL=KIND(1.D0)
7 4 pfleura2
8 4 pfleura2
  INTEGER(KINT), INTENT(IN) :: NFREE
9 4 pfleura2
  REAL(KREAL), INTENT(INOUT) :: Hess(Nfree,Nfree)
10 4 pfleura2
  REAL(KREAL), INTENT(IN) :: ds(Nfree)
11 4 pfleura2
  REAL(KREAL), INTENT(IN) :: dGrad(Nfree)
12 4 pfleura2
13 4 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
14 4 pfleura2
!
15 4 pfleura2
! This subroutine updates the inverse of the Hessian
16 4 pfleura2
! using a DFP formula.
17 4 pfleura2
!
18 4 pfleura2
! input:
19 4 pfleura2
!  - nfree: number of coordinates
20 4 pfleura2
!  - ds: GeomOld-Geom (expressed in the optimization coord.)
21 4 pfleura2
!  - dgrad: GradOld-Grad  (expressed in the optimization coord.)
22 4 pfleura2
!
23 4 pfleura2
!  input/output:
24 4 pfleura2
!  - Hess: old Hessian in input, replaced by updated Hessian on output
25 4 pfleura2
!
26 4 pfleura2
!  Notations for the formula:
27 4 pfleura2
! s=Geom-GeomOld
28 4 pfleura2
! y=Grad-GradOld
29 4 pfleura2
! W= (H)-1 ie the inverse matrix that we are updating
30 4 pfleura2
! W+=W + s(sT)/(s,y)-[Wy(yT)W]/(y,Wy)
31 4 pfleura2
!
32 4 pfleura2
! We decompose the computation in two steps:
33 4 pfleura2
! first we compute the update, and then we add it to Hess to get the
34 4 pfleura2
! new Hessian.
35 4 pfleura2
! This allows us to introduce a scaling factor if needed later.
36 4 pfleura2
!
37 4 pfleura2
!!!!!!!!!!!!!!!!
38 4 pfleura2
!
39 4 pfleura2
! Due to the dual properties, this routine is also called to compute
40 4 pfleura2
! the BFGS update for the Hessian
41 4 pfleura2
!
42 4 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
43 4 pfleura2
44 4 pfleura2
45 4 pfleura2
  REAL(KREAL), ALLOCATABLE  :: HessOld(:,:) , Wy(:)
46 4 pfleura2
  REAL(KREAL), ALLOCATABLE  :: Hup(:,:)
47 4 pfleura2
  REAL(KREAL), ALLOCATABLE  :: Num(:,:), Num2(:,:)
48 4 pfleura2
  REAL(KREAL) :: Den, Den2,NormDS
49 4 pfleura2
  INTEGER(KINT) :: i,j,k, Idx
50 4 pfleura2
51 4 pfleura2
  LOGICAL :: debug
52 4 pfleura2
53 4 pfleura2
  interface
54 4 pfleura2
     function valid(string) result (isValid)
55 4 pfleura2
       logical                  :: isValid
56 4 pfleura2
       character(*), intent(in) :: string
57 4 pfleura2
     end function valid
58 4 pfleura2
59 4 pfleura2
  end interface
60 4 pfleura2
61 4 pfleura2
  debug=valid("Hinvup_DFP").OR. Valid('HUPDATE')
62 4 pfleura2
63 4 pfleura2
  if (debug) WRITE(*,*) "=========================== Entering Hinvup_DFP ===================="
64 4 pfleura2
65 4 pfleura2
  ALLOCATE(HessOld(nfree,nfree), Hup(nfree,nfree), &
66 4 pfleura2
       Num(nfree,nfree), Num2(nfree,nfree),Wy(Nfree) )
67 4 pfleura2
68 4 pfleura2
69 4 pfleura2
70 4 pfleura2
  HessOld=Hess
71 4 pfleura2
72 4 pfleura2
  if (debug) THEN
73 4 pfleura2
     WRITE(*,*) 'DBG Hinvup_DFP HessOld'
74 4 pfleura2
     Idx=min(12,Nfree)
75 4 pfleura2
     DO I=1,NFree
76 4 pfleura2
        WRITE(*,'(12(1X,F8.4))') HessOld(I,1:Idx)
77 4 pfleura2
     END DO
78 4 pfleura2
     WRITE(*,*) 'DBG Hinvup_DFP ds'
79 4 pfleura2
     WRITE(*,'(12(1X,F8.4))') ds(1:Idx)
80 4 pfleura2
     WRITE(*,*) 'DBG Hinvup_DFP dGrad'
81 4 pfleura2
     WRITE(*,'(12(1X,F8.4))') dGrad(1:Idx)
82 4 pfleura2
  END IF
83 4 pfleura2
84 4 pfleura2
85 4 pfleura2
86 4 pfleura2
  NormDS=sqrt(DOT_PRODUCT(DS,DS))
87 4 pfleura2
  if (NormDS>=1e-6) THEN
88 4 pfleura2
     IF (debug) WRITE(*,*) 'NormDS=',NormDS
89 4 pfleura2
     IF (debug) WRITE(*,*) 'DS=',DS
90 4 pfleura2
     IF (debug) WRITE(*,*) 'DGrad=',DGrad
91 4 pfleura2
     ! We calculate the denominator (DGrad,DS)
92 4 pfleura2
     den=DOT_PRODUCT(DGrad,DS)
93 4 pfleura2
94 4 pfleura2
     if (debug) WRITE(*,*) "(y,s)=(yT)s",den
95 4 pfleura2
96 4 pfleura2
     ! We calculate Wy
97 4 pfleura2
     Wy=0
98 4 pfleura2
     DO I=1,nfree
99 4 pfleura2
        DO J=1,NFree
100 4 pfleura2
           Wy(I)=Wy(I)+HessOld(i,j)*DGrad(j)
101 4 pfleura2
        END DO
102 4 pfleura2
     END DO
103 4 pfleura2
104 4 pfleura2
     if (debug) WRITE(*,*) "Wy=",Wy
105 4 pfleura2
106 4 pfleura2
     ! We calculate Num=s(sT)
107 4 pfleura2
     Num=0.
108 4 pfleura2
     DO I=1,Nfree
109 4 pfleura2
        DO J=1,Nfree
110 4 pfleura2
           Num(I,J)=ds(i)*Ds(j)
111 4 pfleura2
        END DO
112 4 pfleura2
     END DO
113 4 pfleura2
114 4 pfleura2
     if (debug) THEN
115 4 pfleura2
        WRITE(*,*) "s(sT)"
116 4 pfleura2
        DO I=1,NFree
117 4 pfleura2
           WRITE(*,*) Num(I,:)
118 4 pfleura2
        END DO
119 4 pfleura2
     END if
120 4 pfleura2
121 4 pfleura2
     ! We calculate Num2=Wy(WyT)
122 4 pfleura2
     Num2=0
123 4 pfleura2
     Do I=1,NFree
124 4 pfleura2
        DO J=1,NFree
125 4 pfleura2
             Num2(I,J)=Wy(i)*Wy(j)
126 4 pfleura2
        END DO
127 4 pfleura2
     END DO
128 4 pfleura2
129 4 pfleura2
     if (debug) THEN
130 4 pfleura2
        WRITE(*,*) "Wy(WyT)"
131 4 pfleura2
        DO I=1,NFree
132 4 pfleura2
           WRITE(*,*) Num2(I,:)
133 4 pfleura2
        END DO
134 4 pfleura2
     END if
135 4 pfleura2
136 4 pfleura2
137 4 pfleura2
! we calculate den=(sT)y
138 4 pfleura2
     den=DOT_PRODUCT(ds,dgrad)
139 4 pfleura2
140 4 pfleura2
! we calculate den2=(yT)Wy
141 4 pfleura2
     den2=DOT_PRODUCT(dgrad,Wy)
142 4 pfleura2
143 4 pfleura2
     if (debug) THEN
144 4 pfleura2
        WRITE(*,*) "(sT)y,(yT)Wy ",den,den2
145 4 pfleura2
     END if
146 4 pfleura2
147 4 pfleura2
148 4 pfleura2
     !We add everything
149 4 pfleura2
     Hup=Num/den-Num2/den2
150 4 pfleura2
     Hess=HessOld+Hup
151 4 pfleura2
152 4 pfleura2
     if (debug) THEN
153 4 pfleura2
        WRITE(*,*) 'DBG Hinvup_DFP Hup'
154 4 pfleura2
        Idx=min(12,Nfree)
155 4 pfleura2
        DO I=1,NFree
156 4 pfleura2
           WRITE(*,'(12(1X,F8.4))') Hup(I,1:Idx)
157 4 pfleura2
        END DO
158 4 pfleura2
        WRITE(*,*) 'DBG Hinvup_DFP Hess new'
159 4 pfleura2
        Idx=min(12,Nfree)
160 4 pfleura2
        DO I=1,NFree
161 4 pfleura2
           WRITE(*,'(12(1X,F8.4))') Hess(I,1:Idx)
162 4 pfleura2
        END DO
163 4 pfleura2
     END IF
164 4 pfleura2
165 4 pfleura2
  ELSE
166 4 pfleura2
     Hess=HessOld
167 4 pfleura2
  END IF
168 4 pfleura2
169 4 pfleura2
  DEALLOCATE(HessOld, Wy, Hup, Num, Num2 )
170 4 pfleura2
171 4 pfleura2
  if (debug) WRITE(*,*) "=========================== Hinvup_DFP Over ===================="
172 4 pfleura2
173 4 pfleura2
END SUBROUTINE Hinvup_DFP