/[ascend]/trunk/base/generic/solver/conopt.c
ViewVC logotype

Contents of /trunk/base/generic/solver/conopt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 843 - (show annotations) (download) (as text)
Sun Sep 10 06:18:24 2006 UTC (14 years ago) by johnpye
File MIME type: text/x-csrc
File size: 8754 byte(s)
Changed over to ASC_NEW* for some solver memory allocation.
Fixed up file headers.
Change debug and error output to use new mechanism.
1 /* ASCEND modelling environment
2 Copyright (C) 2006 Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18 *//**
19 @file
20 This file allows CONOPT to be dlopened at runtime.
21 *//*
22 By John Pye
23 Based on conopt.c by Vicente Rico Ramirez (created 05/97)
24 */
25
26 #include <utilities/config.h>
27 #include <utilities/ascConfig.h>
28 #include <utilities/error.h>
29 #include <utilities/ascEnvVar.h>
30 #include <general/env.h>
31 #include "conopt.h"
32
33 #ifndef ASC_WITH_CONOPT
34 # error "Shouldn't compile this file unless ASC_WITH_CONOPT set"
35 #endif
36
37 #ifndef ASC_LINKED_CONOPT
38 # include <ctype.h>
39 # include <utilities/ascMalloc.h>
40 # include <utilities/ascDynaLoad.h>
41
42 /*------------------------------------------------------------------------------
43 DLOPENING CONOPT SUPPORT FUNCTIONS
44 */
45
46 # define INTINT (int*cntvect,int*v)
47 # define INTINT1 (cntvect,v)
48 # define INTDOUBLE (int*cntvect,double*v)
49 # define INTDOUBLE1 (cntvect,v)
50 # define SEMICOLON ;
51 # define SPACE
52
53 /*
54 Typedefs for the various function pointers
55 */
56 # define FN_TYPE_DECL(T,A,V,L) \
57 typedef int COI_CALL (T##_fn_t) A
58
59 CONOPT_FNS(FN_TYPE_DECL,SEMICOLON);
60 # undef FN_TYPE_DECL
61
62 /*
63 Define a struct to hold all the function pointers, then
64 declare it as a global variable.
65 */
66 # define FN_PTR_DECL(T,A,V,L) \
67 T##_fn_t* T##_ptr
68
69 typedef struct{
70 CONOPT_FNS(FN_PTR_DECL,SEMICOLON);
71 } conopt_fptrs_t;
72 # undef FN_PTR_DECL
73
74 conopt_fptrs_t conopt_fptrs;
75
76
77 /*
78 Declare local functions to hook into the DLL
79 */
80 # define FN_PTR_EXEC(T,A,V,L) \
81 int COI_CALL T A{ \
82 if(conopt_fptrs.T##_ptr==NULL){ \
83 return 1; \
84 } \
85 return (* conopt_fptrs.T##_ptr) V ; \
86 }
87
88 CONOPT_FNS(FN_PTR_EXEC,SPACE)
89
90 # undef FN_PTR_EXEC
91
92 /**
93 This funciton will load the DLL and resolve all the required symbols
94 */
95 int asc_conopt_load(){
96 static int loaded=0;
97 char *libpath;
98 int status;
99 char fnsymbol[400], *c;
100 const char *libname=ASC_CONOPT_LIB;
101 const char *envvar;
102
103 if(loaded) {
104 return 0; /* already loaded */
105 }
106
107 CONSOLE_DEBUG("LOADING CONOPT...");
108
109 envvar = ASC_CONOPT_ENVVAR;
110
111 /* need to import this variable into the ascend 'environment' */
112 if(-1!=env_import(ASC_CONOPT_ENVVAR,getenv,Asc_PutEnv)){
113 CONSOLE_DEBUG("Using searchpath env var %s = %s",envvar,getenv(envvar));
114 }else{
115 CONSOLE_DEBUG("Using default conopt search path: %s", ASC_CONOPT_DLPATH);
116 }
117
118 libpath = SearchArchiveLibraryPath(libname, ASC_CONOPT_DLPATH, envvar);
119
120 if(libpath==NULL){
121 ERROR_REPORTER_NOLINE(ASC_PROG_ERR
122 , "Library '%s' could not be located (check env var %s)"
123 , libname, envvar
124 );
125 return 1;
126 }
127
128 status = Asc_DynamicLoad(libpath, NULL);
129 if (status != 0) {
130 ASC_FREE(libpath);
131 return 1; /* failed to load */
132 }
133
134 # if defined(FNAME_UCASE_NODECOR) || defined(FNAME_UCASE_DECOR) || defined(FNAME_UCASE_PREDECOR)
135 # define FNCASE(C) C=toupper(C)
136 # elif defined(FNAME_LCASE_NODECOR) || defined(FNAME_LCASE_DECOR)
137 # define FNCASE(C) C=tolower(C)
138 # else
139 # error "CONOPT case rule not defined"
140 # endif
141
142 # if defined(FNAME_UCASE_DECOR) || defined(FNAME_LCASE_DECOR)
143 # define FNDECOR(S,L) strcat(S,"_")
144 # elif defined(FNAME_UCASE_PREDECOR) /* on windows, precede with _ and append @L (integer value of L) */
145 # define FNDECOR(S,L) strcat(S,L);for(c=S+strlen(S)+1;c>S;--c){*c=*(c-1);} *S='_';
146 # else
147 # define FNDECOR(S,L) (void)0
148 # endif
149
150 # define FN_PTR_GET(T,A,V,L) \
151 sprintf(fnsymbol,"%s",#T); \
152 for(c=fnsymbol;*c!='\0';++c){ \
153 FNCASE(*c); \
154 } \
155 FNDECOR(fnsymbol,L); \
156 conopt_fptrs.T##_ptr = (T##_fn_t *)Asc_DynamicFunction(libpath,fnsymbol); \
157 if(conopt_fptrs.T##_ptr==NULL)status+=1;
158
159 CONOPT_FNS(FN_PTR_GET,SPACE)
160
161 # undef FN_PTR_GET
162 # undef FNDECOR
163 # undef FNCASE
164
165 ASC_FREE(libpath);
166
167 if(status!=0){
168 return 1; /* faile to result all symbols */
169 }
170
171 loaded = 1;
172 return 0;
173 }
174
175 #endif
176
177 /*-----------------------------------------------------------------------------
178 std.c
179
180 This file has some 'standard' implementations for the mandatory
181 callback routines Message, ErrMsg, Status, and Solution.
182 The routines use global file pointers, so they are only intended
183 as examples that can be used for further refinements.
184 */
185
186 #define MAXLINE 133 /* maximum line length plus an extra character
187 for the null terminator */
188
189 int COI_CALL asc_conopt_progress( int* LEN_INT, int* INT
190 , int* LEN_RL, double* RL, double* X, double* USRMEM
191 ){
192 /*(void)CONSOLE_DEBUG("Iteration %d, phase %d: %d infeasible, %d non-optimal; objective = %e"
193 , INT[0], INT[1], INT[2], INT[3], RL[1]
194 );*/
195 /* NEED TO IMPLEMENT SOME KIND OF CALLBACK TO THE SOLVERREPORTER */
196 return 0;
197 }
198
199 int COI_CALL asc_conopt_message( int* SMSG, int* DMSG, int* NMSG, int* LLEN
200 ,double* USRMEM, char* MSGV, int MSGLEN
201 ){
202 /* This implementation is writing the screen file to stdout
203 the documentation file to a file opened in main with the name
204 document.txt and the status file to a file with the name
205 status.txt. */
206 int i,j,k,l;
207 char line[MAXLINE];
208 k = 0;
209 for( i=0; i<*SMSG;i++ ){
210 j = LLEN[i];
211 for( l= 0; l<j; l++ ) line[l] = MSGV[k+l];
212 line[j] = '\0';
213 (void)CONSOLE_DEBUG("%s", line);
214 k += MSGLEN;
215 }
216 /* k = 0;
217 for( i=0; i<*DMSG;i++ ){
218 j = LLEN[i];
219 for( l= 0; l<j; l++ ) line[l] = MSGV[k+l];
220 line[j] = '\0';
221 ERROR_REPORTER_NOLINE(ASC_PROG_NOTE,"%s\n", line);
222 k += MSGLEN;
223 }
224 */
225 k = 0;
226 for( i=0; i<*NMSG;i++ ){
227 j = LLEN[i];
228 for( l= 0; l<j; l++ ) line[l] = MSGV[k+l];
229 line[j] = '\0';
230 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"%s\n", line);
231 k += MSGLEN;
232 }
233 return 0;
234 }
235
236 int COI_CALL asc_conopt_errmsg( int* ROWNO, int* COLNO, int* POSNO, int* MSGLEN
237 , double* USRMEM, char* MSG, int LENMSG
238 ){
239 /* Standard ErrMsg routine. Write to Documentation and Status file*/
240 int j,l;
241 char line[MAXLINE];
242 ERROR_REPORTER_START_NOLINE(ASC_PROG_ERR);
243 if ( *ROWNO == -1 ) {
244 FPRINTF(ASCERR,"Variable %d : ",*COLNO); }
245 else if ( *COLNO == -1 ) {
246 FPRINTF(ASCERR,"Equation %d : ",*ROWNO); }
247 else {
248 FPRINTF(ASCERR,"Variable %d appearing in Equation %d : ",*COLNO, *ROWNO); }
249 j = *MSGLEN;
250 for( l= 0; l<j; l++ ) line[l] = MSG[l];
251 line[j] = '\0';
252 FPRINTF(ASCERR,"%s\n", line);
253 error_reporter_end_flush();
254 return 0;
255 }
256
257 int COI_CALL asc_conopt_status(int* MODSTA, int* SOLSTA
258 , int* ITER, double* OBJVAL, double* USRMEM
259 ){
260 /* Standard Status routine. Write to all files */
261 (void)CONSOLE_DEBUG("CONOPT has finished Optimizing");
262 (void)CONSOLE_DEBUG("Model status = %8d", *MODSTA);
263 (void)CONSOLE_DEBUG("Solver status = %8d", *SOLSTA);
264 (void)CONSOLE_DEBUG("Iteration count = %8d", *ITER);
265 (void)CONSOLE_DEBUG("Objective value = %10f", *OBJVAL);
266
267 const char *modsta;
268 error_severity_t t = ASC_USER_SUCCESS;
269 switch(*MODSTA){
270 case 1: modsta = "optimal"; break;
271 case 2: modsta = "locally optimal"; break;
272 case 3: t = ASC_USER_ERROR; modsta = "unbounded"; break;
273 case 4: t = ASC_USER_ERROR; modsta = "infeasible"; break;
274 }
275 const char *solsta;
276 switch(*SOLSTA){
277 case 1: solsta = "normal completion"; break;
278 case 2: t = ASC_USER_NOTE; solsta = "iteration interrupted"; break;
279 case 3: t = ASC_PROG_NOTE; solsta = "time limit exceeded"; break;
280 case 4: t = ASC_PROG_ERR; solsta = "failed (terminated by solver)"; break;
281 }
282
283 (void)CONSOLE_DEBUG("CONOPT %s: %s", solsta, modsta);
284 ERROR_REPORTER_NOLINE(t,"CONOPT %s: %s", solsta, modsta);
285
286 return 0;
287 }
288
289 int COI_CALL asc_conopt_solution( double* XVAL, double* XMAR, int* XBAS
290 , int* XSTA, double* YVAL, double* YMAR, int* YBAS, int* YSTA
291 , int* N, int* M, double* USRMEM
292 ){
293 /* Standard Solution routine */
294 int i;
295 char *status[4] = {"Lower","Upper","Basic","Super"};
296 FILE *fd = stderr;
297
298 fprintf(fd,"\n Variable Solution value Reduced cost Status\n\n");
299 for ( i=0; i<*N; i++ )
300 fprintf(fd,"%6d%18f%18f%10s\n", i, XVAL[i], XMAR[i], status[XBAS[i]] );
301 fprintf(fd,"\n Constrnt Activity level Marginal cost Status\n\n");
302 for ( i=0; i<*M; i++ )
303 fprintf(fd,"%6d%18f%18f%10s\n", i, YVAL[i], YMAR[i], status[YBAS[i]] );
304
305 return 0;
306 }

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