CONOPT
Loading...
Searching...
No Matches
ex01.f90
Go to the documentation of this file.
1!> @file ex01.f90
2!! @ingroup FORT1THREAD_EXAMPLES
3!!
4!!
5!! This is an implementation of the model PORT.GMS (seq 50) in the GAMS
6!! model library. The model is repeated here for easy reference:
7!!
8!!
9!! @verbatim
10!! $TITLE SIMPLE PORTFOLIO MODEL (PORT,SEQ=50)
11!! * THIS SIMPLE PORTFOLIO SELECTION MODEL EXAMINES
12!! * INVESTMENT ALTERNATIVES IN THE BOND MARKET. THE SELECTION
13!! * IS CONSTRAIND BY RATING AND MATURITY CONSIDERATIONS.
14!! *
15!! * REFERENCE: CONTROL DATA CORPORATION, IFPS/OPTIMIM - USERS MANUAL,
16!! * MINNEAPOLIS, 1984.
17!!
18!! SETS B BONDS / MUNICIP-A, MUNICIP-B, CORPORATE, US-SER-E, US-SER-F /
19!! G(B) GROUPING / CORPORATE, US-SER-E, US-SER-F /
20!!
21!! TABLE YDAT(B,*) YIELD DATA
22!!
23!! RATING MATURITY YIELD TAX-RATE
24!! MUNICIP-A 2 9 4.3
25!! MUNICIP-B 5 2 4.5
26!! CORPORATE 2 15 5.4 .5
27!! US-SER-E 1 4 5.0 .5
28!! US-SER-F 1 3 4.4 .5
29!!
30!! VARIABLES INVESTMENT(B)
31!! TINVEST TOTAL INVESTMENT
32!! RETURN
33!! POSITIVE VARIABLE INVESTMENT
34!!
35!! EQUATIONS GROUPMIN MINIMUM INVESTMENT IN GROUP G
36!! RDEF RATING DEFINITION
37!! MDEF MATURITY DEFINITION
38!! IDEF TOTAL RETURN DEFINITION
39!! TDEF TOTAL INVESTMENT DEFINITION ;
40!! $DOUBLE
41!! TINVEST.UP = 10;
42!! GROUPMIN.. SUM(G, INVESTMENT(G)) =G= 4;
43!! RDEF.. SUM(B, YDAT(B,'RATING ')*INVESTMENT(B)) =L= 1.4*TINVEST;
44!! MDEF.. SUM(B, YDAT(B,'MATURITY')*INVESTMENT(B)) =L= 5.0*TINVEST;
45!! TDEF.. TINVEST =E= SUM(B, INVESTMENT(B));
46!! IDEF.. RETURN =E= SUM(B, YDAT(B,'YIELD')/100*(1-YDAT(B,'TAX-RATE'))*INVESTMENT(B));
47!! MODEL PORT / ALL / ; SOLVE PORT MAXIMIZING RETURN USING LP;
48!! @endverbatim
49!!
50!!
51!! For more information about the individual callbacks, please have a look at the source code.
52
53!> Main program. A simple setup and call of CONOPT
54!!
55Program ex01
56!
57! Declare the user callback routines as Integer, External:
58!
59 Use proginfo
60 Use coidef
61 implicit None
62
63 Integer, External :: ex01_readmatrix ! Mandatory Matrix definition routine defined below
64 Integer, External :: std_status ! Standard callback for displaying solution status
65 Integer, External :: ex01_solution ! Specialized callback for displaying solution values
66 Integer, External :: std_message ! Standard callback for managing messages
67 Integer, External :: std_errmsg ! Standard callback for managing error messages
68#if defined(itl)
69!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ex01_ReadMatrix
70!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Status
71!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ex01_Solution
72!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_Message
73!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Std_ErrMsg
74#endif
75!
76! Control vector
77!
78 INTEGER :: numcallback
79 INTEGER, Dimension(:), Pointer :: cntvect
80 INTEGER :: coi_error
81
82 Call startup
83!
84! Create and initialize a Control Vector
85!
86 numcallback = coidef_size()
87 Allocate( cntvect(numcallback) )
88 coi_error = coidef_inifort( cntvect )
89!
90! Tell CONOPT about the size of the model by populating the Control Vector:
91!
92! Number of variables (excl. slacks). 5 Investment, Tinvest, and Return
93! for a total of 7:
94!
95 coi_error = max( coi_error, coidef_numvar( cntvect, 7 ) )
96!
97! Number of equations: Groupmin, Rdef, Mdef, Idef, and Tdef for a total
98! of 5:
99!
100 coi_error = max( coi_error, coidef_numcon( cntvect, 5 ) )
101!
102! Number of nonzeros in the Jacobian. This is more complicated. See the
103! counting in Ex01_ReadMatrix below:
104!
105 coi_error = max( coi_error, coidef_numnz( cntvect,27 ) )
106!
107! Number of nonlinear nonzeros. The model is linear so the number is
108! zero:
109!
110 coi_error = max( coi_error, coidef_numnlnz( cntvect, 0 ) )
111!
112! Optimization direction is Maximize = 1
113!
114 coi_error = max( coi_error, coidef_optdir( cntvect, 1 ) )
115!
116! Objective is variable Return = 7
117!
118 coi_error = max( coi_error, coidef_objvar( cntvect, 7 ) )
119!
120! Define the options file as 'ex01.opt'
121!
122 coi_error = max( coi_error, coidef_optfile( cntvect, 'ex01.opt' ) )
123!
124! Tell CONOPT about the callback routines:
125!
126 coi_error = max( coi_error, coidef_readmatrix( cntvect, ex01_readmatrix ) )
127 coi_error = max( coi_error, coidef_status( cntvect, std_status ) )
128 coi_error = max( coi_error, coidef_solution( cntvect, ex01_solution ) )
129 coi_error = max( coi_error, coidef_message( cntvect, std_message ) )
130 coi_error = max( coi_error, coidef_errmsg( cntvect, std_errmsg ) )
131
132#if defined(LICENSE_INT_1) && defined(LICENSE_INT_2) && defined(LICENSE_INT_3) && defined(LICENSE_TEXT)
133 coi_error = max( coi_error, coidef_license( cntvect, license_int_1, license_int_2, license_int_3, license_text) )
134#endif
135
136 If ( coi_error .ne. 0 ) THEN
137 write(*,*)
138 write(*,*) '**** Fatal Error while loading CONOPT Callback routines.'
139 write(*,*)
140 call flog( "Skipping Solve due to setup errors", 1 )
141 ENDIF
142!
143! Start CONOPT:
144!
145 coi_error = coi_solve( cntvect )
146
147 write(*,*)
148 write(*,*) 'End of example ex01'
149
150 If ( coi_error /= 0 ) then
151 call flog( "Errors encountered during solution", 1 )
152 elseif ( stacalls == 0 .or. solcalls == 0 ) then
153 call flog( "Status or Solution routine was not called", 1 )
154 elseif ( sstat /= 1 .or. mstat /= 1 ) then ! This is an LP model
155 call flog( "Solver and Model Status was not as expected (1,1)", 1 )
156 elseif ( abs( obj-0.298364d0 ) > 0.000001d0 ) then
157 call flog( "Incorrect objective returned", 1 )
158 endif
159
160 if ( coi_free(cntvect) /= 0 ) call flog( "Error while freeing control vector",1)
161
162 call flog( "Successful Solve", 0 )
163
164End Program ex01
165!
166! ============================================================================
167! Define information about the model:
168!
169
170!> Define information about the model
171!!
172!! @include{doc} readMatrix_params.dox
173Integer Function ex01_readmatrix( lower, curr, upper, vsta, type, rhs, esta, &
174 colsta, rowno, value, nlflag, n, m, nz, usrmem )
175#if defined(itl)
176!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ex01_ReadMatrix
177#endif
178 implicit none
179 integer, intent (in) :: n ! number of variables
180 integer, intent (in) :: m ! number of constraints
181 integer, intent (in) :: nz ! number of nonzeros
182 real*8, intent (in out), dimension(n) :: lower ! vector of lower bounds
183 real*8, intent (in out), dimension(n) :: curr ! vector of initial values
184 real*8, intent (in out), dimension(n) :: upper ! vector of upper bounds
185 integer, intent (in out), dimension(n) :: vsta ! vector of initial variable status
186 ! (not defined here)
187 integer, intent (out), dimension(m) :: type ! vector of equation types
188 integer, intent (in out), dimension(m) :: esta ! vector of initial equation status
189 ! (not defined here)
190 real*8, intent (in out), dimension(m) :: rhs ! vector of right hand sides
191 integer, intent (in out), dimension(n+1) :: colsta ! vector with start of column indices
192 integer, intent (out), dimension(nz) :: rowno ! vector of row numbers
193 integer, intent (in out), dimension(nz) :: nlflag ! vector of nonlinearity flags
194 real*8, intent (in out), dimension(nz) :: value ! vector of matrix values
195 real*8 usrmem(*) ! optional user memory
196!
197! Define information about the Variables:
198!
199! Curr is not defined. We will use the default starting values of
200! zero.
201!
202! By default, we do not define the status argument Vsta.
203!
204! The first 5 variables are Positive, i.e. have a lower bound of
205! zero. They must be defined. The remaining two variables are Free,
206! i.e. have a lower bound of -infinity, which is the default, and we
207! do not define them:
208!
209 lower(1) = 0.d0
210 lower(2) = 0.d0
211 lower(3) = 0.d0
212 lower(4) = 0.d0
213 lower(5) = 0.d0
214!
215! Tinvest (number 6) has an upper bound of 10 and all other variables
216! are unbounded, i.e. have an upper bound of +infinity, which is the
217! default, so we do not define them:
218!
219 upper(6) = 10.d0
220!
221! Define information about the Constraints:
222!
223! By default, we do not define the status argument Esta.
224!
225! Groupmin: Type >= or 1:
226!
227 type(1) = 1
228!
229! Rdef and Mdef: Type <= or 2:
230!
231 type(2) = 2
232 type(3) = 2
233!
234! Tdef and Idef: Type = or 0:
235!
236 type(4) = 0
237 type(5) = 0
238!
239! Right hand sides: Only Groupmin (number 1) has a nonzero Right hand
240! side so it is sufficient to define this one. The default is zero:
241!
242 rhs(1) = 4.d0
243!
244! Define the structure and content of the Jacobian
245!
246! To help define the Jacobian pattern and values it can be useful to
247! make a picture of the Jacobian. Since the model is small and linear
248! we can put everything in one small table:
249!
250! inv1 inv2 inv3 inv4 inv5 tinvest return
251! groupmin 1 1 1
252! rdef 2 5 2 1 1 -1.4
253! mdef 9 2 15 4 3 -5.0
254! tdef 1 1 1 1 1 -1
255! idef 0.043 0.045 0.027 0.025 0.022 -1
256!
257! The model is linear so we do not have the define the nonlinearity
258! flag, Nlflag.
259! The Jacobian has to be sorted column-wise so we will just define
260! the elements column by column according to the table above:
261!
262! Column 1, Inv1. Start in position 1.
263!
264 colsta(1) = 1
265 rowno(1) = 2
266 value(1) = 2.d0
267 rowno(2) = 3
268 value(2) = 9.d0
269 rowno(3) = 4
270 value(3) = 1.d0
271 rowno(4) = 5
272 value(4) = 0.043d0
273!
274! Column 2, Inv2. Start in position 5:
275!
276 colsta(2) = 5
277 rowno(5) = 2
278 value(5) = 5.d0
279 rowno(6) = 3
280 value(6) = 2.d0
281 rowno(7) = 4
282 value(7) = 1.d0
283 rowno(8) = 5
284 value(8) = 0.045d0
285!
286! Column 3, Inv3. Start in position 9:
287!
288 colsta(3) = 9
289 rowno(9) = 1
290 value(9) = 1.d0
291 rowno(10) = 2
292 value(10) = 2.d0
293 rowno(11) = 3
294 value(11) = 15.d0
295 rowno(12) = 4
296 value(12) = 1.d0
297 rowno(13) = 5
298 value(13) = 0.027d0
299!
300! Column 4, Inv4. Start in position 14:
301!
302 colsta(4) = 14
303 rowno(14) = 1
304 value(14) = 1.d0
305 rowno(15) = 2
306 value(15) = 1.d0
307 rowno(16) = 3
308 value(16) = 4.d0
309 rowno(17) = 4
310 value(17) = 1.d0
311 rowno(18) = 5
312 value(18) = 0.025d0
313!
314! Column 5, Inv5. Start in position 19:
315!
316 colsta(5) = 19
317 rowno(19) = 1
318 value(19) = 1.d0
319 rowno(20) = 2
320 value(20) = 1.d0
321 rowno(21) = 3
322 value(21) = 3.d0
323 rowno(22) = 4
324 value(22) = 1.d0
325 rowno(23) = 5
326 value(23) = 0.022d0
327!
328! Column 6, Tinvest, Start in position 24:
329!
330 colsta(6) = 24
331 rowno(24) = 2
332 value(24) = -1.4d0
333 rowno(25) = 3
334 value(25) = -5.0d0
335 rowno(26) = 4
336 value(26) = -1.d0
337!
338! Column 7, Return, Start in position 27:
339!
340 colsta(7) = 27
341 rowno(27) = 5
342 value(27) = -1.d0
343!
344! End of columns, the next free position is 28 = number of elements+1:
345! The number of elements, 27, was the one reported in Ipsz(3) in
346! Coipsz.
347!
348 colsta(8) = 28
349
351
352end Function ex01_readmatrix
353!
354! ======================================================================
355! This was the end of the model definition. The next three routines are
356! standard routines used to report the solution back and write the
357! messages.
358! ======================================================================
359Integer Function ex01_solution( XVAL, XMAR, XBAS, XSTA, YVAL, YMAR, YBAS, YSTA, N, M, USRMEM )
360#if defined(itl)
361!DEC$ ATTRIBUTES STDCALL, REFERENCE, NOMIXED_STR_LEN_ARG :: Ex01_Solution
362#endif
363
364 Use proginfo
365 IMPLICIT NONE
366 INTEGER, Intent(IN) :: n, m
367 INTEGER, Intent(IN), Dimension(N) :: xbas, xsta
368 INTEGER, Intent(IN), Dimension(M) :: ybas, ysta
369 real*8, Intent(IN), Dimension(N) :: xval, xmar
370 real*8, Intent(IN), Dimension(M) :: yval, ymar
371 real*8, Intent(IN OUT) :: usrmem(*)
372
373 INTEGER i
374 CHARACTER*5, Parameter, Dimension(4) :: stat = (/ 'Lower','Upper','Basic','Super' /)
375
376 Character*9, Parameter, Dimension(7) :: vname = (/ 'MUNICIP-A', 'MUNICIP-B', 'CORPORATE', 'US-SER-E ', 'US-SER-F ', &
377 'Tinvest ', 'Return ' /)
378 Character*9, Parameter, Dimension(5) :: cname = (/ 'GroupMin ', 'RDef ', 'Mdef ', 'Tdef ', 'Idef ' /)
379
380 WRITE(*,"(/' Variable Solution value Reduced cost B-stat'/)")
381 DO i = 1, n
382 WRITE(*,"(1P,1X,A9,E20.6,E16.6,4X,A5 )") vname(i), xval(i), xmar(i), stat(1+xbas(i))
383 ENDDO
384
385 WRITE(*,"(/' Constraint Activity level Marginal cost B-stat'/)")
386 DO i = 1, m
387 WRITE(*,"(1P,1X,A9,E20.6,E16.6,4X,A5 )") cname(i), yval(i), ymar(i), stat(1+ybas(i))
388 ENDDO
389
390 solcalls = solcalls + 1
391 ex01_solution = 0
392
393END Function ex01_solution
integer function std_status(modsta, solsta, iter, objval, usrmem)
Definition comdecl.f90:82
integer function std_message(smsg, dmsg, nmsg, llen, usrmem, msgv)
Definition comdecl.f90:203
integer function std_errmsg(rowno, colno, posno, msglen, usrmem, msg)
Definition comdecl.f90:248
program ex01
Main program. A simple setup and call of CONOPT.
Definition ex01.f90:55
integer function ex01_readmatrix(lower, curr, upper, vsta, type, rhs, esta, colsta, rowno, value, nlflag, n, m, nz, usrmem)
Define information about the model.
Definition ex01.f90:175
integer function ex01_solution(xval, xmar, xbas, xsta, yval, ymar, ybas, ysta, n, m, usrmem)
Definition ex01.f90:360
integer function coidef_errmsg(cntvect, coi_errmsg)
define callback routine for returning error messages for row, column or Jacobian elements.
integer function coidef_message(cntvect, coi_message)
define callback routine for handling messages returned during the solution process.
integer function coidef_readmatrix(cntvect, coi_readmatrix)
define callback routine for providing the matrix data to CONOPT.
integer function coidef_status(cntvect, coi_status)
define callback routine for returning the completion status.
integer function coidef_solution(cntvect, coi_solution)
define callback routine for returning the final solution values.
integer function coidef_optfile(cntvect, optfile)
define callback routine for defining an options file.
integer function coidef_license(cntvect, licint1, licint2, licint3, licstring)
define the License Information.
Definition coistart.f90:680
integer function coidef_numvar(cntvect, numvar)
defines the number of variables in the model.
Definition coistart.f90:358
integer function coidef_numnz(cntvect, numnz)
defines the number of nonzero elements in the Jacobian.
Definition coistart.f90:437
integer function coidef_optdir(cntvect, optdir)
defines the Optimization Direction.
Definition coistart.f90:552
integer function coidef_numnlnz(cntvect, numnlnz)
defines the Number of Nonlinear Nonzeros.
Definition coistart.f90:476
integer function coidef_numcon(cntvect, numcon)
defines the number of constraints in the model.
Definition coistart.f90:398
integer function coidef_objvar(cntvect, objvar)
defines the Objective Variable.
Definition coistart.f90:586
integer function coidef_size()
returns the size the Control Vector must have, measured in standard Integer units.
Definition coistart.f90:176
integer function coidef_inifort(cntvect)
initialisation method for Fortran applications.
Definition coistart.f90:314
integer function coi_solve(cntvect)
method for starting the solving process of CONOPT.
Definition coistart.f90:14
real *8 obj
Definition comdecl.f90:10
integer solcalls
Definition comdecl.f90:9
integer sstat
Definition comdecl.f90:12
integer stacalls
Definition comdecl.f90:8
subroutine flog(msg, code)
Definition comdecl.f90:56
integer mstat
Definition comdecl.f90:11
subroutine startup
Definition comdecl.f90:35