1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 2007-2011 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 |
*//** @file |
19 |
Encapsulation of the NLA solver interface, separate from the |
20 |
system definition and access routines. |
21 |
*//* |
22 |
created from bits of slv.c, slv_stdcalls.c, etc. |
23 |
John Pye, 2007. |
24 |
*/ |
25 |
|
26 |
#ifndef ASC_SOLVER_H |
27 |
#define ASC_SOLVER_H |
28 |
|
29 |
#include <ascend/general/platform.h> |
30 |
#include <ascend/system/slv_client.h> |
31 |
|
32 |
/** @addtogroup solver_api Solver API |
33 |
@{ |
34 |
*/ |
35 |
|
36 |
/*----------------------------------------------------------------------- |
37 |
SOLVER HOOKS AND REGISTRATION DATA STRUCTURE |
38 |
*/ |
39 |
|
40 |
/** @todo We will explain all these later in this file someday soon. */ |
41 |
typedef SlvClientToken (SlvClientCreateF) (slv_system_t,int *); |
42 |
typedef int (SlvClientDestroyF) (slv_system_t,SlvClientToken); |
43 |
typedef int (SlvClientEligibleF) (slv_system_t); |
44 |
typedef int32 (SlvGetDefParamsF) (slv_system_t,SlvClientToken,slv_parameters_t *); |
45 |
typedef void (SlvGetParamsF) (slv_system_t, SlvClientToken, slv_parameters_t *); |
46 |
typedef void (SlvSetParamsF) (slv_system_t, SlvClientToken, slv_parameters_t *); |
47 |
typedef int (SlvGetStatusF) (slv_system_t, SlvClientToken, slv_status_t *); |
48 |
typedef linsolqr_system_t (SlvGetLinSysF)(slv_system_t, SlvClientToken); |
49 |
typedef mtx_matrix_t (SlvGetSysMtxF)(slv_system_t, SlvClientToken); |
50 |
typedef void (SlvDumpInfoF)(slv_system_t, SlvClientToken,int); |
51 |
typedef int (SlvSolveF)(slv_system_t, SlvClientToken); |
52 |
|
53 |
/** Registration information for a solver. |
54 |
@TODO Complete documentation of slv_registration_data members. |
55 |
*/ |
56 |
typedef struct slv_registration_data { |
57 |
int number; |
58 |
/**< we set number AFTER the client registration returns 0. |
59 |
client sets all the rest, starting with a symbolic name */ |
60 |
|
61 |
const char *name; /**< symbolic name for solver (required). */ |
62 |
/* |
63 |
Required functions |
64 |
*/ |
65 |
SlvClientCreateF *ccreate; /**< (required) */ |
66 |
SlvClientDestroyF *cdestroy; /**< (required) */ |
67 |
SlvClientEligibleF *celigible; /**< (required) */ |
68 |
SlvGetDefParamsF *getdefparam; /**< Function that will create default solver-parameter structure (required) */ |
69 |
SlvGetParamsF *get_parameters;/**< (required) */ |
70 |
SlvSetParamsF *setparam; /**< (required) */ |
71 |
SlvGetStatusF *getstatus; /**< (required) */ |
72 |
SlvSolveF *solve; /**< (required) */ |
73 |
/* |
74 |
Functions we really want, but can live without if your solver is old |
75 |
and klunky. Your solver may not 'look good' in an interactive environment, |
76 |
but then those nasty batch codes seldom do anyway. |
77 |
Redesign your bloody batch code. |
78 |
*/ |
79 |
SlvSolveF *presolve; /**< (desired) */ |
80 |
SlvSolveF *iterate; /**< (desired) */ |
81 |
SlvSolveF *resolve; /**< (desired) */ |
82 |
/** |
83 |
Strictly Optional Functions |
84 |
*/ |
85 |
SlvGetLinSysF *getlinsys; /**< (optional) */ |
86 |
SlvGetSysMtxF *get_sys_mtx; /**< (optional) */ |
87 |
SlvDumpInfoF *dumpinternals; /**< (optional) */ |
88 |
} SlvFunctionsT; |
89 |
|
90 |
|
91 |
typedef int SolverRegisterFn(void); |
92 |
/**< |
93 |
Registration function for solvers. Should add solver to the list of |
94 |
available solvers for NLA/LP/NLP/MINLP problems. |
95 |
@return 0 on success |
96 |
*/ |
97 |
|
98 |
/*------------------------------------------------------------------------------ |
99 |
REGISTRATION SOLVERS AND QUERYING OF SOLVER LIST |
100 |
*/ |
101 |
|
102 |
ASC_DLLSPEC int solver_register(const SlvFunctionsT *solver); |
103 |
|
104 |
ASC_DLLSPEC int SlvRegisterStandardClients(void); |
105 |
/**< |
106 |
Attempts to register solvers slv0 through (as of 6/96) slv7. |
107 |
|
108 |
The solvers registered here are those linked at build time of the |
109 |
ascend binary. See slv_client.h for registering dynamically loaded |
110 |
solvers. |
111 |
|
112 |
@return number of solvers registered successfully |
113 |
*/ |
114 |
|
115 |
ASC_DLLSPEC const struct gl_list_t *solver_get_engines(); |
116 |
/**< |
117 |
Get the list of engines. For the purpose of output to the GUI. |
118 |
*/ |
119 |
|
120 |
ASC_DLLSPEC const SlvFunctionsT *solver_engine(const int number); |
121 |
/**< |
122 |
@param number solver ID number to check for |
123 |
@return SlvFunctions for this solver, if the number is valid, else NULL |
124 |
*/ |
125 |
|
126 |
ASC_DLLSPEC const SlvFunctionsT *solver_engine_named(const char *name); |
127 |
/**< |
128 |
@param name name of solver to check for |
129 |
@return SlvFunctions for this solver, if the name is found, else NULL |
130 |
*/ |
131 |
|
132 |
ASC_DLLSPEC void solver_destroy_engines(); |
133 |
/**< |
134 |
Unregister (unload?) all registered solvers. |
135 |
*/ |
136 |
|
137 |
/*------------------------------------------------------------------------------ |
138 |
HOOKS INTO SOLVER ENGINE, CALLED BY ASCEND |
139 |
*/ |
140 |
|
141 |
ASC_DLLSPEC int slv_get_status(slv_system_t sys, slv_status_t *status); |
142 |
/**< |
143 |
Copies the current system status into the given structure. |
144 |
@return 0 on success, or nonzero if there is a problem determining status. |
145 |
*/ |
146 |
|
147 |
ASC_DLLSPEC linsolqr_system_t slv_get_linsolqr_sys(slv_system_t sys); |
148 |
/**< |
149 |
Returns the linsolqr system used, or NULL if none. |
150 |
@deprecated { THIS CALL SHOULD GO AWAY } |
151 |
*/ |
152 |
|
153 |
ASC_DLLSPEC mtx_matrix_t slv_get_sys_mtx(slv_system_t sys); |
154 |
/**< |
155 |
Returns the mtx used, or NULL if none. The user should check. |
156 |
|
157 |
@deprecated {THIS CALL SHOULD GO AWAY} |
158 |
|
159 |
@NOTE this function is referenced by the C++ api (Simulation::getMatrix). |
160 |
So don't don't vanish it! -- JP 20070113 @ENDNOTE |
161 |
**/ |
162 |
|
163 |
ASC_DLLSPEC void slv_dump_internals(slv_system_t sys, int level); |
164 |
/**< |
165 |
Will spew whatever the solver interface developer feels like to |
166 |
stderr. Larger values of level will give more detailed information, |
167 |
we hope. No specification is made with regard to what the |
168 |
information will be. returns -1 if solver gutless. This is provided |
169 |
principally to facilitate debugging a little. |
170 |
|
171 |
@TODO fix dubious documentation (return type is void...) |
172 |
*/ |
173 |
|
174 |
ASC_DLLSPEC int slv_presolve(slv_system_t sys); |
175 |
/**< |
176 |
Prepares the system for solving. This must be called before the |
177 |
system is solved, but after everything about the system is set up |
178 |
(i.e. variables and relations cannot be changed IN ANY WAY, objective |
179 |
function cannot be modified, boundaries cannot be modified, or even |
180 |
repermuted, and a new solver cannot be selected: some parameters may |
181 |
be modified, they will be marked as such). The system essentially |
182 |
becomes "read-only". If anything is modified after slv_presolve was |
183 |
called, slv_presolve must be called again before solving (EXCEPTIONS: |
184 |
slv_resolve may do for a certain restricted class of changes). @par |
185 |
|
186 |
It is at this point that the variable list is created if it does not |
187 |
already exist and the newly created variables are indexed in the |
188 |
order they end up. The relation list is indexed as well in the order |
189 |
it is received. @par |
190 |
|
191 |
Among other things, this function will perform structural analysis |
192 |
so that structural analysis flags in the status will be accurate. |
193 |
|
194 |
@return 0 on success, 1 if errors occurred (they will be output via ERROR_REPORTER) |
195 |
*/ |
196 |
|
197 |
ASC_DLLSPEC int slv_resolve(slv_system_t sys); |
198 |
/**< |
199 |
This function re-prepares the system for solving. This function may |
200 |
be used instead of slv_presolve, provided the system was partially |
201 |
or completely solved before, and then the only changes to the system |
202 |
since are as follows: |
203 |
|
204 |
@li any parameter except "partition". |
205 |
@li variable values. |
206 |
@li variable nominal values. |
207 |
@li variable bounds. |
208 |
|
209 |
In particular, the following changes are NOT allowed: |
210 |
|
211 |
@li variable fixed flag. |
212 |
@li relation included flag. |
213 |
@li variable/relation list contents, including order. Also, the |
214 |
variable/relation indices must continue to be consistent with |
215 |
the list. |
216 |
@li definition of relations, objective function, and boundaries: |
217 |
including structural rearrangement on relations, although any |
218 |
expression may be simplified. |
219 |
|
220 |
This function is considerably more efficient when it is usable. |
221 |
|
222 |
@return 0 on success |
223 |
*/ |
224 |
|
225 |
ASC_DLLSPEC int slv_iterate(slv_system_t sys); |
226 |
/**< |
227 |
Performs one iteration toward the ultimate solution (or |
228 |
failure thereof) of the system. The user can obtain information |
229 |
from the status and from the variables and relations themselves |
230 |
(some care should be taken in examining the residuals of relations; |
231 |
they may not be up to date). The user may not modify the system in |
232 |
any way between iterations (i.e. you may look, but don't touch: see |
233 |
slv_presolve()). See also slv_solve(). |
234 |
|
235 |
@return 0 on success |
236 |
*/ |
237 |
|
238 |
ASC_DLLSPEC int slv_solve(slv_system_t sys); |
239 |
/**< |
240 |
Attempts to solve the entire system in one shot (i.e. |
241 |
performs as many iterations as needed or allowed). For some solvers, |
242 |
slv_iterate() and slv_solve() may mean the same thing. |
243 |
|
244 |
@return 0 on success |
245 |
*/ |
246 |
|
247 |
|
248 |
ASC_DLLSPEC int slv_eligible_solver(slv_system_t sys); |
249 |
/**< |
250 |
Determines whether or not the current solver is capable of solving the |
251 |
given system as it is currently set up (e.g. some solvers cannot do |
252 |
optimization, or inequalities, etc). |
253 |
|
254 |
The system must be set up first before calling this function, or the |
255 |
return value may be misleading. @par |
256 |
|
257 |
The solver in question will be asked to pass judgement on the |
258 |
data in the slv_system_t wrt the solver being useful. |
259 |
If no solver is registered, this returns FALSE. |
260 |
|
261 |
@return 1 if solver is elegible |
262 |
*/ |
263 |
|
264 |
ASC_DLLSPEC int slv_select_solver(slv_system_t sys, int solver); |
265 |
/**< |
266 |
Sets the given solver to be the current solver |
267 |
for the system. The intelligence or stupidity of this move is not |
268 |
investigated. If the system has already has a solver selected and |
269 |
it is not the same solver, the data structures of the old selection |
270 |
will be blown away. |
271 |
|
272 |
@return number of solver actually selected or -1 on failure |
273 |
*/ |
274 |
|
275 |
ASC_DLLSPEC int slv_get_selected_solver(slv_system_t sys); |
276 |
/**< |
277 |
Returns the current solver number for a system. |
278 |
*/ |
279 |
|
280 |
ASC_DLLSPEC int slv_switch_solver(slv_system_t sys, int solver); |
281 |
/**< |
282 |
Sets the given solver to be the current solver for the system. |
283 |
Return value is number of solver actually selected. |
284 |
If failure, return is -1; |
285 |
*/ |
286 |
|
287 |
ASC_DLLSPEC int32 slv_get_default_parameters(int32 sindex, slv_parameters_t *parameters); |
288 |
/**< @TODO needs commenting, KHACK */ |
289 |
|
290 |
ASC_DLLSPEC void slv_get_parameters(slv_system_t sys, slv_parameters_t *parameters); |
291 |
/**< |
292 |
Copies the current system parameters to the given structure. |
293 |
|
294 |
Do not confuse these parameters [algorithm control variables] |
295 |
with the parameter list which is a list of pointers to var_variable. |
296 |
*/ |
297 |
ASC_DLLSPEC void slv_set_parameters(slv_system_t sys, slv_parameters_t *parameters); |
298 |
/**< |
299 |
Sets the current system parameters to the values contained |
300 |
in the given structure. It is recommended that one |
301 |
gets the parameters first, before one modifies them and sets them, |
302 |
especially if not all of the parameters are to be modified (and you |
303 |
never know when that might suddenly become true because a new |
304 |
parameter was added to the structure). Parameters will only be |
305 |
accepted by an engine if they came from that engine, so fetching |
306 |
before setting is not only a good idea, it's the law (gas engines |
307 |
don't run on diesel very well...). @par |
308 |
|
309 |
Do not confuse these parameters [algorithm control variables] |
310 |
with the parameter list which is a list of pointers to var_variable. |
311 |
*/ |
312 |
|
313 |
//------------------------------------------------------------------------------ |
314 |
|
315 |
ASC_DLLSPEC SlvClientToken slv_get_client_token(slv_system_t sys); |
316 |
/**< |
317 |
Returns the client token of the system_t. |
318 |
*/ |
319 |
|
320 |
ASC_DLLSPEC void slv_set_client_token(slv_system_t sys, SlvClientToken ct); |
321 |
/**< |
322 |
Sets the client token of the system_t. |
323 |
@deprecated |
324 |
*/ |
325 |
|
326 |
ASC_DLLSPEC void slv_set_solver_index(slv_system_t sys, int sindex); |
327 |
/**< |
328 |
Sets the solver index of the slv_system_t. |
329 |
@deprecated |
330 |
*/ |
331 |
|
332 |
ASC_DLLSPEC void slv_destroy_client(slv_system_t sys); |
333 |
/**< |
334 |
Destroy the client token of slv_system_t. It does not deallocate |
335 |
the allocated data space of sys |
336 |
*/ |
337 |
|
338 |
ASC_DLLSPEC boolean slv_change_basis(slv_system_t,int32,mtx_range_t *); |
339 |
/**< |
340 |
Move var (given by index #) to the unassigned region (far right) |
341 |
of the solver matrix if possible. returns FALSE if impossible |
342 |
because structural infeasibility would occur or because solver selected |
343 |
won't do it. |
344 |
|
345 |
@deprecated THIS CALL SHOULD GO AWAY |
346 |
*/ |
347 |
|
348 |
extern void slv_print_output(FILE *fp, slv_system_t sys); |
349 |
/**< |
350 |
Start of some report generation routines. For now just prints out |
351 |
the variable values and residuals at the moment. |
352 |
|
353 |
@TODO make more general in the future. |
354 |
*/ |
355 |
|
356 |
ASC_DLLSPEC const char*slv_solver_name(int sindex); |
357 |
/**< |
358 |
@param index index of the solver in question (the index depends on the order in which the solvers have been registered) |
359 |
@return name of the solver |
360 |
|
361 |
There may in general be more than one solver. The solvers will be |
362 |
numbered [0..slv_number_of_solvers). Not all the solvers may |
363 |
be present in a given installation of ASCEND as some are proprietary |
364 |
(MINOS, for example). @par |
365 |
|
366 |
Solvers not yet registered will not have names. Each registered |
367 |
client must have a unique name if user interfaces are to be happy, |
368 |
though we suppose an interface could make a unique identifier out |
369 |
of name-number pair. |
370 |
*/ |
371 |
|
372 |
/* @} */ |
373 |
|
374 |
#endif |
375 |
|
376 |
|