/[ascend]/trunk/ascend/system/relman.h
ViewVC logotype

Contents of /trunk/ascend/system/relman.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2351 - (show annotations) (download) (as text)
Thu Jan 6 02:02:41 2011 UTC (7 years, 11 months ago) by jpye
File MIME type: text/x-chdr
File size: 18186 byte(s)
Resolved memory leak with test/test solver_ipopt.formula.
Still some issues to overcome with regard to inactive relations, probably.
Some issue still occurring when attempting to run whole solver_ipopt suite in one go.
1 /* ASCEND modelling environment
2 Copyright (C) 2006 Carnegie Mellon University
3 Copyright (C) 1994 Joseph Zaher, Benjamin Andrew Allan
4 Copyright (C) 1993 Joseph Zaher
5 Copyright (C) 1990 Karl Michael Westerberg
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21 *//** @file
22 Relation manipulator module for the SLV solver.
23
24 This module will provide supplemental operations for
25 relations such as simplification, evaluation, and
26 differentiation.
27
28 Dates: 06/90 - original version
29 06/93 - separated out exprman
30 11/93 - added relman_calc_satisfied
31
32 *//*
33 by Karl Michael Westerberg and Joseph Zaher, 2/6/90
34 Last in CVS: $Revision: 1.29 $ $Date: 1998/04/23 23:56:24 $ $Author: ballan $
35 */
36
37 #ifndef ASC_RELMAN_H
38 #define ASC_RELMAN_H
39
40 #include <ascend/general/platform.h>
41
42 #include <ascend/linear/mtx.h>
43 #include <ascend/general/ltmatrix.h>
44
45 #include "var.h"
46 #include "rel.h"
47
48 /** @addtogroup solver Solver
49 @{
50 */
51
52 #define relman_is_linear(a,b) (FALSE)
53 /**<
54 * Determines whether or not the given relation is linear in
55 * all of the variables which pass through the variable filter, treating
56 * those variables which fail to pass as constants.<br><br>
57 *
58 * Example:
59 * x1 + x2 >= 3 is a linear relation.
60 */
61
62 extern real64 relman_linear_coef(struct rel_relation *rel,
63 struct var_variable *var,
64 var_filter_t *filter);
65 /**<
66 * Computes the coefficient of the given variable in a linear
67 * relation. If var=NULL, then the "RHS" is returned instead. More
68 * nprecisely, "a[var]" is returned where:<br><br>
69 *
70 * rel : sum[variables v](a[v] * v) COMPARISON a[NULL]<br><br>
71 *
72 * It is assumed that the relation is linear, otherwise,
73 * something will be returned, but it won't be very meaningful.
74 */
75
76 #if 0
77 extern void relman_simplify(struct rel_relation *rel, int opt_level);
78 /**< NOT IMPLEMENTED
79 * The left and right hand sides of the given relation are simplified
80 * to the extent given by opt_level. The effect of varying values of
81 * opt_level is given in the description for exprman_simplify().
82 */
83
84 extern void relman_dissolve_vars(struct rel_relation *rel, var_filter_t *filter);
85 /**< NOT IMPLEMENTED
86 * Variables which pass through the filter are replaced in the
87 * relation by their current values.
88 */
89 #endif
90
91 extern void relman_decide_incidence(struct rel_relation *rel);
92 /**<
93 * Sets the incidence field of each variable which is found to be
94 * incident in the relation rel to TRUE. If these variables make
95 * up a subset of some larger variable list, it is important to first
96 * set the incidence field of all of the variables to FALSE before
97 * using this function in order to determine the unattached variables.
98 */
99
100 extern void relman_get_incidence(struct rel_relation *rel,
101 var_filter_t *filter,
102 mtx_matrix_t matrix);
103 /**<
104 * Upon return, coefficient (rel_n,var_n) (using original row and column
105 * numbers) is non-zero if and only if the relation rel with index rel_n
106 * depends on a variable with index var_n.
107 */
108
109 ASC_DLLSPEC real64 relman_eval(struct rel_relation *rel, int32 *calc_okp, int safe);
110 /**<
111 The residual of the relation is calculated and returned. In addition
112 to returning the residual, the residual field of the relation is
113 updated. The residual field of the relation is not updated when an error
114 occurs.
115
116 @param safe If set nonzero, "safe" functions are used for evaluation (means
117 that overflows, divide by zero, etc are avoided)
118 @param calc_ok (returned) status of the calculation. 0=error, else ok.
119 @return residual (= LHS - RHS, regardless of comparison)
120
121 @NOTE
122 This function should be surrounded by Asc_SignalHandlerPush/Pop both
123 with arguments (SIGFPE,SIG_IGN). If it is being called in a loop,
124 the push/pop should be _outside_ the loop.
125 */
126
127 ASC_DLLSPEC int32 relman_obj_direction(struct rel_relation *rel);
128 /**<
129 * Returns:
130 * - direction = -1 if objective is minimization
131 * - direction = 1 if objective is maximization
132 * - direction = 0 otherwise. (ie. if not an objective)
133 */
134
135 ASC_DLLSPEC real64 relman_scale(struct rel_relation *rel);
136 /**<
137 * Calculates relation nominal scaling factor for
138 * current values stored in the relations variables.
139 * Fills the relations nominal field and also returns
140 * the relations nominal.
141 */
142
143 #define relman_diff(a,b,c,d) (abort(),1)
144 /**<
145 Calculates the derivative of the relation residual with respect to
146 the specified variable and stuffs it in pd. if problem with
147 calculation, returns 1, else 0.
148 If the value of safe is nonzero, "safe" functions will be used to
149 calculate the residual.
150
151 @TODO relman_diff() needs to be reimplemented - needs compiler-side work.
152 */
153
154
155 ASC_DLLSPEC int relman_diff2(struct rel_relation *rel,
156 const var_filter_t *filter,
157 real64 *derivatives,
158 int32 *variables,
159 int32 *count,
160 int32 safe);
161 /**<
162 Calculates the row of the jacobian matrix (the transpose gradient of
163 the relation residual, \f$ \grad^{T}(f) \f$) corresponding to the relation
164 rel. The filter determines which variables actually contribute to the
165 jacobian.
166
167 derivatives[i] will contain the derivative of the relation with
168 respect to the variable whose solver index is stored in
169 variables[i].
170
171 @param rel Relation being differentiated
172 @param filter Filter for variables for which derivs are desired
173 @param safe If nonzero, "safe" functions are used to for the calculations
174 @param derivatives output vector (allocated by the calling function)
175 @param variables output vector (allocated by the calling function)
176 @param count output value, will be set to the number of elements assigned upon exit.
177
178 @return 0 on success, non-zero if an error is encountered in the calculation
179 */
180
181
182 /* return 0 on success (derivatives, variables and count are output vars too) */
183 ASC_DLLSPEC int relman_diff2_rev(struct rel_relation *rel,
184 const var_filter_t *filter,
185 real64 *derivatives,
186 int32 *variables,
187 int32 *count, int32 safe);
188
189 /**<
190 similar to relman_diff2, but uses revers Automatic differentiation to obtain derivatives
191 */
192
193 ASC_DLLSPEC int relman_hess(struct rel_relation *rel,
194 const var_filter_t *filter,
195 hessian_mtx *hess_matrix,
196 int32 *count,
197 unsigned long max_dimension,
198 int32 safe);
199 /**<
200 Hessian Matrix Evaluation,
201 @param rel is the relation whose Hessian Matrix is desired
202 @param filter is the variable filter
203 @param hess_matrix is the Lower Triangular Matrix into which values are filled
204 @param count is the count of elements filled
205 @param safe is the boolean value indicating whether evaluation is safe or non-safe
206
207 @return 0 on success, non-zero if an error is encountered in the calculation
208 */
209
210 ASC_DLLSPEC int relman_diff3(struct rel_relation *rel,
211 const var_filter_t *filter,
212 real64 *derivatives,
213 struct var_variable **variables,
214 int32 *count,
215 int32 safe);
216 /**< as relman_diff2 but fills a var_variable* array intest of an index array. */
217
218 ASC_DLLSPEC int relman_diff_grad(struct rel_relation *rel,
219 const var_filter_t *filter,
220 real64 *derivatives,
221 int32 *variables_master,
222 int32 *variables_solver,
223 int32 *count,
224 real64 *resid,
225 int32 safe);
226 /**<
227 * Calculates the row of the jacobian matrix (the transpose gradient of
228 * the relation residual grad^T(f) ) corresponding to the relation
229 * rel. The filter determines which variables actually contribute to the
230 * jacobian. The residual of the relation is also computed and returned.
231 * If an error is encountered in the calculation, the status returned is
232 * 1. Status = 0 is OK.
233 * If the value of safe is nonzero, "safe" functions are used to for
234 * the calculations.<br><br>
235 * The calling function should allocate the output vectors 'derivatives',
236 * 'variables_master' and 'variables_solver'. 'count' will be set to
237 * the number of elements assigned upon exit.
238 * derivative(i) will contain the derivative of the relation with
239 * respect to the variable whose master index is stored in
240 * variables_master(i). The solver index of each variable is stored in
241 * variables_solver(i).
242 *
243 * There are two differences wrt to relman_diff2:
244 * - the master index (solver independent) is obtained
245 * - the residual is evaluated
246 */
247
248 ASC_DLLSPEC int relman_diffs(struct rel_relation *rel,
249 const var_filter_t *filter, mtx_matrix_t mtx,
250 real64 *resid, int safe);
251 /**<
252 Calculates the row of the jacobian matrix (the transpose gradient of
253 the relation residual grad^T(f) ) corresponding to the relation
254 rel. The filter determines which variables actually contribute to the
255 jacobian. The residual of the relation is also computed and returned.
256 If an error is encountered in the calculation, the status returned is
257 1 and the residual is set to some number we managed to calculate,
258 while the gradient is discarded. status = 0 is OK.
259
260 @param rel relation for which jacobian entries are required
261 @param filter filter for which variables should actually contribute to the jacobian
262 @param mtx matrix into which the row (corresponding to rel) is written
263 @param safe if non-zero, "safe" functions are used to for the calucaltions.
264
265 It doesn't matter how you have permuted the columns and rows:
266 for the vars which pass the filter you send we
267 fill the org row determined by rel_sindex and the org cols
268 determined by var_sindex.
269
270 @return 0 on success, 1 on calculation error (residual will be returned, grad discarded)
271
272 @NOTE The row of the mtx corresponding to rel should be cleared
273 before calling this function, since this FILLS with the gradient.<br><br>
274
275 @NOTE *changed* -- This operator used to just ADD on top of any incidence
276 already in the row. This is not TRUE now.
277
278 @TODO This operator really needs to be redesigned so it can deal with
279 harwellian matrices, glassbox rels and blackbox.
280 */
281
282 extern int32 relman_diff_harwell(struct rel_relation **rlist,
283 var_filter_t *vfilter, rel_filter_t *rfilter,
284 int32 rlen, int32 bias, int32 mors,
285 real64 *avec, int32 *ivec, int32 *jvec);
286 /**<
287 * This fills an "a-i-j" sparse matrix in the avec/ivec/jvec given.
288 * @param rlist struct rel_relation **, list of relations rlen long.
289 * @param vfilter var_filter_t *, stuffs gradient for matching variables only.
290 * @param rlen int32, length of list of relations.
291 * @param bias int32, 0 = row grouped together, 1 = column grouped together.
292 * There is a substantial penalty for bias = 1. we MODEL by row.
293 * @param mors int32, 0 = master var index of columns, master rel index of rows
294 * 1 = solver var index of columns, master rel index of rows
295 * 2 = master var index of columns, solver rel index of rows
296 * 3 = solver var index of columns, solver rel index of rows
297 * Size of avec,ivec,jvec given is assumed big enough.
298 * big_enough = relman_jacobian_count(rlist,rlen,vfilter,rfilter,&dummy);
299 * If ivec or jvec given is NULL, then neither is stuffed, though avec is.
300 @return 0 on success, <0 on floating point errors, 1 on unrecoverable error.
301
302 err = 1 --> unrecoverable error/bad input. caller should probably punt.
303 err < 0 --> -(number of floating point errors in evaluation).
304 The matrix will contain an approximation only.
305
306 @todo relman_diff_harwell() bias == 1 is not yet implemented.
307 */
308
309 ASC_DLLSPEC int32 relman_jacobian_count(struct rel_relation **rlist,
310 int32 rlen,
311 var_filter_t *vfilter,
312 rel_filter_t *rfilter,
313 int32 *rhomax);
314 /**<
315 * Return the number of nonzero gradient entries in the equations
316 * given. Only equations passing rfilter and entries passing vfilter
317 * are counted. rlen is the length of the relation list.
318 * *rhomax is the largest row count on return.
319 */
320
321 ASC_DLLSPEC int32 relman_hessian_count(
322 struct rel_relation **rlist, int32 rlen
323 , var_filter_t *vfilter, rel_filter_t *rfilter
324 , int32 *rhomax
325 );
326 /**<
327 * Return the number of nonzero gradient entries in the equations
328 * given. Only equations passing rfilter and entries passing vfilter
329 * are counted. rlen is the length of the relation list.
330 * *rhomax is the largest row count on return.
331 */
332
333 ASC_DLLSPEC boolean relman_calc_satisfied_scaled(struct rel_relation *rel,
334 real64 tolerance);
335 /**<
336 * This definition of satisfaction includes the notion
337 * of scaling by the relation nominal before comparison.
338 * @see relman_calc_satisfied.
339 */
340 ASC_DLLSPEC boolean relman_calc_satisfied(struct rel_relation *rel,
341 real64 tolerance);
342 /**<
343 * Returns TRUE or FALSE depending on whether the relation whose residual
344 * has been previously calculated is satisfied based on the value stored
345 * in the residual field. The satisfied field of the relation is also
346 * updated. A tolerance specification allows equalities to be declared
347 * satisfied as long as their residuals are close to zero.
348 * @see relman_calc_satisfied_scaled.
349 */
350
351 #define relman_directly_solve(r,s,a,n) \
352 relman_directly_solve_new(r,s,a,n,1.0e-8)
353 /**< @see relman_directly_solve_new(). */
354 extern real64 *relman_directly_solve_new(struct rel_relation *rel,
355 struct var_variable *solvefor,
356 int *able,
357 int *nsolns,
358 real64 tol);
359 /**<
360 * Attempts to solve the given equation for the given variable. If this
361 * function is able to determine the solution set, then *able is set to
362 * 1 and a newly allocated solution list is returned: *nsolns will be
363 * set to the length of this array. Otherwise *able is 0 and NULL
364 * is returned. NULL *may* also be returned if the solution set is empty.
365 * A return of able == 1, solution_list != NULL, and nsolns == 0 is
366 * possible for certain classes of floating point exceptions.
367 * It is assumed that the relation is a condition of equality.<br><br>
368 *
369 * relman_directly_solve_new() handles passing in a tolerance for glassbox
370 * relations so a rootfinder can do the work rather than leaving it to
371 * someone else. The rootfinder is based on Brent's algorithm. Old clients of
372 * relman_directly solve are grandfathered at a default tolerance of 1e-8.
373 * Once all these clients are gone, go back to the old name space for
374 * the new function.<br><br>
375 *
376 * Do NOT free or keep a persistent pointer to the solution_list this
377 * function returns.
378 */
379
380 #define relman_make_string_infix(sys,rel) \
381 relman_make_vstring_infix((sys),(rel),TRUE)
382 /**< @see relman_make_xstring_infix() */
383 #define relman_make_string_postfix(sys,rel) \
384 relman_make_vstring_postfix((sys),(rel),TRUE)
385 /**< @see relman_make_xstring_infix() */
386 #define relman_make_xstring_infix(sys,rel) \
387 relman_make_vstring_infix((sys),(rel),FALSE)
388 /**<
389 @return string
390 @param sys
391 @param rel struct rel_relation *rel
392
393 Creates a sufficiently large string (you must free it when you're
394 done with it) into which it converts a relation. The string will be
395 terminated with a '\0' character.
396
397 The xstring versions of this call make strings where all the variables
398 are written as x<varindex> (e.g. x23) rather than as object names.
399 The MASTER index (var_mindex) is used, not the solver's sindex.
400 Currently the compiler does not support xstring postfix format,
401 but could easily do so if needed.
402
403 The name of a var is context dependent, so you have to provide the
404 slv_system_t from which you got the relation.
405
406 @see relman_make_string_postfix
407 @see relman_make_string_infix
408 */
409
410 #if 0 /* needs compiler-side work */
411 # define relman_make_xstring_postfix(sys,rel) \
412 relman_make_vstring_postfix((sys),(rel),FALSE)
413 #else
414 # define relman_make_xstring_postfix(sys,rel) \
415 dummy_rel_string((sys),(rel),0)
416 #endif
417 /**<
418 * Not suppported.
419 * @TODO Consider adding support for xstring postfix format.
420 */
421
422 ASC_DLLSPEC char *relman_make_vstring_infix(slv_system_t sys,
423 struct rel_relation *rel,
424 int style);
425 /**<
426 * Implementation function for relman_make_string_infix() and
427 * relman_make_xstring_infix(). Do not call this function
428 * directly - use one of the macros instead.
429 */
430 extern char *relman_make_vstring_postfix(slv_system_t sys,
431 struct rel_relation *rel,
432 int style);
433 /**<
434 * Implementation function for relman_make_string_postfix(). and
435 * Do not call this function directly - use the macro instead.
436 */
437
438 extern char *dummyrelstring(slv_system_t sys,
439 struct rel_relation *rel,
440 int style);
441 /**< Temporary no-op function to placehold unimplemented io functions. */
442
443 extern void relman_free_reused_mem(void);
444 /**< Call when desired to free memory cached internally. */
445
446 /* @} */
447
448 #endif /* ASC_RELMAN_H */
449

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