Skip to content

Commit e35562f

Browse files
Merge pull request #18 from esa/infinite-opt-loop
Infinite opt loop
2 parents 7068f95 + 39fae00 commit e35562f

File tree

8 files changed

+96
-54
lines changed

8 files changed

+96
-54
lines changed

CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ message(STATUS "System name: ${CMAKE_SYSTEM_NAME}")
1212
# compiler setup
1313

1414
enable_language(Fortran)
15-
# Force debug flags for Fortran, including preprocessed .F files
16-
# set(CMAKE_Fortran_FLAGS_DEBUG "-g -O0" CACHE STRING "" FORCE)
17-
# set(CMAKE_Fortran_FLAGS "-g -O0" CACHE STRING "" FORCE)
1815

1916
set(CMAKE_CXX_STANDARD 11)
2017
set(CMAKE_CXX_STANDARD_REQUIRED ON)

pyoptgra/core/ogcorr.F

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ SUBROUTINE OGCORR (VARACC, FINISH, TOTERR, NORERR, CALVAL, CALDER)
159159
ENDIF
160160
NUMACT = 0
161161
CONACT = 0
162-
CONRED(1:NUMCON+1,:) = CONDER(1:NUMCON+1,:)
162+
CONRED(1:NUMCON+1,:) = CONDER(1:NUMCON+1,:) ! CONRED=constraint gradient matrix (scaled)
163163
CONRED( NUMCON+2,:) = VARDIR
164164
C ----------------------------------------------------------------------
165165
C CHECK CONSTRAINTS

pyoptgra/core/ogeval.F

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
SUBROUTINE OGEVAL (VALVAR, VALCON, DERVAR, DERCON, CALVAL, CALDER)
22
C ======================================================================
33
C COMPUTES SCALED CONTRAINTS+MERIT AND DERIVATIVES
4-
C FROM SCALED VARIABLES
4+
C FROM SCALED VARIABLES
55
C ======================================================================
6+
C INP | VALVAR(NUMVAR) | R*8 | VARIABLES VALUE (SCALED, INTERNAL)
7+
C | | | -> VALVAR(VAR) = x_var / VARSCA(VAR)
8+
C ----------------------------------------------------------------------
9+
C I/O | VALCON(NUMCON+1) | R*8 | CONSTRAINTS VALUE (1:NUMCON)
10+
C | | | MERIT VALUE (NUMCON+1)
11+
C | | | -> UNSCALED INSIDE CALVAL/CALDER
12+
C | | | (physical units)
13+
C | | | -> SCALED ON EXIT FROM OGEVAL:
14+
C | | | VALCON(CON) = raw_value / CONSCA(CON)
15+
C ----------------------------------------------------------------------
616
C INP | DERVAR | I*4 | DERIVATIVES COMPUTATION MODE
7-
C | | | -> 0: VALUES ONLY
8-
C | | | -> 1: USER DEFINED
17+
C | | | -> 0: VALUES ONLY (DERCON UNCHANGED)
18+
C | | | -> 1: USER DEFINED (CALL CALDER)
19+
C | | | ->-1: USER DEFINED, SPECIAL MODE
920
C | | | -> 2: NUMERIC WITH DOUBLE DIFFERENCING
1021
C | | | -> 3: NUMERIC WITH SINGLE DIFFERENCING
1122
C ----------------------------------------------------------------------
23+
C OUT | DERCON(NUMCON+1, | R*8 | DERIVATIVES OF SCALED VALCON W.R.T.
24+
C | NUMVAR) | | SCALED VALVAR:
25+
C | | | DERCON(CON,VAR) =
26+
C | | | d(VALCON(CON))/d(VALVAR(VAR))
27+
C | | | -> SET BY CALDER IF DERVAR=1 OR -1
28+
C | | | -> SET BY FINITE DIFF. IF DERVAR=2 OR 3
29+
C | | | -> NOT MODIFIED IF DERVAR=0
30+
C ----------------------------------------------------------------------
1231
C INP | CALVAL | EXT | FUNCTION FOR VALUES
13-
C | | | -> CALVAL (VALVAR, VALCON)
32+
C | | | -> CALVAL (VARVEC, VALCON, IFLAG)
1433
C | | | -> INPUT AND OUTPUT NOT SCALED
1534
C ----------------------------------------------------------------------
1635
C INP | CALDER | EXT | FUNCTION FOR VALUES AND DERIVATIVES
17-
C | | | -> CALDER (VALVAR, VALCON, DERCON)
36+
C | | | -> CALDER (VARVEC, VALCON, DERCON)
1837
C | | | -> INPUT AND OUTPUT NOT SCALED
1938
C ======================================================================
2039
C SUBROUTINES CALLED: CALVAL, CALDER
@@ -92,6 +111,7 @@ SUBROUTINE OGEVAL (VALVAR, VALCON, DERVAR, DERCON, CALVAL, CALDER)
92111
DO VAR = 1, NUMVAR
93112
VARVEC(VAR) = VALVAR(VAR) * VARSCA(VAR)
94113
ENDDO
114+
! TODO: do we need to initialise CONVEC and CONDER with zeros here?
95115
C ======================================================================
96116
C GET RESULTS
97117
C GET DERIVATIVES IF USER DEFINED
@@ -219,7 +239,7 @@ SUBROUTINE OGEVAL (VALVAR, VALCON, DERVAR, DERCON, CALVAL, CALDER)
219239
C ======================================================================
220240
C NO DERIVATIVES
221241
C ----------------------------------------------------------------------
222-
IF (DERVAR .EQ. 0) THEN
242+
IF (DERVAR .EQ. 0) THEN
223243
RETURN
224244
ELSEIF (DERVAR .EQ. 1 .OR. DERVAR .EQ. -1) THEN
225245
CALL CALDER (VARVEC, CONVEC, DERCON)

pyoptgra/core/ogexec.F

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ SUBROUTINE OGEXEC (VALVAR, VALCON, FINOPT, FINITE, CALVAL, CALDER)
5757
CALL OGWRIT (2,"")
5858
CALL OGWRIT (2,"OPTGRA START")
5959
CALL OGWRIT (2,"")
60-
FINOPT = 3
60+
FINOPT = 3 ! initialize with NOT MATCHED & NOT OPTIMAL
6161
ITECOR = 0
6262
ITEOPT = 0
6363
MEAERR = 0D0
@@ -112,15 +112,15 @@ SUBROUTINE OGEXEC (VALVAR, VALCON, FINOPT, FINITE, CALVAL, CALDER)
112112
& (CON,CON=1,NUMCON)
113113
ENDIF
114114
C ======================================================================
115-
1000 CONTINUE
115+
1000 CONTINUE ! main iteration loop
116116
C IF (NUMITE .GE. 52) MATLEV = 3
117117
C IF (NUMITE .GE. 55) MATLEV = 2
118118
C ======================================================================
119119
C NEW ITERATION
120120
C ----------------------------------------------------------------------
121-
IF (NUMITE .GE. CORITE .AND. ITECOR .EQ. 0) THEN
122-
FINOPT = 3
123-
FINITE = NUMITE
121+
IF (NUMITE .GE. CORITE .AND. ITECOR .EQ. 0) THEN ! correction limit reached
122+
FINOPT = 3 ! not matched and not optimal
123+
FINITE = NUMITE ! FINITE=Number of iterations at which termination occurred
124124
CALL OGWRIT (1,"")
125125
WRITE(STR,'("OPTGRA: Converged: not ITERAT=",2I4,2D11.3)')
126126
& NUMITE,MAXITE,CONERR,DESNOR
@@ -132,9 +132,9 @@ SUBROUTINE OGEXEC (VALVAR, VALCON, FINOPT, FINITE, CALVAL, CALDER)
132132
CALL OGEVAL (VARVAL, CONVAL, VARDER, CONDER(1:NUMCON+1,:),
133133
& CALVAL, CALDER)
134134
GOTO 9999
135-
ELSEIF (NUMITE .GE. MAXITE .OR.
135+
ELSEIF (NUMITE .GE. MAXITE .OR. ! Maximum iteration reached or after correction phase
136136
& (NUMITE-ITECOR .GE. OPTITE-1 .AND. ITECOR .NE. 0)) THEN
137-
FINOPT = 2
137+
FINOPT = 2 ! matched, but not optimal
138138
FINITE = ITEOPT
139139
VARVAL = VARCOR
140140
CONVAL = CONCOR
@@ -152,36 +152,37 @@ SUBROUTINE OGEXEC (VALVAR, VALCON, FINOPT, FINITE, CALVAL, CALDER)
152152
GOTO 9999
153153
ENDIF
154154
C ----------------------------------------------------------------------
155-
NUMITE = NUMITE + 1
155+
NUMITE = NUMITE + 1 ! new iteration
156156
C ----------------------------------------------------------------------
157157
CALL OGWRIT (3,"")
158158
WRITE (STR,'("ITERAT=",I5)') NUMITE
159159
CALL OGWRIT (2,STR)
160160
C ======================================================================
161161
C GET VALUES AND GRADIENTS
162162
C ======================================================================
163-
IF (SENOPT .LE. 0) THEN
163+
IF (SENOPT .LE. 0) THEN ! No sensitivity analysis, only optimisation
164164
CALL OGEVAL (VARVAL, CONVAL, VARDER, CONDER(1:NUMCON+1,:),
165165
& CALVAL, CALDER)
166-
ELSEIF (SENOPT .EQ. +1 .OR. SENOPT .EQ. +3) THEN
166+
ELSEIF (SENOPT .EQ. +1 .OR. SENOPT .EQ. +3) THEN ! sens. WITH CONSTRAINT CALCULATION
167167
VARVAL = SENVAR
168168
CALL OGEVAL (VARVAL, CONVAL, 0, CONDER(1:NUMCON+1,:),
169169
& CALVAL, CALDER)
170-
ELSEIF (SENOPT .EQ. +2 .OR. SENOPT .EQ. +4) THEN
170+
ELSEIF (SENOPT .EQ. +2 .OR. SENOPT .EQ. +4) THEN ! sens. WITH CONSTRAINT BIAS
171171
VARVAL = SENVAR
172172
DO CON = 1, NUMCON+1
173173
SCA = CONSCA(CON)
174174
IF (CONTYP(CON) .EQ. -1) SCA = - SCA
175175
CONVAL(CON) = SENCON(CON) - SENDEL(CON) / SCA
176176
ENDDO
177177
ENDIF
178-
IF (SENOPT .EQ. -1) THEN
178+
IF (SENOPT .EQ. -1) THEN ! intialisation of sensitivity analysis
179179
SENVAR = VARVAL
180180
SENCON = CONVAL
181181
ENDIF
182182
C ======================================================================
183+
C Do finite-difference check of provided gradients if VARDER=-1 (documented options are 0,1,2,3)
183184
IF (VARDER .EQ. -1 .AND. SENOPT .LE. 0) THEN
184-
CONRED(1:NUMCON+1,:) = CONDER(1:NUMCON+1,:)
185+
CONRED(1:NUMCON+1,:) = CONDER(1:NUMCON+1,:) ! CONDER=current constraint derivatives
185186
CALL OGEVAL (VARVAL, CONVAL, 2, CONDER(1:NUMCON+1,:),
186187
& CALVAL, CALDER)
187188
WRITE (STR,'("GRADIENT CHECK")')
@@ -219,12 +220,12 @@ SUBROUTINE OGEXEC (VALVAR, VALCON, FINOPT, FINITE, CALVAL, CALDER)
219220
C GOTO 9999
220221
ENDIF
221222
C ======================================================================
222-
SENDER = CONDER
223+
SENDER = CONDER ! SENDER=derivatives for sensitivity analysis???
223224
DO VAR = 1,NUMVAR
224-
IF (VARTYP(VAR) .NE. 1) CYCLE
225+
IF (VARTYP(VAR) .NE. 1) CYCLE ! VARTYP=1 are sensitivity parameters, VARTYP=0 free params
225226
C WRITE (STR,*) "VAR=",VAR,VARVAL(VAR)*VARSCA(VAR)
226227
C CALL OGWRIT (2,STR)
227-
CONDER(1:NUMCON+1,VAR) = 0D0
228+
CONDER(1:NUMCON+1,VAR) = 0D0 ! zero derivatives of free parameters???
228229
ENDDO
229230
C ======================================================================
230231
IF (NUMITE .EQ. 1) THEN
@@ -235,16 +236,16 @@ SUBROUTINE OGEXEC (VALVAR, VALCON, FINOPT, FINITE, CALVAL, CALDER)
235236
VARREF = VARVAL
236237
CONREF = CONVAL
237238
C ======================================================================
238-
VARACC = 0D0
239+
VARACC = 0D0 ! initialise ITERATION SCALED DISTANCE ACCUMULATED
239240
C ======================================================================
240241
COSOLD = COSNEW
241-
COSNEW = CONVAL(NUMCON+1)
242+
COSNEW = CONVAL(NUMCON+1) ! cost function value
242243
CALL OGWRIT (3,"")
243244
WRITE (STR,'("OPTGRA: VALCOS=",D15.8,1X,D15.8)') COSNEW,
244245
&COSNEW-COSOLD
245246
CALL OGWRIT (3,STR)
246247
C ======================================================================
247-
C CORRECTION PART
248+
C CONSTRAINTS CORRECTION PART
248249
C ----------------------------------------------------------------------
249250
CALL OGCORR (VARACC, FINISH, CONERR,NORERR,CALVAL,CALDER)
250251
C ----------------------------------------------------------------------

pyoptgra/core/ogopti.F

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
7777
C WRITE (STR,'("NUMACT = ",I4)') NUMACT
7878
C CALL OGWRIT (3,STR)
7979
NUMCOR = NUMACT
80-
CONCOR = ACTCON
81-
NUMACT = 0
80+
CONCOR = ACTCON ! ACTCON = list of indices of active constraints
81+
NUMACT = 0 ! number of active constraints
8282
CONACT(1:DES) = 0
8383
C DO COR = 1, NUMCOR
8484
C CON = CONCOR(COR)
@@ -89,7 +89,8 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
8989
C CALL OGINCL (CON)
9090
C ENDDO
9191
C ======================================================================
92-
1100 CONTINUE
92+
1100 CONTINUE ! Begin optimisation iteration
93+
9394
C ======================================================================
9495
C VECTOR OF STEEPEST ASCENT
9596
C ----------------------------------------------------------------------
@@ -103,23 +104,23 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
103104
C REMOVE PASSIVE INEQUALITY CONSTRAINTS
104105
C ----------------------------------------------------------------------
105106
DO ACT = NUMACT, 1, -1
106-
CON = ACTCON(ACT)
107-
IF (CONVAL(CON) .LE. 1D0) CYCLE
107+
CON = ACTCON(ACT) ! CON=index of active constraint in CONVAL
108+
IF (CONVAL(CON) .LE. 1D0) CYCLE
108109
NAM = CONSTR(CON)
109110
LEN = CONLEN(CON)
110111
WRITE (STR,'(I4,5X,1X,A)') CON, NAM(1:LEN)
111112
CALL OGWRIT (2,STR)
112-
CALL OGEXCL (ACT)
113-
CONACT(CON) = -1
113+
CALL OGEXCL (ACT) ! Exclude constraint ACT from active set
114+
CONACT(CON) = -1 ! Mark CON as blocked from inclusion in active set
114115
ENDDO
115116
C ----------------------------------------------------------------------
116117
C INCLUDE VIOLATED INEQUALITY CONSTRAINTS AND SELECT PASSIVE ONES
117118
C SELECT PASSIVE INEQUALITY CONSTRAINTS
118119
C ----------------------------------------------------------------------
119120
DO CON = 1, NUMCON
120121
IF (CONTYP(CON) .EQ. -2) CYCLE
121-
IF (CONACT(CON) .GT. 0 ) THEN
122-
ELSEIF (CONTYP(CON) .EQ. 0 ) THEN
122+
IF (CONACT(CON) .GT. 0 ) THEN ! CON is active, CONACT(CON) is the position of CON in active set
123+
ELSEIF (CONTYP(CON) .EQ. 0 ) THEN ! CON in inactive
123124
CONACT(CON) = 0
124125
ELSEIF (CONVAL(CON) .LT. -1D0) THEN
125126
CONACT(CON) = 0
@@ -131,9 +132,9 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
131132
ENDDO
132133
C ======================================================================
133134
NNN = 1
134-
1110 CONTINUE
135+
1110 CONTINUE ! Active set refinement loop
135136
NNN = NNN + 1
136-
IF (NNN .GT. 999) THEN
137+
IF (NNN .GT. 999) THEN ! saveguard active set refinement loop to continue forever
137138
FINISH = 0
138139
WRITE (STR,*) "NNN=",NNN
139140
CALL OGWRIT (2,STR)
@@ -142,16 +143,16 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
142143
C ======================================================================
143144
C DERIVATIVES OF MERIT W.R.T. ACTIVE CONSTRAINTS
144145
C ----------------------------------------------------------------------
145-
CALL OGRIGT (-CONRED(COS,1:NUMACT), COSACT)
146-
DESNOR = DSQRT(SUM(CONRED(COS,NUMACT+1:NUMVAR)**2))
146+
CALL OGRIGT (-CONRED(COS,1:NUMACT), COSACT) ! COSACT=Lagrange multipliers???
147+
DESNOR = DSQRT(SUM(CONRED(COS,NUMACT+1:NUMVAR)**2)) ! norm of cost function gradient
147148
C ----------------------------------------------------------------------
148149
C CONSTRAINT REMOVAL
149150
C ----------------------------------------------------------------------
150151
IND = 0
151152
EXC = -1D-12
152153
MAX = EXC
153154
DO ACT = 1, NUMACT
154-
CON = ACTCON(ACT)
155+
CON = ACTCON(ACT) ! ACT=index in active set, CON=index of constraint
155156
IF (CONTYP(CON) .EQ. 0) CYCLE
156157
VAL = COSACT(ACT)
157158
FAC = DOT_PRODUCT (CONRED(CON,1:NUMVAR),
@@ -163,6 +164,7 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
163164
MAX = VAL
164165
IND = ACT
165166
ENDDO
167+
166168
C ----------------------------------------------------------------------
167169
IF (IND .NE. 0) THEN
168170
CON = ACTCON(IND)
@@ -171,7 +173,7 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
171173
WRITE (STR,'(I4,5X,3(1X,D10.3),1X,A)')
172174
& CON,DESNOR,MAX,VARMAX,NAM(1:LEN)
173175
CALL OGWRIT (3,STR)
174-
CALL OGEXCL (IND)
176+
CALL OGEXCL (IND) ! Exclude constraint IND from active set
175177
GOTO 1110
176178
ENDIF
177179
C ----------------------------------------------------------------------
@@ -279,7 +281,7 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
279281
VAL = DOT_PRODUCT (CONRED(CON,NUMACT+1:NUMVAR),
280282
& CONRED(COS,NUMACT+1:NUMVAR))
281283
IF (VAL .EQ. 0D0) CYCLE
282-
VAL = - CONVAL(CON) / VAL * DESNOR
284+
VAL = - CONVAL(CON) / VAL * DESNOR
283285
IF (VAL .LE. 0D0) CYCLE
284286
IF (VAL .GE. DIS) CYCLE
285287
DIS = VAL
@@ -472,6 +474,20 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
472474
VARDES = THT * DESPRV + BET * VARDIR
473475
DESNOR = DSQRT(SUM(VARDES**2))
474476
C ----------------------------------------------------------------------
477+
C SAFEGUARD: ZERO STEEPEST-ASCENT NORM => TREAT AS CONVERGENCE
478+
C ----------------------------------------------------------------------
479+
! NOTE: otherwise, DESNOR used in denominator later on may cause
480+
! NaN issues
481+
IF (DESNOR .EQ. 0D0) THEN
482+
WRITE(LOGLUP,'("OGOPTI WARN: ZERO SECOND ORDER CORRECTION")')
483+
WRITE(LOGLUP,'(" TREATING AS CONVERGENCE")')
484+
FOLDIS = 0D0
485+
QUACOR = 0D0
486+
COSIMP = 0D0
487+
FINISH = 1
488+
GOTO 9999
489+
ENDIF
490+
C ----------------------------------------------------------------------
475491
C MAXIMUM TRAVEL DISTANCE
476492
C ----------------------------------------------------------------------
477493
DIS = VARMAX
@@ -509,6 +525,7 @@ SUBROUTINE OGOPTI (VARACC, NUMEQU, FINISH, DESNOR, CALVAL)
509525
IF (SENOPT .LE. 0 .OR. NNN .EQ. 1) THEN
510526
FAC = VARSTP / DESNOR
511527
VARVEC = VARREF + VARDES * VARSTP / DESNOR
528+
! TODO: do we need to initialise CONVEC and CONDER with zeros here?
512529
CALL OGEVAL (VARVEC, CONVEC, 0, CONDER, CALVAL, CALVAL)
513530
CONQUA = MATMUL (CONDER(1:COS, 1:NUMVAR),
514531
& VARDES( 1:NUMVAR))

pyoptgra/core/wrapper.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ namespace optgra
288288
ogsopt_(&sensitivity_mode);
289289

290290
int finopt = 0;
291-
int finite = 0;
291+
int finite = 0; // number of iterations at which termination occured
292292
ogexec_(valvar.data(), valcon.data(), &finopt, &finite,
293293
static_callable_store::fitness, static_callable_store::gradient);
294294

0 commit comments

Comments
 (0)