Statistiques
| Révision :

root / src / Hupdate_MS.f90 @ 7

Historique | Voir | Annoter | Télécharger (2,99 ko)

1 4 pfleura2
! Hessian - or its inverse - update
2 4 pfleura2
! We use the Murtagh-Sargent update, also called Symmetric Rank 1
3 4 pfleura2
!
4 4 pfleura2
! input:
5 4 pfleura2
!  - nfree: number of coordinates
6 4 pfleura2
!  - ds: GeomOld-Geom (expressed in the optimization coord.)
7 4 pfleura2
!  - dgrad: GradOld-Grad  (expressed in the optimization coord.)
8 4 pfleura2
!
9 4 pfleura2
!  input/output:
10 4 pfleura2
!  - Hess: old Hessian in input, replaced by updated Hessian on output
11 4 pfleura2
!             (or inverse Hessian)
12 4 pfleura2
!
13 4 pfleura2
!
14 4 pfleura2
!!!!!!!!!!!!!!!!!!!!!!
15 4 pfleura2
! The update formula for the Hessian is:
16 4 pfleura2
! (following Fletcher, approximate Hessian is denoted by B)
17 4 pfleura2
! B(k+1)=B+[(y-Bs){(y-Bs)T}]/[{(y-Bs)T}s]
18 4 pfleura2
!
19 4 pfleura2
! it is self dual, ie for the inverse Hessian, denote by H:
20 4 pfleura2
! H(k+1)=H+[(s-Hy){(s-Hy)T}]/[{(s-Hy)T}y]
21 4 pfleura2
!
22 4 pfleura2
!
23 4 pfleura2
! We decompose the computation in two steps:
24 4 pfleura2
! first we compute the update, and then we add it to Hess to get the
25 4 pfleura2
! new Hessian.
26 4 pfleura2
! This allows us to introduce a scaling factor if needed later.
27 4 pfleura2
!
28 4 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
29 1 equemene
30 1 equemene
SUBROUTINE Hupdate_MS(Nfree,ds,dgrad,Hess)
31 1 equemene
32 1 equemene
  IMPLICIT NONE
33 1 equemene
34 1 equemene
  INTEGER, PARAMETER :: KINT=KIND(1)
35 1 equemene
  INTEGER, PARAMETER :: KREAL=KIND(1.D0)
36 1 equemene
37 1 equemene
  INTEGER(KINT), INTENT(IN) :: NFREE
38 1 equemene
  REAL(KREAL), INTENT(INOUT) :: Hess(Nfree,Nfree)
39 1 equemene
  REAL(KREAL), INTENT(IN) :: ds(Nfree)
40 1 equemene
  REAL(KREAL), INTENT(IN) :: dGrad(Nfree)
41 1 equemene
42 1 equemene
43 1 equemene
  REAL(KREAL), ALLOCATABLE  :: HessOld(:,:) , HupMS(:,:)
44 1 equemene
  REAL(KREAL), ALLOCATABLE  :: Hup(:,:)
45 1 equemene
  REAL(KREAL), ALLOCATABLE  :: HupInt(:)
46 1 equemene
  REAL(KREAL), ALLOCATABLE  :: HS(:), Num(:,:)
47 1 equemene
  REAL(KREAL) :: Phi, Num3, Den, Den2,NormDS
48 1 equemene
  CHARACTER(120) :: fmt,fmt2,Line
49 1 equemene
  INTEGER(KINT) :: i,j, idx
50 1 equemene
51 4 pfleura2
  LOGICAL :: debug
52 1 equemene
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
62 4 pfleura2
63 4 pfleura2
64 1 equemene
  debug=valid("Hupdate").OR.Valid("Hupdate_MS")
65 1 equemene
66 1 equemene
  if (debug) Call Header("Entering Hupdate_MS")
67 1 equemene
68 4 pfleura2
  ALLOCATE(HessOld(nfree,nfree),  &
69 1 equemene
       Hup(nfree,nfree), &
70 1 equemene
       HupInt(nfree), HS(nfree),  &
71 1 equemene
       Num(nfree,nfree))
72 1 equemene
73 1 equemene
  HessOld=Hess
74 1 equemene
75 1 equemene
  if (debug) THEN
76 1 equemene
     WRITE(*,*) 'DBG Hupdate HessOld'
77 1 equemene
     Idx=min(12,Nfree)
78 1 equemene
     DO I=1,NFree
79 1 equemene
        WRITE(*,'(12(1X,F8.4))') HessOld(I,1:Idx)
80 1 equemene
     END DO
81 1 equemene
     WRITE(*,*) 'DBG Hupdate ds'
82 1 equemene
     WRITE(*,'(12(1X,F8.4))') ds(1:Idx)
83 1 equemene
     WRITE(*,*) 'DBG Hupdate dGrad'
84 1 equemene
     WRITE(*,'(12(1X,F8.4))') dGrad(1:Idx)
85 1 equemene
  END IF
86 1 equemene
87 1 equemene
  NormDS=sqrt(DOT_PRODUCT(DS,DS))
88 1 equemene
  if (NormDS>=1e-6) THEN
89 1 equemene
90 1 equemene
     HS=0
91 1 equemene
     DO I=1,nfree
92 1 equemene
        DO J=1,nfree
93 1 equemene
           HS(I)=HS(I)+HessOld(i,j)*Ds(j)
94 1 equemene
        END DO
95 1 equemene
     END DO
96 4 pfleura2
97 4 pfleura2
     if (debug) WRITE(*,*) "HS:",HS
98 1 equemene
     HupInt=DGrad-HS
99 1 equemene
100 1 equemene
     ! WE calculate the MS update
101 1 equemene
     Num=0.
102 1 equemene
     Den=0.
103 1 equemene
     DO I=1,nfree
104 1 equemene
        DO J=1,nfree
105 1 equemene
           Num(I,J)=HUpInt(i)*HupInt(j)
106 1 equemene
        END DO
107 1 equemene
        Den=Den+Hupint(i)*Ds(i)
108 1 equemene
     END DO
109 4 pfleura2
     if (debug) WRITE(*,*) "Den:",Den,1./Den
110 1 equemene
111 4 pfleura2
     Hup=Num/Den
112 1 equemene
113 4 pfleura2
     Hess=HessOld+Hup
114 1 equemene
  ELSE
115 1 equemene
     Hess=HessOld
116 1 equemene
  END IF
117 1 equemene
  !     WRITE(*,*) 'New hess'
118 1 equemene
  !     DO I=1,nfree
119 1 equemene
  !        WRITE(*,fmt) Hess(i,:)
120 1 equemene
  !     END DO
121 1 equemene
122 4 pfleura2
  DEALLOCATE(HessOld,Hup, HupInt, HS, Num )
123 1 equemene
124 1 equemene
  if (debug) Call Header("Hupdate_MS Over")
125 1 equemene
126 1 equemene
END SUBROUTINE Hupdate_MS