Parent Directory | Revision Log

Revision **1555** -
(**show annotations**)
(**download**)
(**as text**)

*Tue Jul 24 14:16:45 2007 UTC*
(13 years, 3 months ago)
by *jpye*

File MIME type: text/x-chdr

File size: 16728 byte(s)

File MIME type: text/x-chdr

File size: 16728 byte(s)

Bit more work on IPOPT presolve and hessian calculation. Added export of relman_jacobian_count.

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 <utilities/ascConfig.h> |

41 | |

42 | #include <linear/mtx.h> |

43 | |

44 | #include "var.h" |

45 | #include "rel.h" |

46 | |

47 | /** @addtogroup solver Solver |

48 | @{ |

49 | */ |

50 | |

51 | #define relman_is_linear(a,b) (FALSE) |

52 | /**< |

53 | * Determines whether or not the given relation is linear in |

54 | * all of the variables which pass through the variable filter, treating |

55 | * those variables which fail to pass as constants.<br><br> |

56 | * |

57 | * Example: |

58 | * x1 + x2 >= 3 is a linear relation. |

59 | */ |

60 | |

61 | extern real64 relman_linear_coef(struct rel_relation *rel, |

62 | struct var_variable *var, |

63 | var_filter_t *filter); |

64 | /**< |

65 | * Computes the coefficient of the given variable in a linear |

66 | * relation. If var=NULL, then the "RHS" is returned instead. More |

67 | * nprecisely, "a[var]" is returned where:<br><br> |

68 | * |

69 | * rel : sum[variables v](a[v] * v) COMPARISON a[NULL]<br><br> |

70 | * |

71 | * It is assumed that the relation is linear, otherwise, |

72 | * something will be returned, but it won't be very meaningful. |

73 | */ |

74 | |

75 | #if 0 |

76 | extern void relman_simplify(struct rel_relation *rel, int opt_level); |

77 | /**< NOT IMPLEMENTED |

78 | * The left and right hand sides of the given relation are simplified |

79 | * to the extent given by opt_level. The effect of varying values of |

80 | * opt_level is given in the description for exprman_simplify(). |

81 | */ |

82 | |

83 | extern void relman_dissolve_vars(struct rel_relation *rel, var_filter_t *filter); |

84 | /**< NOT IMPLEMENTED |

85 | * Variables which pass through the filter are replaced in the |

86 | * relation by their current values. |

87 | */ |

88 | #endif |

89 | |

90 | extern void relman_decide_incidence(struct rel_relation *rel); |

91 | /**< |

92 | * Sets the incidence field of each variable which is found to be |

93 | * incident in the relation rel to TRUE. If these variables make |

94 | * up a subset of some larger variable list, it is important to first |

95 | * set the incidence field of all of the variables to FALSE before |

96 | * using this function in order to determine the unattached variables. |

97 | */ |

98 | |

99 | extern void relman_get_incidence(struct rel_relation *rel, |

100 | var_filter_t *filter, |

101 | mtx_matrix_t matrix); |

102 | /**< |

103 | * Upon return, coefficient (rel_n,var_n) (using original row and column |

104 | * numbers) is non-zero if and only if the relation rel with index rel_n |

105 | * depends on a variable with index var_n. |

106 | */ |

107 | |

108 | ASC_DLLSPEC real64 relman_eval(struct rel_relation *rel, int32 *calc_okp, int safe); |

109 | /**< |

110 | The residual of the relation is calculated and returned. In addition |

111 | to returning the residual, the residual field of the relation is |

112 | updated. The residual field of the relation is not updated when an error |

113 | occurs. |

114 | |

115 | @param safe If set nonzero, "safe" functions are used for evaluation (means |

116 | that overflows, divide by zero, etc are avoided) |

117 | @param calc_ok (returned) status of the calculation. 0=error, else ok. |

118 | @return residual (= LHS - RHS, regardless of comparison) |

119 | |

120 | @NOTE |

121 | This function should be surrounded by Asc_SignalHandlerPush/Pop both |

122 | with arguments (SIGFPE,SIG_IGN). If it is being called in a loop, |

123 | the push/pop should be _outside_ the loop. |

124 | */ |

125 | |

126 | ASC_DLLSPEC int32 relman_obj_direction(struct rel_relation *rel); |

127 | /**< |

128 | * Returns: |

129 | * - direction = -1 if objective is minimization |

130 | * - direction = 1 if objective is maximization |

131 | * - direction = 0 otherwise. (ie. if not an objective) |

132 | */ |

133 | |

134 | ASC_DLLSPEC real64 relman_scale(struct rel_relation *rel); |

135 | /**< |

136 | * Calculates relation nominal scaling factor for |

137 | * current values stored in the relations variables. |

138 | * Fills the relations nominal field and also returns |

139 | * the relations nominal. |

140 | */ |

141 | |

142 | #define relman_diff(a,b,c,d) (abort(),1) |

143 | /**< |

144 | Calculates the derivative of the relation residual with respect to |

145 | the specified variable and stuffs it in pd. if problem with |

146 | calculation, returns 1, else 0. |

147 | If the value of safe is nonzero, "safe" functions will be used to |

148 | calculate the residual. |

149 | |

150 | @TODO relman_diff() needs to be reimplemented - needs compiler-side work. |

151 | */ |

152 | |

153 | ASC_DLLSPEC int relman_diff2(struct rel_relation *rel, |

154 | const var_filter_t *filter, |

155 | real64 *derivatives, |

156 | int32 *variables, |

157 | int32 *count, |

158 | int32 safe); |

159 | /**< |

160 | Calculates the row of the jacobian matrix (the transpose gradient of |

161 | the relation residual, $ \grad^{T}(f) $) corresponding to the relation |

162 | rel. The filter determines which variables actually contribute to the |

163 | jacobian. |

164 | |

165 | derivatives[i] will contain the derivative of the relation with |

166 | respect to the variable whose solver index is stored in |

167 | variables[i]. |

168 | |

169 | @param rel Relation being differentiated |

170 | @param filter Filter for variables for which derivs are desired |

171 | @param safe If nonzero, "safe" functions are used to for the calculations |

172 | @param derivatives output vector (allocated by the calling function) |

173 | @param variables output vector (allocated by the calling function) |

174 | @param count output value, will be set to the number of elements assigned upon exit. |

175 | |

176 | @return 0 on success, non-zero if an error is encountered in the calculation |

177 | */ |

178 | |

179 | |

180 | ASC_DLLSPEC int relman_diff3(struct rel_relation *rel, |

181 | const var_filter_t *filter, |

182 | real64 *derivatives, |

183 | struct var_variable **variables, |

184 | int32 *count, |

185 | int32 safe); |

186 | /**< as relman_diff2 but fills a var_variable* array intest of an index array. */ |

187 | |

188 | ASC_DLLSPEC int relman_diff_grad(struct rel_relation *rel, |

189 | const var_filter_t *filter, |

190 | real64 *derivatives, |

191 | int32 *variables_master, |

192 | int32 *variables_solver, |

193 | int32 *count, |

194 | real64 *resid, |

195 | int32 safe); |

196 | /**< |

197 | * Calculates the row of the jacobian matrix (the transpose gradient of |

198 | * the relation residual grad^T(f) ) corresponding to the relation |

199 | * rel. The filter determines which variables actually contribute to the |

200 | * jacobian. The residual of the relation is also computed and returned. |

201 | * If an error is encountered in the calculation, the status returned is |

202 | * 1. Status = 0 is OK. |

203 | * If the value of safe is nonzero, "safe" functions are used to for |

204 | * the calculations.<br><br> |

205 | * The calling function should allocate the output vectors 'derivatives', |

206 | * 'variables_master' and 'variables_solver'. 'count' will be set to |

207 | * the number of elements assigned upon exit. |

208 | * derivative(i) will contain the derivative of the relation with |

209 | * respect to the variable whose master index is stored in |

210 | * variables_master(i). The solver index of each variable is stored in |

211 | * variables_solver(i). |

212 | * |

213 | * There are two differences wrt to relman_diff2: |

214 | * - the master index (solver independent) is obtained |

215 | * - the residual is evaluated |

216 | */ |

217 | |

218 | ASC_DLLSPEC int relman_diffs(struct rel_relation *rel, |

219 | const var_filter_t *filter, mtx_matrix_t mtx, |

220 | real64 *resid, int safe); |

221 | /**< |

222 | Calculates the row of the jacobian matrix (the transpose gradient of |

223 | the relation residual grad^T(f) ) corresponding to the relation |

224 | rel. The filter determines which variables actually contribute to the |

225 | jacobian. The residual of the relation is also computed and returned. |

226 | If an error is encountered in the calculation, the status returned is |

227 | 1 and the residual is set to some number we managed to calculate, |

228 | while the gradient is discarded. status = 0 is OK. |

229 | |

230 | @param rel relation for which jacobian entries are required |

231 | @param filter filter for which variables should actually contribute to the jacobian |

232 | @param mtx matrix into which the row (corresponding to rel) is written |

233 | @param safe if non-zero, "safe" functions are used to for the calucaltions. |

234 | |

235 | It doesn't matter how you have permuted the columns and rows: |

236 | for the vars which pass the filter you send we |

237 | fill the org row determined by rel_sindex and the org cols |

238 | determined by var_sindex. |

239 | |

240 | @return 0 on success, 1 on calculation error (residual will be returned, grad discarded) |

241 | |

242 | @NOTE The row of the mtx corresponding to rel should be cleared |

243 | before calling this function, since this FILLS with the gradient.<br><br> |

244 | |

245 | @NOTE *changed* -- This operator used to just ADD on top of any incidence |

246 | already in the row. This is not TRUE now. |

247 | |

248 | @TODO This operator really needs to be redesigned so it can deal with |

249 | harwellian matrices, glassbox rels and blackbox. |

250 | */ |

251 | |

252 | extern int32 relman_diff_harwell(struct rel_relation **rlist, |

253 | var_filter_t *vfilter, rel_filter_t *rfilter, |

254 | int32 rlen, int32 bias, int32 mors, |

255 | real64 *avec, int32 *ivec, int32 *jvec); |

256 | /**< |

257 | * This fills an "a-i-j" sparse matrix in the avec/ivec/jvec given. |

258 | * @param rlist struct rel_relation **, list of relations rlen long. |

259 | * @param vfilter var_filter_t *, stuffs gradient for matching variables only. |

260 | * @param rlen int32, length of list of relations. |

261 | * @param bias int32, 0 = row grouped together, 1 = column grouped together. |

262 | * There is a substantial penalty for bias = 1. we MODEL by row. |

263 | * @param mors int32, 0 = master var index of columns, master rel index of rows |

264 | * 1 = solver var index of columns, master rel index of rows |

265 | * 2 = master var index of columns, solver rel index of rows |

266 | * 3 = solver var index of columns, solver rel index of rows |

267 | * Size of avec,ivec,jvec given is assumed big enough. |

268 | * big_enough = relman_jacobian_count(rlist,rlen,vfilter,rfilter,&dummy); |

269 | * If ivec or jvec given is NULL, then neither is stuffed, though avec is. |

270 | @return 0 on success, <0 on floating point errors, 1 on unrecoverable error. |

271 | |

272 | err = 1 --> unrecoverable error/bad input. caller should probably punt. |

273 | err < 0 --> -(number of floating point errors in evaluation). |

274 | The matrix will contain an approximation only. |

275 | |

276 | @todo relman_diff_harwell() bias == 1 is not yet implemented. |

277 | */ |

278 | |

279 | ASC_DLLSPEC int32 relman_jacobian_count(struct rel_relation **rlist, |

280 | int32 rlen, |

281 | var_filter_t *vfilter, |

282 | rel_filter_t *rfilter, |

283 | int32 *rhomax); |

284 | /**< |

285 | * Return the number of nonzero gradient entries in the equations |

286 | * given. Only equations passing rfilter and entries passing vfilter |

287 | * are counted. rlen is the length of the relation list. |

288 | * *rhomax is the largest row count on return. |

289 | */ |

290 | |

291 | ASC_DLLSPEC boolean relman_calc_satisfied_scaled(struct rel_relation *rel, |

292 | real64 tolerance); |

293 | /**< |

294 | * This definition of satisfaction includes the notion |

295 | * of scaling by the relation nominal before comparison. |

296 | * @see relman_calc_satisfied. |

297 | */ |

298 | ASC_DLLSPEC boolean relman_calc_satisfied(struct rel_relation *rel, |

299 | real64 tolerance); |

300 | /**< |

301 | * Returns TRUE or FALSE depending on whether the relation whose residual |

302 | * has been previously calculated is satisfied based on the value stored |

303 | * in the residual field. The satisfied field of the relation is also |

304 | * updated. A tolerance specification allows equalities to be declared |

305 | * satisfied as long as their residuals are close to zero. |

306 | * @see relman_calc_satisfied_scaled. |

307 | */ |

308 | |

309 | #define relman_directly_solve(r,s,a,n) \ |

310 | relman_directly_solve_new(r,s,a,n,1.0e-8) |

311 | /**< @see relman_directly_solve_new(). */ |

312 | extern real64 *relman_directly_solve_new(struct rel_relation *rel, |

313 | struct var_variable *solvefor, |

314 | int *able, |

315 | int *nsolns, |

316 | real64 tol); |

317 | /**< |

318 | * Attempts to solve the given equation for the given variable. If this |

319 | * function is able to determine the solution set, then *able is set to |

320 | * 1 and a newly allocated solution list is returned: *nsolns will be |

321 | * set to the length of this array. Otherwise *able is 0 and NULL |

322 | * is returned. NULL *may* also be returned if the solution set is empty. |

323 | * A return of able == 1, solution_list != NULL, and nsolns == 0 is |

324 | * possible for certain classes of floating point exceptions. |

325 | * It is assumed that the relation is a condition of equality.<br><br> |

326 | * |

327 | * relman_directly_solve_new() handles passing in a tolerance for glassbox |

328 | * relations so a rootfinder can do the work rather than leaving it to |

329 | * someone else. The rootfinder is based on Brent's algorithm. Old clients of |

330 | * relman_directly solve are grandfathered at a default tolerance of 1e-8. |

331 | * Once all these clients are gone, go back to the old name space for |

332 | * the new function.<br><br> |

333 | * |

334 | * Do NOT free or keep a persistent pointer to the solution_list this |

335 | * function returns. |

336 | */ |

337 | |

338 | #define relman_make_string_infix(sys,rel) \ |

339 | relman_make_vstring_infix((sys),(rel),TRUE) |

340 | /**< @see relman_make_xstring_infix() */ |

341 | #define relman_make_string_postfix(sys,rel) \ |

342 | relman_make_vstring_postfix((sys),(rel),TRUE) |

343 | /**< @see relman_make_xstring_infix() */ |

344 | #define relman_make_xstring_infix(sys,rel) \ |

345 | relman_make_vstring_infix((sys),(rel),FALSE) |

346 | /**< |

347 | @return string |

348 | @param sys |

349 | @param rel struct rel_relation *rel |

350 | |

351 | Creates a sufficiently large string (you must free it when you're |

352 | done with it) into which it converts a relation. The string will be |

353 | terminated with a '\0' character. |

354 | |

355 | The xstring versions of this call make strings where all the variables |

356 | are written as x<varindex> (e.g. x23) rather than as object names. |

357 | The MASTER index (var_mindex) is used, not the solver's sindex. |

358 | Currently the compiler does not support xstring postfix format, |

359 | but could easily do so if needed. |

360 | |

361 | The name of a var is context dependent, so you have to provide the |

362 | slv_system_t from which you got the relation. |

363 | |

364 | @see relman_make_string_postfix |

365 | @see relman_make_string_infix |

366 | */ |

367 | |

368 | #if 0 /* needs compiler-side work */ |

369 | # define relman_make_xstring_postfix(sys,rel) \ |

370 | relman_make_vstring_postfix((sys),(rel),FALSE) |

371 | #else |

372 | # define relman_make_xstring_postfix(sys,rel) \ |

373 | dummy_rel_string((sys),(rel),0) |

374 | #endif |

375 | /**< |

376 | * Not suppported. |

377 | * @TODO Consider adding support for xstring postfix format. |

378 | */ |

379 | |

380 | ASC_DLLSPEC char *relman_make_vstring_infix(slv_system_t sys, |

381 | struct rel_relation *rel, |

382 | int style); |

383 | /**< |

384 | * Implementation function for relman_make_string_infix() and |

385 | * relman_make_xstring_infix(). Do not call this function |

386 | * directly - use one of the macros instead. |

387 | */ |

388 | extern char *relman_make_vstring_postfix(slv_system_t sys, |

389 | struct rel_relation *rel, |

390 | int style); |

391 | /**< |

392 | * Implementation function for relman_make_string_postfix(). and |

393 | * Do not call this function directly - use the macro instead. |

394 | */ |

395 | |

396 | extern char *dummyrelstring(slv_system_t sys, |

397 | struct rel_relation *rel, |

398 | int style); |

399 | /**< Temporary no-op function to placehold unimplemented io functions. */ |

400 | |

401 | extern void relman_free_reused_mem(void); |

402 | /**< Call when desired to free memory cached internally. */ |

403 | |

404 | /* @} */ |

405 | |

406 | #endif /* ASC_RELMAN_H */ |

407 |

john.pye@anu.edu.au | ViewVC Help |

Powered by ViewVC 1.1.22 |