CONOPT
Loading...
Searching...
No Matches
mp_pinthread4.c
Go to the documentation of this file.
1
17
18#include <stdlib.h>
19#include <stdio.h>
20#include <math.h>
21#include <string.h>
22#include <omp.h>
23#include "coiheader.h"
24
25#include "comdecl.h"
26
27#ifdef _MSC_VER
28#pragma warning (disable : 3280)
29#endif
30
31#define Tmin 21 /* Min number of time periods */
32#define Tmax 40 /* Max number of time periods */
33#define Vpp 7 /* Variables per period */
34#define Epp 6 /* Equations per period */
35double xkeep[Tmax*Tmax*Vpp]; /* Space to store solution for all periods */
36double xkeep1[Tmax*Tmax*Vpp]; /* Space to store solution for all periods */
37double xkeep2[Tmax*Tmax*Vpp]; /* Space to store solution for all periods */
38
39struct Periods /* Structure used to pass number of periods to the
40 models solved in parallel */
41{
42 int NT;
43};
44
45
50int COI_CALLCONV Pin_ReadMatrix( double LOWER[], double CURR[], double UPPER[], int VSTA[], int TYPE[],
51 double RHS[], int ESTA[], int COLSTA[], int ROWNO[], double VALUE[],
52 int NLFLAG[], int NUMVAR, int NUMCON, int NUMNZ, void* USRMEM )
53{
54 int it, is, i, icol, iz;
55 int T;
56
57 T = ((struct Periods *)USRMEM)->NT; /* Extract the number of periods from USRMEM */
58/*
59 Define the information for the columns.
60
61 We should not supply status information, VSTA.
62
63 We order the variables as follows:
64 0: td, 1: cs, 2: s, 3: d, 4: r, 5: p, and 6: rev. All variables for
65 period 1 appears first followed by all variables for period 2 etc.
66
67 td, cs, s, and d have lower bounds of 0, r and p have lower
68 bounds of 1, and rev has no lower bound.
69 All have infinite upper bounds (default).
70 The initial value of td is 18, s is 7, cs is 7*t, d is td-s,
71 p is 14, and r is r(t-1)-d. No initial value for rev. */
72
73 for ( it=1; it<=T; it++ ) {
74 is = Vpp*(it-1);
75 LOWER[is ] = 0;
76 LOWER[is+1] = 0;
77 LOWER[is+2] = 0;
78 LOWER[is+3] = 0;
79 LOWER[is+4] = 1;
80 LOWER[is+5] = 1;
81 CURR[is ] = 18;
82 CURR[is+1] = 7*it;
83 CURR[is+2] = 7;
84 CURR[is+3] = CURR[is] - CURR[is+2];
85 if ( it > 1 )
86 CURR[is+4] = CURR[is+4-Vpp] - CURR[is+3];
87 else
88 CURR[is+4] = 500 - CURR[is+3];
89 CURR[is+5] = 14;
90 }
91/*
92 Define the information for the rows
93
94 We order the constraints as follows: The objective is first,
95 followed by tddef, sdef, csdef, ddef, rdef, and revdef for
96 the first period, the same for the second period, etc.
97
98 The objective is a nonbinding constraint: */
99
100 TYPE[0] = 3;
101
102/* All others are equalities: */
103
104 for ( i = 1; i < NUMCON; i++ )
105 TYPE[i] = 0;
106/*
107 Right hand sides: In all periods except the first, only tddef
108 has a nonzero right hand side of 1+2.3*1.015**(t-1).
109 In the initial period there are contributions from lagged
110 variables in the constraints that have lagged variables. */
111
112 for ( it = 1; it<=T; it++ ) {
113 is = 1 + 6*(it-1);
114 RHS[is] = 1.0+2.3*pow(1.015,(it-1.));
115 }
116
117/* tddef: + 0.87*td(0) */
118
119 RHS[1] = RHS[1]+ 0.87*18.;
120
121/* sdef: +0.75*s(0) */
122
123 RHS[2] = 0.75*6.5;
124
125/* csdef: +1*cs(0) */
126
127 RHS[3] = 0;
128
129/* rdef: +1*r(0) */
130
131 RHS[5] = 500;
132
133/*
134 Define the structure and content of the Jacobian:
135 To help define the Jacobian pattern and values it can be useful to
136 make a picture of the Jacobian. We describe the variables for one
137 period and the constraints they are part of:
138
139 td cs s d r p rev
140 0 1 2 3 4 5 6
141 0: Obj (1+r)**(1-t)
142 Period t:
143 0: tddef 1.0 0.13
144 1: sdef NL 1.0 NL
145 2: csdef 1.0 -1.0
146 3: ddef -1.0 1.0 1.0
147 4: rdef 1.0 1.0
148 5: revdef NL NL NL 1.0
149 Period t+1:
150 0: tddef -0.87
151 1: sdef -0.75
152 2: csdef -1.0
153 3: ddef
154 4: rdef -1.0
155 5: revdef
156
157 The Jacobian has to be sorted column-wise so we will just define
158 the elements column by column according to the table above: */
159
160 iz = 0; /* Running index for Jacobian in C convention 0 to nz-1 */
161 icol = 0; /* Running column index in C convention 0 to N-1 */
162 for ( it = 1; it <= T; it++ )
163 {
164
165/* is points to the position before the first equation for the period */
166
167 is = 1 + 6*(it-1); /* 1 correspond to the objective in row 0 */
168
169/* Column td: */
170 COLSTA[icol] = iz;
171 icol = icol + 1;
172 ROWNO[iz] = is;
173 VALUE[iz] = +1.0;
174 NLFLAG[iz] = 0;
175 iz++;
176 ROWNO[iz] = is+3;
177 VALUE[iz] = -1.0;
178 NLFLAG[iz] = 0;
179 iz++;
180 if ( it < T ) {
181 ROWNO[iz] = is+Epp;
182 VALUE[iz] = -0.87;
183 NLFLAG[iz] = 0;
184 iz++;
185 }
186
187/* Column cs */
188 COLSTA[icol] = iz;
189 icol = icol + 1;
190 ROWNO[iz] = is+1;
191 NLFLAG[iz] = 1;
192 iz++;
193 ROWNO[iz] = is+2;
194 VALUE[iz] = +1.0;
195 NLFLAG[iz] = 0;
196 iz++;
197 if ( it < T ) {
198 ROWNO[iz] = is+2+Epp;
199 VALUE[iz] = -1.0;
200 NLFLAG[iz] = 0;
201 iz++;
202 }
203
204/* Column s */
205 COLSTA[icol] = iz;
206 icol = icol + 1;
207 ROWNO[iz] = is+1;
208 VALUE[iz] = +1.0;
209 NLFLAG[iz] = 0;
210 iz++;
211 ROWNO[iz] = is+2;
212 VALUE[iz] = -1.0;
213 NLFLAG[iz] = 0;
214 iz++;
215 ROWNO[iz] = is+3;
216 VALUE[iz] = +1.0;
217 NLFLAG[iz] = 0;
218 iz++;
219 if ( it < T ) {
220 ROWNO[iz] = is+1+Epp;
221 VALUE[iz] = -0.75;
222 NLFLAG[iz] = 0;
223 iz++;
224 }
225
226/* Column d: */
227 COLSTA[icol] = iz;
228 icol = icol + 1;
229 ROWNO[iz] = is+3;
230 VALUE[iz] = +1.0;
231 NLFLAG[iz] = 0;
232 iz++;
233 ROWNO[iz] = is+4;
234 VALUE[iz] = +1.0;
235 NLFLAG[iz] = 0;
236 iz++;
237 ROWNO[iz] = is+5;
238 NLFLAG[iz] = 1;
239 iz++;
240
241/* Column r: */
242 COLSTA[icol] = iz;
243 icol = icol + 1;
244 ROWNO[iz] = is+4;
245 VALUE[iz] = +1.0;
246 NLFLAG[iz] = 0;
247 iz++;
248 ROWNO[iz] = is+5;
249 NLFLAG[iz] = 1;
250 iz++;
251 if ( it < T ) {
252 ROWNO[iz] = is+4+Epp;
253 VALUE[iz] = -1.0;
254 NLFLAG[iz] = 0;
255 iz++;
256 }
257
258/* Column p: */
259 COLSTA[icol] = iz;
260 icol = icol + 1;
261 ROWNO[iz] = is;
262 VALUE[iz] = +0.13;
263 NLFLAG[iz] = 0;
264 iz++;
265 ROWNO[iz] = is+1;
266 NLFLAG[iz] = 1;
267 iz++;
268 ROWNO[iz] = is+5;
269 NLFLAG[iz] = 1;
270 iz++;
271
272/* Column rev: */
273 COLSTA[icol] = iz;
274 icol = icol + 1;
275 ROWNO[iz] = +0; /* Objective -- no is term */
276 VALUE[iz] = pow(1.05,(1.0-it));
277 NLFLAG[iz] = 0;
278 iz++;
279 ROWNO[iz] = is+5;
280 VALUE[iz] = 1.0;
281 NLFLAG[iz] = 0;
282 iz++;
283 }
284 COLSTA[icol] = iz; /* First elements past last column */
285
286 return 0;
287}
288/*
289 =====================================================================
290 Compute nonlinear terms and non-constant Jacobian elements */
291
292
297int COI_CALLCONV Pin_FDEval( const double X[], double* G, double JAC[], int ROWNO, const int JACNUM[], int MODE,
298 int IGNERR, int* ERRCNT, int NUMVAR, int NUMJAC, int THREAD, void* USRMEM )
299{
300
301 int it, is;
302 double h1, h2;
303
304/* Compute the number of the period, it */
305
306 it = ( ROWNO+Epp-1) / Epp;
307 is = Vpp*(it-1);
308 if ( 1+(it-1)*Epp+1 == ROWNO ) {
309
310/* sdef equation. Nonlinear term = -(1.1+0.1*p)*1.02**(-cs/7) */
311
312 h1 = (1.1+0.1*X[is+5]);
313 h2 = pow(1.02,-X[is+1]/7.0);
314 if ( 1 == MODE || 3 == MODE )
315 *G = -h1*h2;
316 if ( 2 == MODE || 3 == MODE ) {
317 JAC[is+1] = h1*h2*log(1.02)/7.0;
318 JAC[is+5] = -h2*0.1;
319 }
320 }
321 else if ( 1+(it-1)*Epp+5 == ROWNO ) {
322
323/* revdef equation. Nonlinear term = -d*(p-250/r) */
324
325 if ( 1 == MODE || 3 == MODE )
326 *G = -X[is+3]*(X[is+5]-250./X[is+4]);
327 if ( 2 == MODE || 3 == MODE ) {
328 JAC[is+3] = -(X[is+5]-250./X[is+4]);
329 JAC[is+4] = -X[is+3]*250./pow(X[is+4],2);
330 JAC[is+5] = -X[is+3];
331 }
332 }
333 else {
334
335/* Error - this equation is not nonlinear */
336
337 printf("\nError. Pin_FDEval called with ROWNO = %d. MODE = %d\n\n", ROWNO, MODE);
338 return 1;
339 };
340 return 0;
341}
342
343/*
344 Here we have some adjusted implementations for the mandatory
345 callback routines Message, ErrMsg, Status, and Solution.
346 They give less output than the standard ones since we are in
347 several long loops */
348
349int COI_CALLCONV Pin_Message( int SMSG, int DMSG, int NMSG, char* MSGV[], void* USRMEM )
350{
351/* This implementation does not write any messages. When running with
352 multiple threads the messages get mixed up. It is possible to identity
353 the periods number of each message to make it readable as shown in
354 the part that is commented out. */
355#if 0
356 int i;
357
358 int T;
359 T = ((struct Periods *)USRMEM)->NT; /* Extract the number of periods from USRMEM */
360
361 for( i=0; i<SMSG;i++ ) printf( "%d: %s\n", T, MSGV[i]);
362 for( i=0; i<DMSG;i++ ) fprintf(fd,"%d: %s\n", T, MSGV[i]);
363 for( i=0; i<SMSG;i++ ) fprintf(fs,"%d: %s\n", T, MSGV[i]);
364#endif
365 return 0;
366}
367
368int COI_CALLCONV Pin_ErrMsg( int ROWNO, int COLNO, int POSNO, const char* MSG, void* USRMEM )
369{
370/* Standard ErrMsg routine. Write to Documentation and Status file*/
371 int T;
372 T = ((struct Periods *)USRMEM)->NT; /* Extract the number of periods from USRMEM */
373
374 if ( ROWNO == -1 ) fprintf(fd,"%d: Variable %d : ",T, COLNO);
375 else if ( COLNO == -1 ) fprintf(fd,"%d: Equation %d : ",T, ROWNO);
376 else fprintf(fd,"%d: Variable %d appearing in Equation %d : ", T, COLNO, ROWNO);
377 fprintf(fd,"%s\n", MSG);
378
379 if ( ROWNO == -1 ) fprintf(fs,"%d: Variable %d : ",T, COLNO);
380 else if ( COLNO == -1 ) fprintf(fs,"%d: Equation %d : ",T, ROWNO);
381 else fprintf(fs,"%d: Variable %d appearing in Equation %d : ",T, COLNO, ROWNO);
382 fprintf(fs,"%s\n", MSG);
383
384#ifdef flush
385 fflush(fd); fflush(fs);
386#endif
387 return 0;
388}
389
390int COI_CALLCONV Pin_Status( int MODSTA, int SOLSTA, int ITER, double OBJVAL, void* USRMEM )
391{
392 int T;
393 T = ((struct Periods *)USRMEM)->NT; /* Extract the number of periods from USRMEM */
394/*
395 printf("\n");
396 printf("CONOPT has finished Optimizing\n");
397 printf("Model status = %8d\n", *MODSTA);
398 printf("Solver status = %8d\n", *SOLSTA);
399 printf("Iteration count = %8d\n", *ITER);
400 printf("Objective value = %10f\n", *OBJVAL); */
401
402 fprintf(fd,"%d: \n",T );
403 fprintf(fd,"%d: CONOPT has finished Optimizing\n",T );
404 fprintf(fd,"%d: Model status = %8d\n",T , MODSTA);
405 fprintf(fd,"%d: Solver status = %8d\n",T , SOLSTA);
406 fprintf(fd,"%d: Iteration count = %8d\n",T , ITER);
407 fprintf(fd,"%d: Objective value = %10f\n",T , OBJVAL);
408
409 fprintf(fs,"%d: \n",T);
410 fprintf(fs,"%d: Model status = %8d\n",T , MODSTA);
411 fprintf(fs,"%d: Solver status = %8d\n",T , SOLSTA);
412 fprintf(fs,"%d: Objective value = %10f\n",T , OBJVAL);
413
414 stacalls++;
415 OBJ = OBJVAL;
416 mstat = MODSTA;
417 sstat = SOLSTA;
418#ifdef flush
419 fflush(fd); fflush(fs);
420#endif
421 return 0;
422}
423
424int COI_CALLCONV Pin_Solution( const double XVAL[], const double XMAR[], const int XBAS[], const int XSTA[],
425 const double YVAL[], const double YMAR[], const int YBAS[], const int YSTA[],
426 int NUMVAR, int NUMCON, void* USRMEM )
427{
428 int i;
429 /* char *status[4] = {"Lower","Upper","Basic","Super"}; */
430 int T;
431
432 T = ((struct Periods *)USRMEM)->NT; /* Extract the number of periods from USRMEM */
433
434 for ( i=0; i<NUMCON; i++ )
435 xkeep[(T-1)*Tmax*Vpp+i] = YVAL[i];
436/* do not print but just store the solution
437 fprintf(fd,"\n%d: Variable Solution value Reduced cost Status\n\n", T);
438 for ( i=0; i<*N; i++ )
439 fprintf(fd,"%d: %6d%18f%18f%10s\n", T, i, XVAL[i], XMAR[i], status[XBAS[i]] );
440 fprintf(fd,"\n%d: Constrnt Activity level Marginal cost Status\n\n", T);
441 for ( i=0; i<*M; i++ )
442 fprintf(fd,"%d: %6d%18f%18f%10s\n", T, i, YVAL[i], YMAR[i], status[YBAS[i]] ); */
443
444 solcalls++;
445 return 0;
446}
447
448void c_log( char *msgt, int code )
449/* This routine has some of the same functionality as the c_log routine in std.c
450 but it does not call coiCreate and CoiFree. This is done in the main program. */
451{
452 FILE *fc;
453 int i;
454 int c;
455
456 if ( code == START )
457 {
458 i = 0; /* Read the name of the program without extension from stdin */
459 while ( (c = getchar()) != EOF && i < MAXLINE ) pname[i++] = (char)c;
460 pname[i-1] = '\0'; /* remove eof and new-line chars */
461 strcpy(fname,pname); strcat(fname,".lst" );
462 fd = fopen(fname,"w");
463 strcpy(fname,pname); strcat(fname,".sta" );
464 fs = fopen(fname,"w");
465 };
466 strcpy(fname,pname); strcat(fname,".rc" );
467 fc = fopen(fname,"w");
468 fprintf(fc,"%s: %s.\n", pname, msgt );
469 fclose(fc);
470 if ( code != START )
471 {
472 fclose(fd);
473 fclose(fs);
474 if ( code == OK )
475 exit(0);
476 else
477 exit(code);
478 }
479}
480
483int main(int argc, char** argv)
484{
485 coiHandle_t *CntVect1; /* Pointers to CONOPT control vectors, one for each thread. */
486 coiHandle_t CntVect; /* CONOPT control vectors, for current thread, local to main. */
487 int maxthread;
488 int thread;
489 int T;
490 int i;
491 int dif1, dif2;
492 char msg[256];
493
494 double time0, time1, time2, time3;
495 struct Periods **Usrmem; /* Vector of Periods structures, one for each thread */
496
497 c_log( "Starting to execute", START );
498
499 maxthread = omp_get_max_threads();
500 printf("Initial maxthread= %d\n",maxthread);
501 if ( maxthread < 4 ) {
502 maxthread = 4;
503 omp_set_num_threads(maxthread);
504 }
505 printf("Revised maxthread= %d\n",maxthread);
506
507/* Write which version of CONOPT we are using. This can be done at
508 any time, also before initializing the control vector. */
509
510 printf("\nSolving Pindyck Model using CONOPT:\n" );
511
512 CntVect1 = (coiHandle_t *) malloc( maxthread*sizeof(coiHandle_t) );
513/* Allocate pointers to maxthread Period structures and allocate the
514 structures themselves */
515 Usrmem = (struct Periods **)malloc( maxthread*sizeof(struct Periods *) );
516 for ( thread=0; thread<maxthread; thread++ )
517 {
518 Usrmem[thread] = (struct Periods *)malloc(sizeof(struct Periods));
519 }
520
521/* Populate Maxthread control vectors. Initially with the information
522 that is independent of the number of time periods */
523
524 COI_Error = 0;
525 for ( thread=0; thread<maxthread; thread++ )
526 {
527 CntVect1[thread] = NULL;
529 if (NULL==CntVect) {
530 printf("Could not create Conopt object: %s\n", msg);
531 exit(1);
532 }
533 CntVect1[thread] = CntVect;
534/* Objective: Maximize Constraint no 0 */
537/* Turn debugging of FDEval on or off */
539/* Register the necessary callback routines with CONOPT */
540 COI_Error += COIDEF_Message ( CntVect, &Pin_Message ); /* Register the callback Message */
541 COI_Error += COIDEF_ErrMsg ( CntVect, &Pin_ErrMsg ); /* Register the callback ErrMsg */
542 COI_Error += COIDEF_Status ( CntVect, &Pin_Status ); /* Register the callback Status */
543 COI_Error += COIDEF_Solution ( CntVect, &Pin_Solution ); /* Register the callback Solution */
544 COI_Error += COIDEF_ReadMatrix( CntVect, &Pin_ReadMatrix); /* Register the callback ReadMatrix */
545 COI_Error += COIDEF_FDEval ( CntVect, &Pin_FDEval); /* Register the callback FDEval */
546 COI_Error += COIDEF_UsrMem ( CntVect, (void *)Usrmem[thread]); /* Register one Usrmem position per thread */
547
548#if defined(LICENSE_INT_1) && defined(LICENSE_INT_2) && defined(LICENSE_INT_3) && defined(LICENSE_TEXT)
549 COI_Error += COIDEF_License ( CntVect, LICENSE_INT_1, LICENSE_INT_2, LICENSE_INT_3, LICENSE_TEXT);
550#endif
551 }
552 if ( COI_Error )
553 {
554 printf("Setup errors during loading of callback routines. COI_Error = %d\n",COI_Error);
555 c_log( "Skipping Solve due to errors loading callback routines", COI_Error);
556 }
557/* Store special values in xkeep */
558 for ( i = 0; i < Tmax*Tmax*Vpp; i++ ) xkeep[i] = -1234.5;
559/* Solve the model for Tmin to Tmax periods using a single thread. */
560 time0 = omp_get_wtime();
561 thread = 0;
562 for ( T = Tmin; T <= Tmax; T++ )
563 {
564/* Store the number of time periods in Usrmem to be used in the
565 callback routines */
566 Usrmem[thread]->NT = T;
567 CntVect = CntVect1[thread];
568/* Tell CONOPT about the sizes in the model */
569/* Number of variables (excl. slacks): 7 per period */
571
572/* Number of equations: 1 objective + 6 per period */
573 COI_Error += COIDEF_NumCon ( CntVect, 1+6*T );
574
575/* Number of nonzeros in the Jacobian. See the counting in */
576/* ReadMatrix above. For each period there is 1 in the objective, 16 */
577/* for unlagged variables and 4 for lagged variables. */
578 COI_Error += COIDEF_NumNz ( CntVect, 17*T + 4*(T-1) );
579
580/* Number of nonlinear nonzeros. 5 unlagged for each period. */
582 if ( COI_Error )
583 {
584 printf("Skipping COI_Solve due to setup errors. T = %d. COI_Error = %d\n", T, COI_Error);
585 c_log( "Skipping Solve due to setup errors", COI_Error);
586 }
587 printf("Starting to solve for T=%d using thread %d\n", T, thread );
588 COI_Error = COI_Solve ( CntVect ); /* Optimize */
589 printf("After solving for T = %d. COI_Error =%d\n", T, COI_Error);
590 }
591/* copy the solutions into xkeep1 */
592 printf("\n** Finished solving sequential loop.\n\n"); fflush(NULL);
593 time1 = omp_get_wtime() - time0;
594 for ( i = 0; i < Tmax*Tmax*Vpp; i++ ) xkeep1[i] = xkeep[i];
595 time0 = omp_get_wtime();
596#pragma omp parallel for default(shared) private(COI_Error,thread,CntVect) schedule(static)
597 for ( T = Tmax; T >= Tmin; T-- )
598 {
599 COI_Error = 0;
600/* Store the number of time periods in Usrmem to be used in the
601 callback routines */
602 thread = omp_get_thread_num();
603 printf("Solving period %d with thread %d.\n", T, thread); fflush(NULL);
604 Usrmem[thread]->NT = T;
605 CntVect = CntVect1[thread];
606/* Tell CONOPT about the sizes in the model */
607/* Number of variables (excl. slacks): 7 per period */
609
610/* Number of equations: 1 objective + 6 per period */
611 COI_Error += COIDEF_NumCon ( CntVect, 1+6*T );
612
613/* Number of nonzeros in the Jacobian. See the counting in */
614/* ReadMatrix above. For each period there is 1 in the objective, 16 */
615/* for unlagged variables and 4 for lagged variables. */
616 COI_Error += COIDEF_NumNz ( CntVect, 17*T+4*(T-1) );
617
618/* Number of nonlinear nonzeros. 5 unlagged for each period. */
620 COI_Error = COI_Solve ( CntVect ); /* Optimize */
621 printf("After solving for T = %d. COI_Error =%d\n", T, COI_Error); fflush(NULL);
622 }
623 time2 = omp_get_wtime() - time0;
624 printf("\n** Finished solving parallel loop with static schedule.\n\n"); fflush(NULL);
625 for ( i = 0; i < Tmax*Tmax*Vpp; i++ ) xkeep2[i] = xkeep[i];
626 time0 = omp_get_wtime();
627/* We redo the parallel loop with a dynamic schedule */
628#pragma omp parallel for default(shared) private(COI_Error,thread,CntVect) schedule(dynamic)
629 for ( T = Tmax; T >= Tmin; T-- )
630 {
631 COI_Error = 0;
632/* Store the number of time periods in Usrmem to be used in the
633 callback routines */
634 thread = omp_get_thread_num();
635 printf("Solving period %d with thread %d.\n", T, thread); fflush(NULL);
636 Usrmem[thread]->NT = T;
637 CntVect = CntVect1[thread];
638/* Tell CONOPT about the sizes in the model */
639/* Number of variables (excl. slacks): 7 per period */
641
642/* Number of equations: 1 objective + 6 per period */
643 COI_Error += COIDEF_NumCon ( CntVect, 1+6*T );
644
645/* Number of nonzeros in the Jacobian. See the counting in */
646/* ReadMatrix above. For each period there is 1 in the objective, 16 */
647/* for unlagged variables and 4 for lagged variables. */
648 COI_Error += COIDEF_NumNz ( CntVect, 17*T+4*(T-1) );
649
650/* Number of nonlinear nonzeros. 5 unlagged for each period. */
652 COI_Error = COI_Solve ( CntVect ); /* Optimize */
653 printf("After solving for T = %d. COI_Error =%d\n", T, COI_Error); fflush(NULL);
654 }
655 time3 = omp_get_wtime() - time0;
656 printf("\n** Finished solving parallel loop with dynamic schedule.\n\n"); fflush(NULL);
657 dif1 = 0;
658 dif2 = 0;
659 for ( i = 0; i < Tmax*Tmax*Vpp; i++ )
660 {
661 if ( xkeep1[i] != xkeep[i] ) dif1 = 1;
662 if ( xkeep2[i] != xkeep[i] ) dif2 = 1;
663 }
664 printf("\nEnd of PinThread Model.\n");
665 printf("Difference between base and static solutions = %d\n",dif1);
666 printf("Difference between base and dynamic solutions= %d\n",dif2);
667 printf("MaxThread = %d\n",maxthread);
668 printf("Time Single thread = %10.3f\n",time1);
669 printf("Time Static Multi thread = %10.3f\n",time2);
670 printf("Time Dynamic Multi thread = %10.3f\n",time3);
671 printf("Speedup, static = %10.3f\n",time1/time2);
672 printf("Speedup, dynamic = %10.3f\n",time1/time3);
673 printf("Efficiency, static = %10.3f\n",time1/time2/maxthread);
674 printf("Efficiency, dynamic = %10.3f\n",time1/time3/maxthread);
675
676 if ( COI_Error ) {
677 c_log( "Errors encountered during solution", COI_Error); }
678 else if ( stacalls == 0 || solcalls == 0 ) {
679 c_log( "Status or Solution routine was not called", -1); }
680 else if ( dif1 ) {
681 c_log( "Base and static solutions are different", -1); }
682 else if ( dif2 ) {
683 c_log( "Base and dynamic solutions are different", -1); }
684
685 for ( thread=0; thread<maxthread; thread++ )
686 {
687 CntVect = CntVect1[thread];
689 free(Usrmem[thread]);
690 }
691 free(Usrmem);
692 free(CntVect1);
693 coiFinalize();
694 c_log( "Successful Solve", OK );
695}
C language header file for direct linking against the COI library generated by apiwrapper for GAMS Ve...
int stacalls
Definition comdecl.h:4
char pname[MAXLINE]
Definition comdecl.h:10
char fname[MAXLINE]
Definition comdecl.h:11
coiHandle_t CntVect
Definition comdecl.h:14
#define START
Definition comdecl.h:13
#define MAXLINE
Definition comdecl.h:9
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
FILE * fs
Definition comdecl.h:2
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_UsrMem(coiHandle_t cntvect, void *usrmem)
provides a pointer to user memory that is available in all callback functions. NOTE: this is not a ca...
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.
void COI_CALLCONV coiFinalize(void)
finializes the solving process for CONOPT. This must be called when using OpenMP. It will terminate t...
int COI_CALLCONV coiCreate(coiHandle_t *cntvect)
initialises and create the control vector.
int COI_CALLCONV coiFree(coiHandle_t *cntvect)
frees the control vector.
int COI_CALLCONV COI_Solve(coiHandle_t cntvect)
method for starting the solving process of CONOPT.
int COI_CALLCONV Pin_ErrMsg(int ROWNO, int COLNO, int POSNO, const char *MSG, void *USRMEM)
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.
int main(int argc, char **argv)
Main program. A simple setup and call of CONOPT.
int COI_CALLCONV Pin_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)
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.
double xkeep2[Tmax *Tmax *Vpp]
int COI_CALLCONV Pin_Status(int MODSTA, int SOLSTA, int ITER, double OBJVAL, void *USRMEM)
void c_log(char *msgt, int code)
double xkeep[Tmax *Tmax *Vpp]
double xkeep1[Tmax *Tmax *Vpp]
int COI_CALLCONV Pin_Message(int SMSG, int DMSG, int NMSG, char *MSGV[], void *USRMEM)
coiHandle_t * CntVect1
Definition mp_qpbandb.c:48
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_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 pinadd.c:344
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 Tmin
Definition pinadd.c:15
#define Epp
Definition pinadd.c:18
#define Tmax
Definition pinadd.c:16
#define Vpp
Definition pinadd.c:17