/[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 917 - (show annotations) (download) (as text)
Thu Nov 2 21:34:59 2006 UTC (16 years, 3 months ago) by johnpye
File MIME type: text/x-csrc
File size: 8921 byte(s)
Added some debug stuff to work on the on_load problem.
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("Searching in path '%s' (from env var '%s')",getenv(envvar),envvar);
114 }/*else{
115 CONSOLE_DEBUG("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 value of env var '%s' and/or default path '%s')"
123 , libname, envvar, ASC_CONOPT_DLPATH
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 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 CONSOLE_DEBUG("CONOPT has finished Optimizing");
262 CONSOLE_DEBUG("Model status = %8d", *MODSTA);
263 CONSOLE_DEBUG("Solver status = %8d", *SOLSTA);
264 CONSOLE_DEBUG("Iteration count = %8d", *ITER);
265 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 default: t = ASC_PROG_ERR; modsta = "UNKNOWN MODSTA";
275 }
276 const char *solsta;
277 switch(*SOLSTA){
278 case 1: solsta = "normal completion"; break;
279 case 2: t = ASC_USER_NOTE; solsta = "iteration interrupted"; break;
280 case 3: t = ASC_PROG_NOTE; solsta = "time limit exceeded"; break;
281 case 4: t = ASC_PROG_ERR; solsta = "failed (terminated by solver)"; break;
282 default: t = ASC_PROG_ERR; solsta = "UNKNOWN SOLSTA";
283 }
284
285 CONSOLE_DEBUG("CONOPT %s (%d): %s (%d)", solsta, *SOLSTA, modsta, *MODSTA);
286 ERROR_REPORTER_NOLINE(t,"CONOPT %s: %s", solsta, modsta);
287
288 return 0;
289 }
290
291 int COI_CALL asc_conopt_solution( double* XVAL, double* XMAR, int* XBAS
292 , int* XSTA, double* YVAL, double* YMAR, int* YBAS, int* YSTA
293 , int* N, int* M, double* USRMEM
294 ){
295 /* Standard Solution routine */
296 int i;
297 char *status[4] = {"Lower","Upper","Basic","Super"};
298 FILE *fd = stderr;
299
300 fprintf(fd,"\n Variable Solution value Reduced cost Status\n\n");
301 for ( i=0; i<*N; i++ )
302 fprintf(fd,"%6d%18f%18f%10s\n", i, XVAL[i], XMAR[i], status[XBAS[i]] );
303 fprintf(fd,"\n Constrnt Activity level Marginal cost Status\n\n");
304 for ( i=0; i<*M; i++ )
305 fprintf(fd,"%6d%18f%18f%10s\n", i, YVAL[i], YMAR[i], status[YBAS[i]] );
306
307 return 0;
308 }

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