CONOPT
Loading...
Searching...
No Matches
pinopt.c
Go to the documentation of this file.
1
6
7#include <stdlib.h>
8#include <stdio.h>
9#include <math.h>
10#include <string.h>
11#include "coiheader.h"
12
13#include "comdecl.h"
14
15
16
17int T = 16; /* Number of time periods */
18int Vpp = 7; /* Variables per period */
19int Epp = 6; /* Equations per period */
20
21
26int COI_CALLCONV Pin_ReadMatrix( double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[],
27 double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[],
28 int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void* USRMEM )
29{
30 int it, is, i, icol, iz;
31/*
32 Define the information for the columns.
33
34 We should not supply status information, VSTA.
35
36 We order the variables as follows:
37 0: td, 1: cs, 2: s, 3: d, 4: r, 5: p, and 6: rev. All variables for
38 period 1 appears first followed by all variables for period 2 etc.
39
40 td, cs, s, and d have lower bounds of 0, r and p have lower
41 bounds of 1, and rev has no lower bound.
42 All have infinite upper bounds (default).
43 The initial value of td is 18, s is 7, cs is 7*t, d is td-s,
44 p is 14, and r is r(t-1)-d. No initial value for rev. */
45
46 for ( it=1; it<=T; it++ ) {
47 is = Vpp*(it-1);
48 LOWER[is ] = 0;
49 LOWER[is+1] = 0;
50 LOWER[is+2] = 0;
51 LOWER[is+3] = 0;
52 LOWER[is+4] = 1;
53 LOWER[is+5] = 1;
54 CURR[is ] = 18;
55 CURR[is+1] = 7*it;
56 CURR[is+2] = 7;
57 CURR[is+3] = CURR[is] - CURR[is+2];
58 if ( it > 1 )
59 CURR[is+4] = CURR[is+4-Vpp] - CURR[is+3];
60 else
61 CURR[is+4] = 500 - CURR[is+3];
62 CURR[is+5] = 14;
63 }
64/*
65 Define the information for the rows
66
67 We order the constraints as follows: The objective is first,
68 followed by tddef, sdef, csdef, ddef, rdef, and revdef for
69 the first period, the same for the second period, etc.
70
71 The objective is a nonbinding constraint: */
72
73 TYPE[0] = 3;
74
75/* All others are equalities: */
76
77 for ( i = 1; i < NUMCON; i++ )
78 TYPE[i] = 0;
79/*
80 Right hand sides: In all periods except the first, only tddef
81 has a nonzero right hand side of 1+2.3*1.015**(t-1).
82 In the initial period there are contributions from lagged
83 variables in the constraints that have lagged variables. */
84
85 for ( it = 1; it<=T; it++ ) {
86 is = 1 + 6*(it-1);
87 RHS[is] = 1.0+2.3*pow(1.015,(it-1.));
88 }
89
90/* tddef: + 0.87*td(0) */
91
92 RHS[1] = RHS[1]+ 0.87*18.;
93
94/* sdef: +0.75*s(0) */
95
96 RHS[2] = 0.75*6.5;
97
98/* csdef: +1*cs(0) */
99
100 RHS[3] = 0;
101
102/* rdef: +1*r(0) */
103
104 RHS[5] = 500;
105
106/*
107 Define the structure and content of the Jacobian:
108 To help define the Jacobian pattern and values it can be useful to
109 make a picture of the Jacobian. We describe the variables for one
110 period and the constraints they are part of:
111
112 td cs s d r p rev
113 0 1 2 3 4 5 6
114 0: Obj (1+r)**(1-t)
115 Period t:
116 0: tddef 1.0 0.13
117 1: sdef NL 1.0 NL
118 2: csdef 1.0 -1.0
119 3: ddef -1.0 1.0 1.0
120 4: rdef 1.0 1.0
121 5: revdef NL NL NL 1.0
122 Period t+1:
123 0: tddef -0.87
124 1: sdef -0.75
125 2: csdef -1.0
126 3: ddef
127 4: rdef -1.0
128 5: revdef
129
130 The Jacobian has to be sorted column-wise so we will just define
131 the elements column by column according to the table above: */
132
133 iz = 0; /* Running index for Jacobian in C convention 0 to nz-1 */
134 icol = 0; /* Running column index in C convention 0 to N-1 */
135 for ( it = 1; it <= T; it++ )
136 {
137
138/* is points to the position before the first equation for the period */
139
140 is = 1 + 6*(it-1); /* 1 correspond to the objective in row 0 */
141
142/* Column td: */
143 COLSTA[icol] = iz;
144 icol = icol + 1;
145 ROWNO[iz] = is;
146 VALUE[iz] = +1.0;
147 NLFLAG[iz] = 0;
148 iz = iz + 1;
149 ROWNO[iz] = is+3;
150 VALUE[iz] = -1.0;
151 NLFLAG[iz] = 0;
152 iz = iz + 1;
153 if ( it < T ) {
154 ROWNO[iz] = is+Epp;
155 VALUE[iz] = -0.87;
156 NLFLAG[iz] = 0;
157 iz = iz + 1;
158 }
159
160/* Column cs */
161 COLSTA[icol] = iz;
162 icol = icol + 1;
163 ROWNO[iz] = is+1;
164 NLFLAG[iz] = 1;
165 iz = iz + 1;
166 ROWNO[iz] = is+2;
167 VALUE[iz] = +1.0;
168 NLFLAG[iz] = 0;
169 iz = iz + 1;
170 if ( it < T ) {
171 ROWNO[iz] = is+2+Epp;
172 VALUE[iz] = -1.0;
173 NLFLAG[iz] = 0;
174 iz = iz + 1;
175 }
176
177/* Column s */
178 COLSTA[icol] = iz;
179 icol = icol + 1;
180 ROWNO[iz] = is+1;
181 VALUE[iz] = +1.0;
182 NLFLAG[iz] = 0;
183 iz = iz + 1;
184 ROWNO[iz] = is+2;
185 VALUE[iz] = -1.0;
186 NLFLAG[iz] = 0;
187 iz = iz + 1;
188 ROWNO[iz] = is+3;
189 VALUE[iz] = +1.0;
190 NLFLAG[iz] = 0;
191 iz = iz + 1;
192 if ( it < T ) {
193 ROWNO[iz] = is+1+Epp;
194 VALUE[iz] = -0.75;
195 NLFLAG[iz] = 0;
196 iz = iz + 1;
197 }
198
199/* Column d: */
200 COLSTA[icol] = iz;
201 icol = icol + 1;
202 ROWNO[iz] = is+3;
203 VALUE[iz] = +1.0;
204 NLFLAG[iz] = 0;
205 iz = iz + 1;
206 ROWNO[iz] = is+4;
207 VALUE[iz] = +1.0;
208 NLFLAG[iz] = 0;
209 iz = iz + 1;
210 ROWNO[iz] = is+5;
211 NLFLAG[iz] = 1;
212 iz = iz + 1;
213
214/* Column r: */
215 COLSTA[icol] = iz;
216 icol = icol + 1;
217 ROWNO[iz] = is+4;
218 VALUE[iz] = +1.0;
219 NLFLAG[iz] = 0;
220 iz = iz + 1;
221 ROWNO[iz] = is+5;
222 NLFLAG[iz] = 1;
223 iz = iz + 1;
224 if ( it < T ) {
225 ROWNO[iz] = is+4+Epp;
226 VALUE[iz] = -1.0;
227 NLFLAG[iz] = 0;
228 iz = iz + 1;
229 }
230
231/* Column p: */
232 COLSTA[icol] = iz;
233 icol = icol + 1;
234 ROWNO[iz] = is;
235 VALUE[iz] = +0.13;
236 NLFLAG[iz] = 0;
237 iz = iz + 1;
238 ROWNO[iz] = is+1;
239 NLFLAG[iz] = 1;
240 iz = iz + 1;
241 ROWNO[iz] = is+5;
242 NLFLAG[iz] = 1;
243 iz = iz + 1;
244
245/* Column rev: */
246 COLSTA[icol] = iz;
247 icol = icol + 1;
248 ROWNO[iz] = +0; /* Objective -- no is term */
249 VALUE[iz] = pow(1.05,(1.0-it));
250 NLFLAG[iz] = 0;
251 iz = iz + 1;
252 ROWNO[iz] = is+5;
253 VALUE[iz] = 1.0;
254 NLFLAG[iz] = 0;
255 iz = iz + 1;
256 }
257 COLSTA[icol] = iz; /* First elements past last column */
258
259 return 0;
260}
261/*
262 =====================================================================
263 Compute nonlinear terms and non-constant Jacobian elements */
264
265
270int COI_CALLCONV Pin_FDEval( const double X[], double* G, double JAC[], int ROWNO, const int JACNUM[], int MODE,
271 int IGNERR, int* ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void* USRMEM )
272{
273
274 int it, is;
275 double h1, h2;
276
277/* Compute the number of the period, it */
278
279 it = (ROWNO+Epp-1) / Epp;
280 is = Vpp*(it-1);
281 if ( 1+(it-1)*Epp+1 == ROWNO ) {
282
283/* sdef equation. Nonlinear term = -(1.1+0.1*p)*1.02**(-cs/7) */
284
285 h1 = (1.1+0.1*X[is+5]);
286 h2 = pow(1.02,-X[is+1]/7.0);
287 if ( 1 == MODE || 3 == MODE )
288 *G = -h1*h2;
289 if ( 2 == MODE || 3 == MODE ) {
290 JAC[is+1] = h1*h2*log(1.02)/7.0;
291 JAC[is+5] = -h2*0.1;
292 }
293 }
294 else if ( 1+(it-1)*Epp+5 == ROWNO ) {
295
296/* revdef equation. Nonlinear term = -d*(p-250/r) */
297
298 if ( 1 == MODE || 3 == MODE )
299 *G = -X[is+3]*(X[is+5]-250./X[is+4]);
300 if ( 2 == MODE || 3 == MODE ) {
301 JAC[is+3] = -(X[is+5]-250./X[is+4]);
302 JAC[is+4] = -X[is+3]*250./pow(X[is+4],2);
303 JAC[is+5] = -X[is+3];
304 }
305 }
306 else {
307
308/* Error - this equation is not nonlinear */
309
310 printf("\nError. Pin_FDEval called with ROWNO = %d. MODE = %d\n\n", ROWNO, MODE);
311 return 1;
312 };
313 return 0;
314}
315
316
321int COI_CALLCONV Pin_Option( int NCALL, double* RVAL, int* IVAL, int* LVAL, char* NAME, void* USRMEM )
322{
323 fprintf(fd,"Inside Pin_Option. NCALL = %d\n",NCALL);
324 if (NCALL == 0) {
325 strcpy(NAME, "Doprep");
326 *LVAL = 0;
327 }
328 else if (NCALL == 1) {
329 strcpy(NAME, "Lotria");
330 *IVAL = 1;
331 }
332 else {
333 strcpy(NAME,"");
334 };
335 return 0;
336}
337#include "std.c"
338
341int main(int argc, char** argv)
342{
343 int major, minor, patch;
344
345 c_log( "Starting to execute", START );
346
347/* Write which version of CONOPT we are using. */
348
349 COIGET_Version( &major, &minor, &patch );
350 printf("\nSolving Pindyck Model using CONOPT version %d.%d.%d:\n", major, minor, patch );
351
352/* Tell CONOPT about the sizes in the model */
353/* Number of variables (excl. slacks): 7 per period */
354
356
357/* Number of equations: 1 objective + 6 per period */
358
359 COI_Error += COIDEF_NumCon ( CntVect, 1+6*T );
360
361/* Number of nonzeros in the Jacobian. See the counting in */
362/* ReadMatrix above. For each period there is 1 in the objective, 16 */
363/* for unlagged variables and 4 for lagged variables. */
364
365 COI_Error += COIDEF_NumNz ( CntVect, 17*T+4*(T-1) );
366
367/* Number of nonlinear nonzeros. 5 unlagged for each period. */
368
370
371/* Objective: Maximize Constraint no 0 */
372
375
376/* Turn debugging of FDEval on (1) or off (0) */
377
379
380/* Register the options file */
381
382 COI_Error += COIDEF_Optfile ( CntVect, "pindyck.opt");
383 /*
384 Register the necessary callback routines with CONOPT
385 */
386 COI_Error += COIDEF_Message ( CntVect, &Std_Message ); /* Register the callback Message */
387 COI_Error += COIDEF_ErrMsg ( CntVect, &Std_ErrMsg ); /* Register the callback ErrMsg */
388 COI_Error += COIDEF_Status ( CntVect, &Std_Status ); /* Register the callback Status */
389 COI_Error += COIDEF_Solution ( CntVect, &Std_Solution ); /* Register the callback Solution */
390 COI_Error += COIDEF_ReadMatrix( CntVect, &Pin_ReadMatrix); /* Register the callback ReadMatrix */
391 COI_Error += COIDEF_FDEval ( CntVect, &Pin_FDEval); /* Register the callback FDEval */
392 COI_Error += COIDEF_Option ( CntVect, &Pin_Option); /* Register the callback Option */
393
394#if defined(LICENSE_INT_1) && defined(LICENSE_INT_2) && defined(LICENSE_INT_3) && defined(LICENSE_TEXT)
395 COI_Error += COIDEF_License ( CntVect, LICENSE_INT_1, LICENSE_INT_2, LICENSE_INT_3, LICENSE_TEXT);
396#endif
397
398 if ( COI_Error ) {
399 printf("Skipping COI_Solve due to setup errors. COI_Error = %d\n",COI_Error);
400 c_log( "Skipping Solve due to setup errors", COI_Error);
401 }
402 COI_Error = COI_Solve ( CntVect ); /* Optimize */
403 printf("After solving. COI_Error =%d\n",COI_Error);
404 if ( COI_Error ) {
405 c_log( "Errors encountered during solution", COI_Error); }
406 else if ( stacalls == 0 || solcalls == 0 ) {
407 c_log( "Status or Solution routine was not called", -1); }
408 else if ( mstat != 2 || sstat != 1 ) {
409 c_log( "Incorrect Model or Solver Status", -1); }
410 else if ( fabs( OBJ-1170.486 ) > 0.001 ) {
411 c_log( "Incorrect objective returned", -1); }
412
413 c_log( "Successful Solve", OK );
414}
C language header file for direct linking against the COI library generated by apiwrapper for GAMS Ve...
int stacalls
Definition comdecl.h:4
coiHandle_t CntVect
Definition comdecl.h:14
#define START
Definition comdecl.h:13
FILE * fd
Definition comdecl.h:3
int solcalls
Definition comdecl.h:5
double OBJ
Definition comdecl.h:6
int mstat
Definition comdecl.h:7
#define OK
Definition comdecl.h:12
int sstat
Definition comdecl.h:8
int COI_Error
Definition comdecl.h:15
int COI_CALLCONV COIDEF_ReadMatrix(coiHandle_t cntvect, COI_READMATRIX_t coi_readmatrix)
define callback routine for providing the matrix data to CONOPT.
int COI_CALLCONV COIDEF_Message(coiHandle_t cntvect, COI_MESSAGE_t coi_message)
define callback routine for handling messages returned during the solution process.
int COI_CALLCONV COIDEF_Solution(coiHandle_t cntvect, COI_SOLUTION_t coi_solution)
define callback routine for returning the final solution values.
int COI_CALLCONV COIDEF_Status(coiHandle_t cntvect, COI_STATUS_t coi_status)
define callback routine for returning the completion status.
int COI_CALLCONV COIDEF_ErrMsg(coiHandle_t cntvect, COI_ERRMSG_t coi_errmsg)
define callback routine for returning error messages for row, column or Jacobian elements.
int COI_CALLCONV COIDEF_FDEval(coiHandle_t cntvect, COI_FDEVAL_t coi_fdeval)
define callback routine for performing function and derivative evaluations.
int COI_CALLCONV COIDEF_Option(coiHandle_t cntvect, COI_OPTION_t coi_option)
define callback routine for defining runtime options.
int COI_CALLCONV COIDEF_Optfile(coiHandle_t cntvect, const char *optfile)
define callback routine for defining an options file.
int COI_CALLCONV COIDEF_DebugFV(coiHandle_t cntvect, int debugfv)
turn Debugging of FDEval on and off.
int COI_CALLCONV COIDEF_License(coiHandle_t cntvect, int licint1, int licint2, int licint3, const char *licstring)
define the License Information.
int COI_CALLCONV COIDEF_ObjCon(coiHandle_t cntvect, int objcon)
defines the Objective Constraint.
int COI_CALLCONV COIDEF_NumVar(coiHandle_t cntvect, int numvar)
defines the number of variables in the model.
int COI_CALLCONV COIDEF_NumNz(coiHandle_t cntvect, int numnz)
defines the number of nonzero elements in the Jacobian.
int COI_CALLCONV COIDEF_NumCon(coiHandle_t cntvect, int numcon)
defines the number of constraints in the model.
int COI_CALLCONV COIDEF_OptDir(coiHandle_t cntvect, int optdir)
defines the Optimization Direction.
int COI_CALLCONV COIDEF_NumNlNz(coiHandle_t cntvect, int numnlnz)
defines the Number of Nonlinear Nonzeros.
int COI_CALLCONV COI_Solve(coiHandle_t cntvect)
method for starting the solving process of CONOPT.
void COI_CALLCONV COIGET_Version(int *major, int *minor, int *patch)
returns the version number. It can be used to ensure that the modeler is linked to the correct versio...
int COI_CALLCONV Pin_ReadMatrix(double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[], double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[], int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void *USRMEM)
Define information about the model.
Definition pinadd.c:28
int COI_CALLCONV Pin_FDEval(const double X[], double *G, double JAC[], int ROWNO, const int JACNUM[], int MODE, int IGNERR, int *ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
Compute nonlinear terms and non-constant Jacobian elements.
Definition pinadd.c:298
int T
Definition pinadd.c:14
#define Epp
Definition pinadd.c:18
#define Vpp
Definition pinadd.c:17
int COI_CALLCONV Pin_ReadMatrix(double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[], double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[], int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void *USRMEM)
Define information about the model.
Definition pinopt.c:26
int main(int argc, char **argv)
Main program. A simple setup and call of CONOPT.
Definition pinopt.c:341
int COI_CALLCONV Pin_FDEval(const double X[], double *G, double JAC[], int ROWNO, const int JACNUM[], int MODE, int IGNERR, int *ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void *USRMEM)
Compute nonlinear terms and non-constant Jacobian elements.
Definition pinopt.c:270
int COI_CALLCONV Pin_Option(int NCALL, double *RVAL, int *IVAL, int *LVAL, char *NAME, void *USRMEM)
Sets runtime options.
Definition pinopt.c:321
int COI_CALLCONV Std_Status(int MODSTA, int SOLSTA, int ITER, double OBJVAL, void *USRMEM)
Definition std.c:45
int COI_CALLCONV Std_Message(int SMSG, int DMSG, int NMSG, char *MSGV[], void *USRMEM)
Definition std.c:8
void c_log(char *msgt, int code)
Definition std.c:202
int COI_CALLCONV Std_ErrMsg(int ROWNO, int COLNO, int POSNO, const char *MSG, void *USRMEM)
Definition std.c:26
int COI_CALLCONV Std_Solution(const double XVAL[], const double XMAR[], const int XBAS[], const int XSTA[], const double YVAL[], const double YMAR[], const int YBAS[], const int YSTA[], int NUMVAR, int NUMCON, void *USRMEM)
Definition std.c:77