CONOPT
Loading...
Searching...
No Matches
minimax07.f90
Go to the documentation of this file.
1!> @file minimax07.f90
2!! @ingroup FORT1THREAD_EXAMPLES
3!!
4!!
5!! Minimax07 is a minimax model with multiple minimax variables
6!! and some side constraints.
7!!
8!! Compared to Minimax06 we have added higher order terms on z(k)
9!! so the limits on res are
10!! \f{eqnarray*}{
11!! k = 1: && z_1 \\
12!! k = 2: && z_1^2 + z_2 \\
13!! k = 3: && z_2^2 + z_3
14!! \f}
15!!
16!! We solve the following nonlinear minimax model:
17!!
18!! \f[
19!! \min \sum_k \max_{i} |res_{ik}| \\
20!! \sum_{j} (a_{ijk}x_{jk} + b_{ijk}x_{jk}^2) + res_{ik} = obs_{ik} \quad \forall i, k \\
21!! \sum_{j} x_{jk} \leq 1 \quad \forall k
22!! \f]
23!!
24!! where \f$a\f$, \f$b\f$, and \f$obs\f$ are known data, and \f$res\f$ and \f$x\f$ are the
25!! variables of the model.
26!!
27!! To get a model with continuous derivatives we introduce an
28!! objective variable, \f$z\f$, and the constraints
29!! \f[
30!! res_{ik} - z_k \leq 0 \\
31!! -res_{ik} - z_k \leq 0
32!! \f]
33!! Note opposite sign from Minimax01
34!! and minimize \f$\sum_k z_k\f$
35!!
36!!
37!! For more information about the individual callbacks, please have a look at the source code.
38
39#if defined(_WIN32) && !defined(_WIN64)
40#define dec_directives_win32
41#endif
42
43REAL FUNCTION rndx( )
44!
45! Defines a pseudo random number between 0 and 1
46!
47 IMPLICIT NONE
48
49 Integer, save :: seed = 12359
50
51 seed = mod(seed*1027+25,1048576)
52 rndx = float(seed)/float(1048576)
53
54END FUNCTION rndx
55
56subroutine defdata
57!
58! Define values for A, B, and Obs
59!
60 Use lsq_7k
61 IMPLICIT NONE
62
63 Integer :: i, j, k
64 real*8, Parameter :: xtarg = -1.0
65 real*8, Parameter :: noise = 1.0
66 Real, External :: Rndx
67 real*8 :: o
68
69 do i = 1, nobs
70 o = 0.d0
71 do k = 1, dimk
72 do j = 1, dimx
73 a(i,k,j) = rndx()
74 b(i,k,j) = rndx()
75 o = o + a(i,k,j) * xtarg + b(i,k,j) * xtarg**2
76 enddo
77 obs(i,k) = o + noise * rndx()
78 enddo
79 enddo
80
81end subroutine defdata
82!
83! Main program.
84!
85!> Main program. A simple setup and call of CONOPT
86!!
87Program minimax07
88
90 Use conopt
91 Use lsq_7k
92 implicit None
93!
94! Declare the user callback routines as Integer, External:
95!
96 Integer, External :: mm_readmatrix ! Mandatory Matrix definition routine defined below
97 Integer, External :: mm_fdeval ! Function and Derivative evaluation routine
98 ! needed a nonlinear model.
99 Integer, External :: std_status ! Standard callback for displaying solution status
100 Integer, External :: std_solution ! Standard callback for displaying solution values
101 Integer, External :: std_message ! Standard callback for managing messages
102 Integer, External :: std_errmsg ! Standard callback for managing error messages
103#ifdef dec_directives_win32
104!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: MM_ReadMatrix
105!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: MM_FDEval
106!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Status
107!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Solution
108!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Message
109!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_ErrMsg
110#endif
111!
112! Control vector
113!
114 INTEGER, Dimension(:), Pointer :: cntvect
115 INTEGER :: coi_error
116
117 call startup
118!
119! Define data
120!
121 Call defdata
122!
123! Create and initialize a Control Vector
124!
125 coi_error = coi_create( cntvect )
126!
127! Tell CONOPT about the size of the model by populating the Control Vector:
128!
129 coi_error = max( coi_error, coidef_numvar( cntvect, nobs*dimk + dimx*dimk + dimk ) )
130 coi_error = max( coi_error, coidef_numcon( cntvect, 3*nobs*dimk+dimk+1 ) )
131 coi_error = max( coi_error, coidef_numnz( cntvect, nobs * dimx * dimk + 5* nobs*dimk + dimk + dimk*dimx + 4*nobs ) )
132 coi_error = max( coi_error, coidef_numnlnz( cntvect, nobs * dimx * dimk + 4*nobs ) )
133 coi_error = max( coi_error, coidef_optdir( cntvect, -1 ) ) ! Minimize
134 coi_error = max( coi_error, coidef_objcon( cntvect, 3*nobs*dimk + dimk+ 1 ) ) ! Objective is last constraint
135 coi_error = max( coi_error, coidef_optfile( cntvect, 'Minimax07.opt' ) )
136!
137! Tell CONOPT about the callback routines:
138!
139 coi_error = max( coi_error, coidef_readmatrix( cntvect, mm_readmatrix ) )
140 coi_error = max( coi_error, coidef_fdeval( cntvect, mm_fdeval ) )
141 coi_error = max( coi_error, coidef_status( cntvect, std_status ) )
142 coi_error = max( coi_error, coidef_solution( cntvect, std_solution ) )
143 coi_error = max( coi_error, coidef_message( cntvect, std_message ) )
144 coi_error = max( coi_error, coidef_errmsg( cntvect, std_errmsg ) )
145 coi_error = max( coi_error, coidef_debugfv( cntvect, 0 ) ) ! Debug Fdeval on or off
146
147#if defined(CONOPT_LICENSE_INT_1) && defined(CONOPT_LICENSE_INT_2) && defined(CONOPT_LICENSE_INT_3) && defined(CONOPT_LICENSE_TEXT)
148 coi_error = max( coi_error, coidef_license( cntvect, conopt_license_int_1, conopt_license_int_2, conopt_license_int_3, conopt_license_text) )
149#endif
150
151 If ( coi_error .ne. 0 ) THEN
152 write(*,*)
153 write(*,*) '**** Fatal Error while loading CONOPT Callback routines.'
154 write(*,*)
155 call flog( "Skipping Solve due to setup errors", 1 )
156 ENDIF
157!
158! Save the solution so we can check the duals:
159!
160 do_allocate = .true.
161!
162! Start CONOPT:
163!
164 coi_error = coi_solve( cntvect )
165
166 write(*,*)
167 write(*,*) 'End of Minimax07 example 1. Return code=',coi_error
168
169 If ( coi_error /= 0 ) then
170 call flog( "Errors encountered during solution", 1 )
171 elseif ( stacalls == 0 .or. solcalls == 0 ) then
172 call flog( "Status or Solution routine was not called", 1 )
173 elseif ( .not. ( sstat == 1 .and. mstat == 2 ) ) then
174 call flog( "Solver or Model status was not as expected (1,2)", 1 )
175! elseif ( abs( OBJ - 19.44434311d0 ) > 1.d-7 ) then
176! call flog( "Incorrect objective returned", 1 )
177 Else
178 Call checkdual( 'Minimax07', minimize )
179 endif
180
181 if ( coi_free(cntvect) /= 0 ) call flog( "Error while freeing control vector",1)
182
183 call flog( "Successful Solve", 0 )
184
185End Program minimax07
186!
187! ============================================================================
188! Define information about the model:
189!
190
191!> Define information about the model
192!!
193!! @include{doc} readMatrix_params.dox
194Integer Function mm_readmatrix( lower, curr, upper, vsta, type, rhs, esta, &
195 colsta, rowno, value, nlflag, n, m, nz, &
196 usrmem )
197#ifdef dec_directives_win32
198!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: MM_ReadMatrix
199#endif
200 Use lsq_7k
201 implicit none
202 integer, intent (in) :: n ! number of variables
203 integer, intent (in) :: m ! number of constraints
204 integer, intent (in) :: nz ! number of nonzeros
205 real*8, intent (in out), dimension(n) :: lower ! vector of lower bounds
206 real*8, intent (in out), dimension(n) :: curr ! vector of initial values
207 real*8, intent (in out), dimension(n) :: upper ! vector of upper bounds
208 integer, intent (in out), dimension(n) :: vsta ! vector of initial variable status
209 ! (not defined here)
210 integer, intent (out), dimension(m) :: type ! vector of equation types
211 integer, intent (in out), dimension(m) :: esta ! vector of initial equation status
212 ! (not defined here)
213 real*8, intent (in out), dimension(m) :: rhs ! vector of right hand sides
214 integer, intent (in out), dimension(n+1) :: colsta ! vector with start of column indices
215 integer, intent (out), dimension(nz) :: rowno ! vector of row numbers
216 integer, intent (in out), dimension(nz) :: nlflag ! vector of nonlinearity flags
217 real*8, intent (in out), dimension(nz) :: value ! vector of matrix values
218 real*8 usrmem(*) ! optional user memory
219
220 Integer :: i, j, k, l, nzc
221!
222! Information about Variables:
223! Default: Lower = -Inf, Curr = 0, and Upper = +inf.
224! Default: the status information in Vsta is not used.
225!
226 l = 0
227 do i = 1, dimx
228 do k = 1, dimk
229 l = l + 1
230 curr(l) = +0.9d0 ! Make the initial point infeasible to the sum(j,(x(j,k)) =L= 1;
231 lower(l) = -1.0d0
232 enddo
233 enddo
234!
235! Information about Constraints:
236! Default: Rhs = 0
237! Default: the status information in Esta and the function
238! value in FV are not used.
239! Default: Type: There is no default.
240! 0 = Equality,
241! 1 = Greater than or equal,
242! 2 = Less than or equal,
243! 3 = Non binding.
244!
245! Constraints 1 to Nobs*Dimk:
246! Rhs = Obs(i,k) and type Equality
247!
248 l = 0
249 do i = 1, nobs
250 do k = 1, dimk
251 l = l + 1
252 rhs(l) = obs(i,k)
253 type(l) = 0
254 enddo
255 enddo
256!
257! Constraint Nobs*Dimk+1 to 2*Nobs*Dimk
258! Rhs = 0 (default) and type Less than or equal
259!
260 do i = nobs*dimk+1, 2*nobs*dimk
261 type(i) = 2
262 enddo
263!
264! Constraint 2*Nobs*Dimk+1 to 3*Nobs*Dimk
265! Rhs = 0 (default) and type Greater than or equal
266!
267 do i = 2*nobs*dimk+1, 3*nobs*dimk
268 type(i) = 1
269 enddo
270!
271! Constraint 3*Nobs*Dimk+1 to 3*Nobs*Dimk+Dimk
272! Rhs = 1 and type Less than or equal
273!
274 do i = 3*nobs*dimk+1, 3*nobs*dimk+dimk
275 rhs(i) = 1.0d0
276 type(i) = 2
277 enddo
278!
279! Objective, type Nonbinding
280!
281 type(3*nobs*dimk+dimk+1) = 3
282!
283! Information about the Jacobian. CONOPT expects a columnwise
284! representation in Rowno, Value, Nlflag and Colsta.
285!
286! Colsta = Start of column indices (No Defaults):
287! Rowno = Row indices
288! Value = Value of derivative (by default only linear
289! derivatives are used)
290! Nlflag = 0 for linear and 1 for nonlinear derivative
291! (not needed for completely linear models)
292!
293!
294! Indices
295! x(j,k) res(i,k) z(k)
296! i,k: NL L=1
297! i,k: L=1 nl and L=-1
298! i,k: L=1 nl and L=+1
299! k L=1
300! obj L=+1
301!
302! We map (i,k) -> k+DimK*(i-1)
303! and (j,k) -> k+DimK*(j-1)
304!
305 nzc = 1
306 do j = 1, dimx ! x(j,k)
307 do k = 1, dimk
308 l = k+dimk*(j-1)
309 colsta(l) = nzc
310 do i = 1, nobs
311 rowno(nzc) = k+dimk*(i-1)
312 nlflag(nzc) = 1
313 nzc = nzc + 1
314 enddo
315 rowno(nzc) = 3*nobs*dimk+k
316 nlflag(nzc) = 0
317 value(nzc) = 1.d0
318 nzc = nzc + 1
319 enddo
320 enddo
321 do i = 1, nobs ! res(i,k)
322 do k = 1, dimk
323 colsta(dimx*dimk+k+dimk*(i-1)) = nzc
324 rowno(nzc) = k+dimk*(i-1)
325 nlflag(nzc) = 0
326 value(nzc) = 1.d0
327 nzc = nzc + 1
328 rowno(nzc) = nobs*dimk+k+dimk*(i-1)
329 nlflag(nzc) = 0
330 value(nzc) = 1.d0
331 nzc = nzc + 1
332 rowno(nzc) = 2*nobs*dimk+k+dimk*(i-1)
333 nlflag(nzc) = 0
334 value(nzc) = 1.d0
335 nzc = nzc + 1
336 enddo
337 enddo
338 do k = 1, dimk ! z(k)
339 colsta(dimx*dimk+nobs*dimk+k) = nzc
340 do i = 1, nobs
341 rowno(nzc) = nobs*dimk+k+dimk*(i-1)
342 nlflag(nzc) = 0
343 value(nzc) = -1.d0
344 nzc = nzc + 1
345 rowno(nzc) = 2*nobs*dimk+k+dimk*(i-1)
346 nlflag(nzc) = 0
347 value(nzc) = +1.d0
348 nzc = nzc + 1
349 enddo
350 if ( k < dimk ) then ! also nonlinear terms for z(k-1)
351 do i = 1, nobs
352 rowno(nzc) = nobs*dimk+k+1+dimk*(i-1)
353 nlflag(nzc) = 1
354 nzc = nzc + 1
355 rowno(nzc) = 2*nobs*dimk+k+1+dimk*(i-1)
356 nlflag(nzc) = 1
357 nzc = nzc + 1
358 enddo
359 endif
360 rowno(nzc) = 3*nobs*dimk+dimk+1 ! Objective
361 nlflag(nzc) = 0
362 value(nzc) = +1.d0
363 nzc = nzc + 1
364 enddo
365 colsta(dimx*dimk+nobs*dimk+dimk+1) = nzc
367 mm_readmatrix = 0 ! Return value means OK
368
369end Function mm_readmatrix
370!
371!==========================================================================
372! Compute nonlinear terms and non-constant Jacobian elements
373!
374
375!> Compute nonlinear terms and non-constant Jacobian elements
376!!
377!! @include{doc} fdeval_params.dox
378Integer Function mm_fdeval( x, g, jac, rowno, jcnm, mode, ignerr, errcnt, &
379 n, nzc, thread, usrmem )
380#ifdef dec_directives_win32
381!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: MM_FDEval
382#endif
383 use lsq_7k
384 implicit none
385 integer, intent (in) :: n ! number of variables
386 integer, intent (in) :: rowno ! number of the row to be evaluated
387 integer, intent (in) :: nzc ! number of nonzceros in this row
388 real*8, intent (in), dimension(n) :: x ! vector of current solution values
389 real*8, intent (in out) :: g ! constraint value
390 real*8, intent (in out), dimension(n) :: jac ! vector of derivatives for current constraint
391 integer, intent (in), dimension(nzc) :: jcnm ! list of variables that appear nonlinearly
392 ! in this row. Ffor information only.
393 integer, intent (in) :: mode ! evaluation mode: 1 = function value
394 ! 2 = derivatives, 3 = both
395 integer, intent (in) :: ignerr ! if 1 then errors can be ignored as long
396 ! as errcnt is incremented
397 integer, intent (in out) :: errcnt ! error counter to be incremented in case
398 ! of function evaluation errors.
399 integer, intent (in) :: thread
400 real*8 usrmem(*) ! optional user memory
401
402 integer :: i,j,k,l
403 real*8 :: s
404
405 mm_fdeval = 0
406 if ( rowno .le. nobs*dimk ) then
407!
408! We map (i,k): rowno -> k+DimK*(i-1) so
409! i = (Dimk+rowno-1))/Dimk
410! k = rowno-Dimk*(i-1)
411! and (j,k) -> k+DimK*(j-1)
412! Mode = 1 or 3: Function value - x-part only
413!
414 i = (dimk+rowno-1)/dimk
415 k = rowno-dimk*(i-1)
416 if ( mode .eq. 1 .or. mode .eq. 3 ) then
417 s = 0.d0
418 do j = 1, dimx
419 l = k+dimk*(j-1)
420 s = s + a(i,k,j)*x(l) + b(i,k,j)*x(l)**2
421 enddo
422 g = s
423 endif
424!
425! Mode = 2 or 3: Derivatives
426!
427 if ( mode .eq. 2 .or. mode .eq. 3 ) then
428 do j = 1, dimx
429 l = k+dimk*(j-1)
430 jac(l) = a(i,k,j) + 2.d0*b(i,k,j)*x(l)
431 enddo
432 endif
433 Else if ( rowno .le. 2*nobs*dimk ) then
434 i = (dimk+rowno-nobs*dimk-1)/dimk
435 k = rowno-nobs*dimk-dimk*(i-1)-1
436 if ( mode .eq. 1 .or. mode .eq. 3 ) then
437 g = x(nobs*dimk + dimx*dimk+k )**2
438 endif
439 if ( mode .eq. 2 .or. mode .eq. 3 ) then
440 jac(nobs*dimk + dimx*dimk+k) = 2.0d0*x(nobs*dimk + dimx*dimk+k )
441 endif
442 Else if ( rowno .le. 3*nobs*dimk ) then
443 i = (dimk+rowno-2*nobs*dimk-1)/dimk
444 k = rowno-2*nobs*dimk-dimk*(i-1)-1
445 if ( mode .eq. 1 .or. mode .eq. 3 ) then
446 g = x(nobs*dimk + dimx*dimk+k )**2
447 endif
448 if ( mode .eq. 2 .or. mode .eq. 3 ) then
449 jac(nobs*dimk + dimx*dimk+k) = 2.0d0*x(nobs*dimk + dimx*dimk+k )
450 endif
451 Else
452 mm_fdeval = 1 ! Illegal row number
453 endif
454
455end Function mm_fdeval
integer function std_solution(xval, xmar, xbas, xsta, yval, ymar, ybas, ysta, n, m, usrmem)
Definition comdecl.f90:132
integer function std_status(modsta, solsta, iter, objval, usrmem)
Definition comdecl.f90:88
subroutine checkdual(case, minmax)
Definition comdecl.f90:394
integer function std_message(smsg, dmsg, nmsg, llen, usrmem, msgv)
Definition comdecl.f90:205
integer function std_errmsg(rowno, colno, posno, msglen, usrmem, msg)
Definition comdecl.f90:248
integer(c_int) function coidef_message(cntvect, coi_message)
define callback routine for handling messages returned during the solution process.
Definition conopt.f90:1265
integer(c_int) function coidef_solution(cntvect, coi_solution)
define callback routine for returning the final solution values.
Definition conopt.f90:1238
integer(c_int) function coidef_status(cntvect, coi_status)
define callback routine for returning the completion status.
Definition conopt.f90:1212
integer(c_int) function coidef_readmatrix(cntvect, coi_readmatrix)
define callback routine for providing the matrix data to CONOPT.
Definition conopt.f90:1111
integer(c_int) function coidef_errmsg(cntvect, coi_errmsg)
define callback routine for returning error messages for row, column or Jacobian elements.
Definition conopt.f90:1291
integer(c_int) function coidef_fdeval(cntvect, coi_fdeval)
define callback routine for performing function and derivative evaluations.
Definition conopt.f90:1135
integer(c_int) function coidef_optfile(cntvect, optfile)
define callback routine for defining an options file.
Definition conopt.f90:928
integer(c_int) function coidef_license(cntvect, licint1, licint2, licint3, licstring)
define the License Information.
Definition conopt.f90:293
integer(c_int) function coidef_debugfv(cntvect, debugfv)
turn Debugging of FDEval on and off.
Definition conopt.f90:387
integer(c_int) function coidef_numvar(cntvect, numvar)
defines the number of variables in the model.
Definition conopt.f90:97
integer(c_int) function coidef_numcon(cntvect, numcon)
defines the number of constraints in the model.
Definition conopt.f90:121
integer(c_int) function coidef_numnlnz(cntvect, numnlnz)
defines the Number of Nonlinear Nonzeros.
Definition conopt.f90:167
integer(c_int) function coidef_optdir(cntvect, optdir)
defines the Optimization Direction.
Definition conopt.f90:213
integer(c_int) function coidef_numnz(cntvect, numnz)
defines the number of nonzero elements in the Jacobian.
Definition conopt.f90:144
integer(c_int) function coidef_objcon(cntvect, objcon)
defines the Objective Constraint.
Definition conopt.f90:239
integer(c_int) function coi_create(cntvect)
initializes CONOPT and creates the control vector.
Definition conopt.f90:1726
integer(c_int) function coi_free(cntvect)
frees the control vector.
Definition conopt.f90:1749
integer(c_int) function coi_solve(cntvect)
method for starting the solving process of CONOPT.
Definition conopt.f90:1625
#define dimx
Definition leastsq.c:16
#define nobs
Definition leastsq.c:15
void defdata()
Defines the data for the problem.
Definition leastsq.c:35
float rndx()
Defines a pseudo random number between 0 and 1.
Definition leastsq.c:22
program minimax07
Main program. A simple setup and call of CONOPT.
Definition minimax07.f90:89
integer function mm_fdeval(x, g, jac, rowno, jcnm, mode, ignerr, errcnt, n, nz, thread, usrmem)
Compute nonlinear terms and non-constant Jacobian elements.
Definition minimax.f90:289
integer function mm_readmatrix(lower, curr, upper, vsta, type, rhs, esta, colsta, rowno, value, nlflag, n, m, nz, usrmem)
Define information about the model.
Definition minimax.f90:171
integer solcalls
Definition comdecl.f90:15
integer sstat
Definition comdecl.f90:18
integer, parameter minimize
Definition comdecl.f90:31
integer stacalls
Definition comdecl.f90:14
subroutine flog(msg, code)
Definition comdecl.f90:62
logical do_allocate
Definition comdecl.f90:27
integer mstat
Definition comdecl.f90:17
subroutine startup
Definition comdecl.f90:41