/[ascend]/trunk/ascend4/solver/conopt.c
ViewVC logotype

Contents of /trunk/ascend4/solver/conopt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations) (download) (as text)
Fri Oct 29 20:54:12 2004 UTC (17 years, 6 months ago) by aw0a
File MIME type: text/x-csrc
File size: 17794 byte(s)
Setting up web subdirectory in repository
1 /*
2 * Definitions of CONOPT Subroutines
3 * by Vicente Rico-Ramirez
4 * Created: 07/97
5 * Version: $Revision: 1.5 $
6 * Version control file: $RCSfile: conopt.c,v $
7 * Date last modified: $Date: 1998/02/27 14:33:23 $
8 * Last modified by: $Author: mthomas $
9 *
10 * This file is part of the SLV solver.
11 *
12 * The SLV solver is free software; you can redistribute
13 * it and/or modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * The SLV solver is distributed in hope that it will be
18 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with the program; if not, write to the Free Software Foundation,
24 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
25 * COPYING. COPYING is found in ../compiler.
26 *
27 */
28
29 #include "utilities/ascConfig.h"
30 #include "solver/conopt.h"
31 #if defined(DYNAMIC_CONOPT)
32 #include "utilities/ascDynaLoad.h"
33 #include "solver/conoptdll.h"
34 #endif
35
36 /*
37 * is CONOPT available ?
38 */
39 #if (defined(STATIC_CONOPT) || defined(DYNAMIC_CONOPT))
40 #define CONOPT_ACTIVE TRUE
41 #else /* defined(STATIC_CONOPT) */
42 #define CONOPT_ACTIVE FALSE
43 #endif /* defined(STATIC_CONOPT) */
44
45 #if CONOPT_ACTIVE /* code used if CONOPT is available */
46
47 /*
48 * Optimization subroutines for CONOPT
49 * ---------------------------------
50 */
51
52 /*
53 * User-defined subroutines
54 * ------------------------
55 */
56
57 /*
58 * COIRMS Based on the information provided in Coispz, CONOPT will
59 * allocate the number of vectors into which the user can define
60 * the details of the model. The details of the model are defined
61 * here.
62 *
63 * COIRMS(lower, curr, upper, vsta, type,rhs, fv, esta, colsta,
64 * rowno, value, nlflag, n, m, n1, nz, usrmem)
65 *
66 * lower - lower bounds on the variables
67 * curr - intial values of the variables
68 * upper - upper bounds on the variables
69 * vsta - initial status of the variable(o nonbasic, 1 basic)
70 * type - types of equations (0 equality,1 greater,2 less)
71 * rhs - values of the right hand sides
72 * fv - sum of the nonlinear terms in the initial point
73 * esta - initial status of the slack in the constraint (nonbasic,basic)
74 * colsta- start of column pointers
75 * rowno - row or equation numbers of the nonzeros
76 * value - values of the jacobian elements
77 * nlflag- nonlinearity flags(0 nonzero constant,1 varying)
78 * n - number of variables
79 * m - number of constraints
80 * n1 - n+1
81 * nz - number of jacobian elements
82 * usrmem- user memory defined by conopt
83 */
84 void COIRMS(real64 *lower, real64 *curr, real64 *upper, int32 *vsta,
85 int32 *type, real64 *rhs, real64 *fv, int32 *esta, int32 *colsta,
86 int32 *rowno, real64 *value, int32 *nlflag, int32 *n, int32 *m,
87 int32 *n1, int32 *nz, real64 *usrmem)
88 {
89 conopt_pointers conopt_ptrs;
90 real64 **usr_mem;
91
92 usr_mem = (real64 **)usrmem;
93 conopt_ptrs = (conopt_pointers)usr_mem[0];
94 if (conopt_ptrs->coirms_ptr == NULL) {
95 return;
96 }
97 conopt_ptrs->coirms_ptr(lower, curr, upper, vsta, type, rhs, fv, esta,
98 colsta, rowno, value, nlflag, n, m, n1, nz,
99 usr_mem[1]);
100 }
101
102
103 /*
104 * COIFBL Defines the nonlinearities of the model by returning
105 * numerical values. It works on a block of rows during each call.
106 * COIFBL( x, g, otn, nto, from, to, jac, stcl, rnum, cnum, nl, strw,
107 * llen, indx, mode, errcnt, n, m, n1, m1, nz, usrmem)
108 *
109 * x - punt of evaluation provided by conopt
110 * g - vector of function values
111 * otn - old to new permutation vector
112 * nto - new to old permutation vector
113 * from - range in permutation
114 * to - range in permutation
115 * jac - vector of jacobian values.
116 * The following are vectors defining the jacobian structure
117 * stcl - start of column pointers
118 * rnum - row numbers
119 * cnum - column numbers
120 * nl - nonlinearity flags
121 * strw - start row pointers
122 * llen - count of linear jacobian elements
123 * indx - pointers from the row-wise representation
124 * mode - indicator of mode of evaluation
125 * errcnt- number of function evaluation errors
126 * n - umber of variables
127 * m - number of constraints
128 * n1 - n+1
129 * m1 - m+1
130 * nz - number of jacobian elements
131 * usrmem- user memory defined by conopt
132 */
133 void COIFBL(real64 *x, real64 *g, int32 *otn, int32 *nto, int32 *from,
134 int32 *to, real64 *jac, int32 *stcl, int32 *rnum, int32 *cnum,
135 int32 *nl, int32 *strw, int32 *llen, int32 *indx, int32 *mode,
136 int32 *errcnt, int32 *n, int32 *m, int32 *n1, int32 *m1,
137 int32 *nz, real64 *usrmem)
138 {
139 conopt_pointers conopt_ptrs;
140 real64 **usr_mem;
141
142 usr_mem = (real64 **)usrmem;
143 conopt_ptrs = (conopt_pointers)usr_mem[0];
144 if (conopt_ptrs->coifbl_ptr == NULL) {
145 return;
146 }
147 conopt_ptrs->coifbl_ptr(x, g, otn, nto, from, to, jac, stcl, rnum, cnum,
148 nl, strw, llen, indx, mode, errcnt, n, m, n1, m1,
149 nz, usr_mem[1]);
150
151 }
152
153 /*
154 * COIFDE Defines the nonlinearities of the model by returning
155 * numerical values. It works on one row or equation at a time
156 * COIFDE(x, g, jac, rowno, jcnm, mode, errcnt, newpt, n, nj, usrmem)
157 *
158 * x - punt of evaluation provided by conopt
159 * g - function value
160 * jac - jacobian values
161 * rowno - number of the row for which nonlinearities will be eval
162 * jcnm - list of column number fon the NL nonzeros
163 * mode - indicator of mode of evaluation
164 * errcnt - sum of number of func evaluation errors thus far
165 * newpt - new point indicator
166 * nj - number of nonlinear nonzero jacobian elements
167 * n - number of variables
168 * usrmem - user memory
169 */
170 void COIFDE(real64 *x, real64 *g, real64 *jac, int32 *rowno, int32 *jcnm,
171 int32 *mode, int32 *errcnt, int32 *newpt, int32 *n, int32 *nj,
172 real64 *usrmem)
173 {
174 conopt_pointers conopt_ptrs;
175 real64 **usr_mem;
176
177 usr_mem = (real64 **)usrmem;
178
179 conopt_ptrs = (conopt_pointers)usr_mem[0];
180 if (conopt_ptrs->coifde_ptr == NULL) {
181 return;
182 }
183 conopt_ptrs->coifde_ptr(x, g, jac, rowno, jcnm, mode, errcnt, newpt, n,
184 nj, usr_mem[1]);
185 }
186
187
188
189 /*
190 * COISTA Pass the solution from CONOPT to the modeler. It returns
191 * completion status
192 * COISTA(modsta, solsts, iter, objval, usrmem)
193 *
194 * modsta - model status
195 * solsta - solver status
196 * iter - number of iterations
197 * objval - objective value
198 * usrmem - user memory
199 */
200 void COISTA(int32 *modsta, int32 *solsta, int32 *iter, real64 *objval,
201 real64 *usrmem)
202 {
203 conopt_pointers conopt_ptrs;
204 real64 **usr_mem;
205
206 usr_mem = (real64 **)usrmem;
207
208 conopt_ptrs = (conopt_pointers)usr_mem[0];
209 if (conopt_ptrs->coista_ptr == NULL) {
210 return;
211 }
212 conopt_ptrs->coista_ptr(modsta, solsta, iter, objval, usr_mem[1]);
213 }
214
215
216 /*
217 * COIRS passes the solution from CONOPT to the modeler. It returns
218 * solution values
219 * COIRS(val, xmar, xbas, xsta, yval, ymar, ybas, ysta, n, m, usrmem)
220 *
221 * xval - the solution values of the variables
222 * xmar - corresponding marginal values
223 * xbas - basis indicator for column (at bound, basic, nonbasic)
224 * xsta - status of column (normal, nonoptimal, infeasible,unbounded)
225 * yval - values of the left hand side in all the rows
226 * ymar - corresponding marginal values
227 * ybas - basis indicator for row
228 * ysta - status of row
229 * n - number of variables
230 * m - number of constraints
231 * usrmem - user memory
232 */
233 void COIRS(real64 *xval, real64 *xmar, int32 *xbas, int32 *xsta, real64 *yval,
234 real64 *ymar, int32 *ybas, int32 * ysta, int32 *n, int32 *m,
235 real64 *usrmem)
236 {
237 conopt_pointers conopt_ptrs;
238 real64 **usr_mem;
239
240 usr_mem = (real64 **)usrmem;
241
242 conopt_ptrs = (conopt_pointers)usr_mem[0];
243 if (conopt_ptrs->coirs_ptr == NULL) {
244 return;
245 }
246 conopt_ptrs->coirs_ptr(xval, xmar, xbas, xsta, yval, ymar, ybas, ysta,
247 n, m, usr_mem[1]);
248 }
249
250
251 /*
252 * COIUSZ communicates and update of an existing model to CONOPT
253 * COIUSZ(nintg, ipsz, nreal, rpsz, usrmem)
254 *
255 * nintg - number of positions in ipsz
256 * ipsz - array describing problem size and options
257 * nreal - number of positions in rpsz
258 * rpsz - array of reals describing problem size and options
259 * usrmem- user memory
260 */
261 void COIUSZ(int32 *nintg, int32 *ipsz, int32 *nreal, real64 *rpsz,
262 real64 *usrmem)
263 {
264 conopt_pointers conopt_ptrs;
265 real64 **usr_mem;
266
267 usr_mem = (real64 **)usrmem;
268
269 conopt_ptrs = (conopt_pointers)usr_mem[0];
270 if (conopt_ptrs->coiusz_ptr == NULL) {
271 return;
272 }
273 conopt_ptrs->coiusz_ptr(nintg, ipsz, nreal, rpsz, usr_mem[1]);
274 }
275
276
277 /*
278 * COIOPT communicates non-default option values to CONOPT
279 * COIOPT(name, rval, ival, lval, usrmem)
280 * name - the name of a CONOPT CR-cell defined by the modeler
281 * rval - the value to be assigned to name if the cells contains a real
282 * ival - the value to be assigned to name if the cells contains an int
283 * lval - the value to be assigned to name if the cells contains a log value
284 * usrmem - user memory
285 */
286 void COIOPT(char *name, real64 *rval, int32 *ival, int32 *logical,
287 real64 *usrmem)
288 {
289 conopt_pointers conopt_ptrs;
290 real64 **usr_mem;
291
292 usr_mem = (real64 **)usrmem;
293
294 conopt_ptrs = (conopt_pointers)usr_mem[0];
295 if (conopt_ptrs->coiopt_ptr == NULL) {
296 return;
297 }
298 conopt_ptrs->coiopt_ptr(name, rval, ival, logical, usr_mem[1]);
299 }
300
301
302 /*
303 * COIPSZ communicates the model size and structure to CONOPT
304 * COIPSZ(nintgr, ipsz, nreal, rpsz, usrmem)
305 *
306 * ningtr - number of positions in ipsz
307 * ipsz - array describing problem size and options
308 * nreal - number of positions in rpsz
309 * rpsz - array of reals describing problem size and options
310 * usrmem - user memory
311 */
312 void COIPSZ(int32 *nintgr, int32 *ipsz, int32 *nreal, real64 *rpsz,
313 real64 *usrmem)
314 {
315 conopt_pointers conopt_ptrs;
316 real64 **usr_mem;
317
318 usr_mem = (real64 **)usrmem;
319
320 conopt_ptrs = (conopt_pointers)usr_mem[0];
321 if (conopt_ptrs->coipsz_ptr == NULL) {
322 return;
323 }
324 conopt_ptrs->coipsz_ptr(nintgr, ipsz, nreal, rpsz, usr_mem[1]);
325 }
326
327
328 extern void COIMSG (int32 *nmsg, int32 *smsg, int32 *llen,
329 char msgv[80*15],real64 *usrmem)
330 {
331 conopt_pointers conopt_ptrs;
332 real64 **usr_mem;
333
334 usr_mem = (real64 **)usrmem;
335
336 conopt_ptrs = (conopt_pointers)usr_mem[0];
337 if (conopt_ptrs->coimsg_ptr == NULL) {
338 return;
339 }
340 conopt_ptrs->coimsg_ptr(nmsg, smsg, llen, msgv, usr_mem[1]);
341 }
342
343 extern void COISCR (char msg[80], int32 *len)
344 {
345 FPRINTF(stdout,"%.*s\n",*len,&msg[0]);
346 }
347
348 extern void COIEC (int32 *colno, int32 *msglen, char msg[80],real64 *usrmem)
349 {
350 conopt_pointers conopt_ptrs;
351 real64 **usr_mem;
352
353 usr_mem = (real64 **)usrmem;
354
355 conopt_ptrs = (conopt_pointers)usr_mem[0];
356 if (conopt_ptrs->coiec_ptr == NULL) {
357 return;
358 }
359 conopt_ptrs->coiec_ptr(colno, msglen, msg, usr_mem[1]);
360 }
361
362 extern void COIER (int32 *rowno, int32 *msglen, char msg[80],real64 *usrmem)
363 {
364 conopt_pointers conopt_ptrs;
365 real64 **usr_mem;
366
367 usr_mem = (real64 **)usrmem;
368
369 conopt_ptrs = (conopt_pointers)usr_mem[0];
370 if (conopt_ptrs->coier_ptr == NULL) {
371 return;
372 }
373 conopt_ptrs->coier_ptr(rowno, msglen, msg, usr_mem[1]);
374 }
375
376 extern void COIENZ (int32 *colno, int32 *rowno, int32 *posno,
377 int32 *msglen, char msg[80],real64 *usrmem)
378 {
379 conopt_pointers conopt_ptrs;
380 real64 **usr_mem;
381
382 usr_mem = (real64 **)usrmem;
383
384 conopt_ptrs = (conopt_pointers)usr_mem[0];
385 if (conopt_ptrs->coienz_ptr == NULL) {
386 return;
387 }
388 conopt_ptrs->coienz_ptr(colno, rowno, posno, msglen, msg, usr_mem[1]);
389 }
390
391 extern void COIPRG (int32 *nintgr, int32 *intrep, int32 *nreal,
392 real64 *rl, real64 *x, real64 *usrmem, int32 *finish)
393 {
394 conopt_pointers conopt_ptrs;
395 real64 **usr_mem;
396
397 usr_mem = (real64 **)usrmem;
398
399 conopt_ptrs = (conopt_pointers)usr_mem[0];
400 if (conopt_ptrs->coiprg_ptr == NULL) {
401 return;
402 }
403 conopt_ptrs->coiprg_ptr(nintgr, intrep, nreal, rl, x, usr_mem[1], finish);
404 }
405
406 extern void COIORC (int32 *colno, int32 *rowno, real64 *value,
407 real64 *resid,real64 *usrmem)
408 {
409 conopt_pointers conopt_ptrs;
410 real64 **usr_mem;
411
412 usr_mem = (real64 **)usrmem;
413
414 conopt_ptrs = (conopt_pointers)usr_mem[0];
415 if (conopt_ptrs->coiorc_ptr == NULL) {
416 return;
417 }
418 conopt_ptrs->coiorc_ptr(colno, rowno, value, resid, usr_mem[1]);
419 }
420
421 #if defined(DYNAMIC_CONOPT)
422 REGISTER_CONOPT_FUNCTION_FUNC *register_conopt_function;
423 UNREGISTER_CONOPT_FUNCTION_FUNC *unregister_conopt_function;
424 COICRM_FUNC *COICRM;
425 COICSM_FUNC *COICSM;
426 COIMEM_FUNC *COIMEM;
427 #endif /* DYNAMIC_CONOPT */
428
429 /*
430 * Provided subroutines coicsm and coimem
431 * --------------------------------------
432 */
433 /*
434 * IMPORTANT: The use of the following functions is a H A C K to aovid
435 * unresolved externals while linking to the CONOPT library. For some
436 * reason, the linker wants the calls to the provided subroutines
437 * COICSM and COIMEM in the same file as the definition of the user
438 * defined CONOPT subroutines
439 */
440 /*
441 * Memory estimation by using CONOPT subroutine coimem
442 *
443 * COIMEM Estimates the amount of memory needed by CONOPT
444 * COIMEM(nintgr, ipsz, minmem, estmem)
445 *
446 * nintgr - number of elements in the array ipsz. Should be 3.
447 * ipsz - vector of integers to describe the size of the model
448 * minmem - Minimum estimate for the memory needed. Measured in
449 * number of real elements of work
450 * estmem - Estimate of the amount of memory
451 */
452 void conopt_estimate_memory(int32 *nintgr, int32 *ipsz, int32 *minmem,
453 int32 *estmem)
454 {
455 COIMEM(nintgr, ipsz, minmem, estmem);
456 }
457
458
459 /*
460 * COICRM restarts CONOPT with user memory
461 * COICRM(kept, usrmem, lwork, work, maxusd, curusd)
462 *
463 * kept - Whether CONOPT has kept the model after solving it or not
464 * usrmem - array passed to all subroutines. If not needed is dummy array
465 * lwork - lenght of working array work
466 * work - working array supplied by the user
467 * maxusd - maximum amount of memory in work used during optimization
468 * curusd - current amount of memory in use
469 */
470 void conopt_restart(int32 *kept, real64 **usrmem, int32 *lwork, real64 *work,
471 int32 *maxusd, int32 *curusd)
472 {
473 real64 *usr_mem;
474 usr_mem = (real64 *)usrmem;
475
476 FPRINTF(ASCERR,"\n");
477 FPRINTF(ASCERR,"Restarting Conopt\n");
478 FPRINTF(ASCERR,"\n");
479
480 COICRM(kept, usr_mem, lwork, work, maxusd,curusd);
481 }
482
483
484 /*
485 * COICSM starts up CONOPT with user memory
486 * COICSM(kept, usrmem, lwork, work, maxusd, curusd)
487 *
488 * kept - Whether CONOPT has kept the model after solving it or not
489 * usrmem - array passed to all subroutines. If not needed is dummy array
490 * lwork - lenght of working array work
491 * work - working array supplied by the user
492 * maxusd - maximum amount of memory in work used during optimization
493 * curusd - current amount of memory in use
494 */
495 void conopt_start(int32 *kept, real64 **usrmem, int32 *lwork, real64 *work,
496 int32 *maxusd, int32 *curusd)
497 {
498 conopt_pointers conopt_ptrs;
499 real64 *usr_mem;
500 usr_mem = (real64 *)usrmem;
501
502 FPRINTF(ASCERR,"\n");
503 FPRINTF(ASCERR,"Starting Conopt\n");
504 FPRINTF(ASCERR,"\n");
505
506 #if defined(DYNAMIC_CONOPT)
507 conopt_ptrs = (conopt_pointers)usrmem[0];
508
509 register_conopt_function(COIRMS_ENUM,
510 conopt_ptrs->coirms_ptr == NULL ? NULL : (void *)COIRMS);
511 register_conopt_function(COIFBL_ENUM,
512 conopt_ptrs->coifbl_ptr == NULL ? NULL : (void *)COIFBL);
513 register_conopt_function(COIFDE_ENUM,
514 conopt_ptrs->coifde_ptr == NULL ? NULL : (void *)COIFDE);
515 register_conopt_function(COIRS_ENUM,
516 conopt_ptrs->coirs_ptr == NULL ? NULL : (void *)COIRS);
517 register_conopt_function(COISTA_ENUM,
518 conopt_ptrs->coista_ptr == NULL ? NULL : (void *)COISTA);
519 register_conopt_function(COIUSZ_ENUM,
520 conopt_ptrs->coiusz_ptr == NULL ? NULL : (void *)COIUSZ);
521 register_conopt_function(COIOPT_ENUM,
522 conopt_ptrs->coiopt_ptr == NULL ? NULL : (void *)COIOPT);
523 register_conopt_function(COIPSZ_ENUM,
524 conopt_ptrs->coipsz_ptr == NULL ? NULL : (void *)COIPSZ);
525
526 register_conopt_function(COIMSG_ENUM,
527 conopt_ptrs->coimsg_ptr == NULL ? NULL : (void *)COIMSG);
528 register_conopt_function(COISCR_ENUM,(void *)COISCR);
529 register_conopt_function(COIEC_ENUM,
530 conopt_ptrs->coiec_ptr == NULL ? NULL : (void *)COIEC);
531 register_conopt_function(COIER_ENUM,
532 conopt_ptrs->coier_ptr == NULL ? NULL : (void *)COIER);
533 register_conopt_function(COIENZ_ENUM,
534 conopt_ptrs->coienz_ptr == NULL ? NULL : (void *)COIENZ);
535 register_conopt_function(COIPRG_ENUM,
536 conopt_ptrs->coiprg_ptr == NULL ? NULL : (void *)COIPRG);
537 register_conopt_function(COIORC_ENUM,
538 conopt_ptrs->coiorc_ptr == NULL ? NULL : (void *)COIORC);
539
540 #endif /* DYNAMIC_CONOPT */
541 COICSM(kept, usr_mem, lwork, work, maxusd,curusd);
542 }
543 #if defined(DYNAMIC_CONOPT)
544 int32 conopt_loaded = 1;
545
546 int32 conopt_load(void) {
547 int32 status;
548 if (conopt_loaded == 0) {
549 return 0; /* allready loaded */
550 }
551 status = Asc_DynamicLoad("dllcnsub.dll", NULL);
552 if (status != 0) {
553 return 1; /* failure */
554 }
555 register_conopt_function =
556 (REGISTER_CONOPT_FUNCTION_FUNC *)Asc_DynamicSymbol("dllcnsub.dll",
557 "register_conopt_function");
558 unregister_conopt_function =
559 (UNREGISTER_CONOPT_FUNCTION_FUNC *)Asc_DynamicSymbol("dllcnsub.dll",
560 "unregister_conopt_function");
561 COICRM = (COICRM_FUNC *)Asc_DynamicSymbol("dllcnsub.dll","COICRM");
562 COICSM = (COICSM_FUNC *)Asc_DynamicSymbol("dllcnsub.dll","COICSM");
563 COIMEM = (COIMEM_FUNC *)Asc_DynamicSymbol("dllcnsub.dll","COIMEM");
564 if (register_conopt_function == NULL ||
565 unregister_conopt_function == NULL ||
566 COICRM == NULL ||
567 COICSM == NULL ||
568 COIMEM == NULL) {
569 return 1; /* failure */
570 }
571 conopt_loaded = 0;
572 return 0;
573 }
574 #endif /* DYNAMIC_CONOPT */
575 #endif /* CONOPT_ACTIVE */

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22