/[ascend]/trunk/base/generic/compiler/extfunc.h
ViewVC logotype

Contents of /trunk/base/generic/compiler/extfunc.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 710 - (show annotations) (download) (as text)
Thu Jun 29 08:53:37 2006 UTC (16 years, 7 months ago) by johnpye
File MIME type: text/x-chdr
File size: 17174 byte(s)
Added my so-called 'quick fix' to external relation processing.
Still need to pursue corruption of efunc->etype pointer, for some
reason.
1 /*
2 ASCEND modelling environment
3 Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly, Kirk Andre Abbott
4 Copyright (C) 2006 Benjamin Allan
5 Copyright (C) 2006 Carnegie Mellon University
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 *//**
22 @file
23 External Functions Module.
24
25 This module implements the ExternalFunc structure referenced by the
26 ExtCallNode structure, and allows syntax for black box and glass box
27 relations to be implemented, as well as external method calls.
28
29 The ExternalFunc structure stores the number of input and output parameters
30 as well as 'help' string and 'name' string' for each of these 'calls'.
31
32 This header also provides functions for ExternalFunc library maintenance.
33 This allows ASCEND to maintain a list of the ExternalFunc requests derived
34 from statements in the model(s). When compilation completes, I suppose
35 it should be possible to alert the user about any external functions
36 that were not able to be resolved.
37
38 @todo Complete documentation of compiler/extfunc.h.
39
40 Requires:
41 #include "utilities/ascConfig.h"
42 #include "compiler/instance_enum.h"
43 #include "general/list.h"
44 #include "compiler/compiler.h"
45 *//*
46 by Kirk Andre Abbott and Ben Allan
47 Created: July 4, 1994.
48 Version: $Revision: 1.5 $
49 Version control file: $RCSfile: extfunc.h,v $
50 Date last modified: $Date: 1997/07/18 12:29:30 $
51 Last modified by: $Author: mthomas $
52 */
53
54 #ifndef ASC_EXTFUNC_H
55 #define ASC_EXTFUNC_H
56
57 #include <utilities/ascConfig.h>
58 #include "relation_util.h"
59
60 /*------------------------------------------------------------------------------
61 type definitions and forward decls
62 */
63
64 /**
65 ExtEvalFunc type is a function pointer. It's only being used in the
66 GlassBox stuff at this stage I think -- JP
67
68 @see rootfind.c:51
69
70 @param mode 'to pass to the eval function' (?)
71 @param m relation index
72 @param n variable index
73 @param x 'x' vector (?)
74 @param u 'u' vector (?)
75 @param f vector of residuals
76 @param g vector of gradients
77 */
78 typedef int ExtEvalFunc(int *mode, int *m, int *n,
79 double *x, double *u, double *f, double *g);
80
81 /**
82 This is an enum to clarify and make type-safer the
83 the variation of external functions circa 1995.
84 Blackboxes might be callable from methods as well (@TODO), but
85 this is dependent on their code registration to setup.
86 */
87 enum ExternalFuncType {
88 efunc_ERR = 0, /**< err value (Traps old mode errors too) */
89 efunc_BlackBox = 10, /**< remainder of struct is blackbox */
90 efunc_GlassBox = 20, /**< remainder of struct is glassbox */
91 efunc_Method = 30 /**< remainder of struct is method */
92 };
93
94 struct GlassBoxExternalFunc {
95 ExtEvalFunc *initial;
96 ExtEvalFunc **value; /**< array of relation residual functions. */
97 ExtEvalFunc **deriv; /**< array of relation gradient functions. */
98 ExtEvalFunc **deriv2; /**< array of relation hessian functions. */
99 ExtEvalFunc *final; /**< cleanup function. */
100 };
101
102
103 /** values a blackbox (or ?) can report when returning. */
104 enum Calc_status {
105 calc_converged,
106 calc_diverged,
107 calc_fp_error,
108 calc_incorrect_args,
109 calc_error,
110 calc_all_ok
111 };
112
113 /**
114 Things that a blackbox can be asked to do.
115
116 @NOTE Rhetorical question: Why do we want this? See comments in Slv_Interp.
117 */
118 enum Request_type {
119 bb_none, /**< do nothing. should never be sent. */
120 bb_first_call, /**< will be given when the initial function pointer is called. */
121 bb_last_call, /**< will be given when the final function pointer is called. */
122 bb_check_args, /**< do any argument checking of the variables, data */
123 bb_recalculate, /**< the caller thinks the input may have changed: recalc if reqd */
124 bb_func_eval, /**< the caller needs the residual function pointer. */
125 bb_deriv_eval, /**< the caller needs the deriv function pointer. */
126 bb_hess_eval, /**< the caller needs the hessian function pointer. */
127 bb_single_step /**< the caller would like one step toward the solution;
128 usually this is meaningless and should be answered with calc_diverged. */
129 };
130
131 /**
132 Each blackbox equation may show up more than once in a simulation
133 if models repeat in the structure. For each occurence of the
134 blackbox, a unique Slv_Interp object is given when the set of
135 corresponding relations is created.
136 It is used for the blackbox to communicate to the rest of the system.
137 If the blackbox retains internal state between evaluation calls,
138 it should store this state in the user_data pointer.
139 */
140 struct Slv_Interp {
141 /** status is set by blackbox calls before returning. */
142 enum Calc_status status;
143
144 /** user_data is set by the blackbox if it has any persistent state
145 during calls to ExtBBoxInitFunc initial and final given in
146 CreateUserFunctionBlackBox.
147 */
148 void *user_data;
149
150 /** unique identifier tied to instance tree. Set by system. */
151 int nodestamp;
152
153 /** What the caller wants done on a given call.
154
155 As black boxes are represented with 5 function pointers,
156 one might think this is not needed. Providing the 'task' here allows
157 one to implement only one function and have it handle all types of
158 calls. It also facilitates cases where there is checking rather than
159 evaluation.
160
161 @NOTE Problem? Don't init functions and evaluation functions have
162 different signatures?
163 */
164 enum Request_type task;
165 };
166
167 typedef int ExtBBoxInitFunc(struct Slv_Interp *,
168 struct Instance *,
169 struct gl_list_t *);
170
171 /**
172 External black box equations are of the block form
173 y_out = f(x_in). This block expands to N_outputs equations
174 of the form y_out[i] = f_i(x_in), where the functional details
175 of f are assumed to be smooth enough but otherwise totally hidden
176 and x_in, y_out are non-overlapping sets of variables.
177
178 Note that solvers are not psychic; if this blackbox is embedded
179 in a larger model such that some of y_out are fixed variables,
180 the odds of convergence are small. Cleverer solvers may issue
181 a warning.
182
183 @param interp the control information is exchanged in interp; interp->task
184 should be consulted.
185 @param ninputs the length of the inputs, xi_in.
186 @param noutputs, the length of the outputs, y_out.
187 @param jacobian, the partial derivative df/dx, where
188 each row is df[i]/dx[j] over each j for the y_out[i] of
189 matching index. The jacobian array is 1-D, row major, i.e.
190 df[i]/dx[j] -> jacobian[i*ninputs+j].
191
192 @TODO this one may need splitting/rework for hessian.
193 */
194 typedef int ExtBBoxFunc(struct Slv_Interp *interp,
195 int ninputs, int noutputs,
196 double *inputs, double *outputs, double *jacobian);
197
198 struct BlackBoxExternalFunc {
199 ExtBBoxInitFunc *initial;
200 ExtBBoxFunc *value; /**< relation residual function. */
201 ExtBBoxFunc *deriv; /**< relation gradient function. */
202 ExtBBoxFunc *deriv2; /**< relation hessian function. */
203 ExtBBoxInitFunc *final; /**< cleanup function. */
204 };
205
206
207 /**
208 Function pointer (type) to implement an external method on a particular
209 instance
210
211 @param context the instance on which the method is run.
212 context may also appear explicitly in the arg list as SELF.
213 @param args Each element of args is a list of instances; each
214 name in the ascend-language argument list is expanded to a list
215 (which may contain 0 or more Instances) and appended to args.
216 */
217 typedef int ExtMethodRun( struct Instance *context, struct gl_list_t *args);
218
219 struct MethodExternalFunc {
220 ExtMethodRun *run; /**< the method invoked. */
221 #if 0 /* have no use for these currently. */
222 ExtMethodInit *initial; /**< allowed to be null if not needed. */
223 ExtMethodInit *final; /**< allowed to be null if not needed. */
224 #endif
225 };
226
227 struct ExternalFunc {
228 enum ExternalFuncType etype;
229 CONST char *name; /**< a string we own. */
230 CONST char *help; /**< a string we own. */
231 unsigned long n_inputs; /**< expected # of inputs. */
232 unsigned long n_outputs; /**< expected # of outputs. */
233 union {
234 struct GlassBoxExternalFunc glass;
235 struct BlackBoxExternalFunc black;
236 struct MethodExternalFunc method;
237 } u;
238 };
239
240 /*------------------------------------------------------------------------------
241 REGISTRATION / LOOKUP FUNCTIONS
242 */
243
244 /* deleted: RetiredExternalFunc -- JP */
245
246 extern void InitExternalFuncLibrary(void);
247 /**<
248 The main external functions library initialization routine. This
249 function must be called before all others.
250 */
251
252 extern void DestroyExtFuncLibrary(void);
253 /**<
254 Destroys the external function library and deallocates all the
255 information associated with it.
256 */
257
258
259 extern int AddExternalFunc(struct ExternalFunc *efunc, int force);
260 /**<
261 Adds an external function node to the external function library.
262 We look up the external function before adding it to the
263 library. If force is zero and the function exists then nothing
264 is done and 0 is returned. If force is true, then the old entry is
265 removed and the new one is added; 1 is returned. If the name is not
266 found then the information is added to the library.
267
268 @return 1 if an element is added to ExternalFunctionLibrary Table,
269 or 0 if no addition is made.
270 */
271
272 extern struct ExternalFunc *LookupExtFunc(CONST char *funcname);
273 /**<
274 Returns the external function having the given name, or NULL if
275 not found.
276 */
277
278
279 extern struct ExternalFunc *RemoveExternalFunc(char *name);
280 /**<
281 Removes the external function having the given name from the
282 External function library.
283 */
284
285 extern void DestroyExternalFunc(struct ExternalFunc *name);
286 /**<
287 Destroys an external function, but does *not* remove it from the
288 library. Use the RemoveExternalFunc library first to retrieve the
289 information, then call this function.
290 */
291
292
293 extern void PrintExtFuncLibrary(FILE *f);
294 /**<
295 Prints the contents of the external function library to the given
296 file. The file must be opened for writing.
297 */
298
299 ASC_DLLSPEC(char *) WriteExtFuncLibraryString(void);
300 /**<
301 Returns a string of formatted information about the external functions
302 defined. the string looks like "{{name1} {help1}} {{name2} {help2}} "
303 The string may be empty/NULL if there are no external functions loaded.
304 */
305
306 /**
307 This provides a way for other code to visit the external function list
308 */
309 ASC_DLLSPEC(void) TraverseExtFuncLibrary(void (*)(void *,void *),void *secondparam);
310
311
312 /** fetch the required input count for glass, black, or method. */
313 ASC_DLLSPEC(unsigned long) NumberInputArgs(CONST struct ExternalFunc *efunc);
314 /** fetch the required output count for glass, black, or method. */
315 ASC_DLLSPEC(unsigned long) NumberOutputArgs(CONST struct ExternalFunc *efunc);
316
317
318 ASC_DLLSPEC(CONST char*) ExternalFuncName(CONST struct ExternalFunc *efunc);
319 /**<
320 Returns the name of an external function.
321 */
322
323 /*------------------------------------------------------------------------------
324 EXTERNAL METHOD STUFF
325 */
326
327 /**
328 Setup/teardown, if any needed, for a particular instance.
329
330 We don't actually support this method anywhere right now, as
331 we're not sure what it can logically be used for that the
332 init function in dlopening shouldn't be doing.
333 In principal, we could add and cache a client-data pointer
334 in each instance so that the external method may be stateful.
335 Presently, the external methods must be clever to do that
336 on their own or must use ascend instances for state instead.
337 @param context the instance on which the method may be run.
338 */
339 typedef int ExtMethodInit( struct Instance *context);
340
341 ASC_DLLSPEC(int) CreateUserFunctionMethod(CONST char *name,
342 /* ExtMethodInit *initial, */
343 ExtMethodRun *run,
344 /* ExtMethodInit *final, */
345 CONST long n_args,
346 CONST char *help);
347 /**<
348 * Adds an external method call to the ASCEND system.
349 * The name of the function is looked up. If it already exists, the
350 * information will be updated. If the name was not found in the
351 * external function library, then an external function node will be
352 * created and added to the external function library. We make a
353 * *copy* of the help string if it is provided. We also make a copy
354 * of the name. Anyone desirous of ASCEND knowing about their
355 * external methods must use this protocol.
356 *
357 * @param name Name of the function being added (or updated).
358 * @param initial Pointer to initialisation function, or NULL if none.
359 * @param run Pointer to the method.
360 * @param final Pointer to cleanup function, or NULL if none.
361 * @param n_args number of arguments expected as input, or -1 if any number is allowed.
362 * @return Returns 0 if the function was successfully added,
363 * non-zero otherwise.
364 */
365
366 /** Fetch method run function. */
367 extern ExtMethodRun *GetExtMethodRun(struct ExternalFunc *efunc);
368
369 /*------------------------------------------------------------------------------
370 BLACK BOX STUFF
371 */
372
373 /** Fetch black initialization function. */
374 extern ExtBBoxInitFunc *GetInitFunc(struct ExternalFunc *efunc);
375 /** Fetch black residual function. */
376 extern ExtBBoxFunc *GetValueFunc(struct ExternalFunc *efunc);
377 /** Fetch black sensitivity gradient function. */
378 extern ExtBBoxFunc *GetDerivFunc(struct ExternalFunc *efunc);
379 /** Fetch black hessian function. */
380 extern ExtBBoxFunc *GetDeriv2Func(struct ExternalFunc *efunc);
381 /** Fetch black cleanup function. */
382 extern ExtBBoxInitFunc *GetFinalFunc(struct ExternalFunc *efunc);
383
384
385 ASC_DLLSPEC(int) CreateUserFunctionBlackBox(CONST char *name,
386 ExtBBoxInitFunc *init,
387 ExtBBoxFunc *value,
388 ExtBBoxFunc *deriv,
389 ExtBBoxFunc *deriv2,
390 ExtBBoxInitFunc *final,
391 CONST unsigned long n_inputs, CONST unsigned long n_outputs,
392 CONST char *help
393 );
394 /**<
395 Adds an external function to the ASCEND system.
396 The name of the function is looked up. If it already exists, the
397 information will be updated. If the name was not found in the
398 external function library, then an external function node will be
399 created and added to the external function library. We make a
400 *copy* of the help string if it is provided. We also make a copy
401 of the name. Anyone desirous of ASCEND knowing about their
402 functions must use this protocol.
403
404 Note: most blackboxes
405
406 @param name Name of the function being added (or updated).
407 @param init Pointer to initialisation function, or NULL if none.
408 @param final Pointer to shutdown function. May be same as init.
409 @param value evaluation function pointers, or NULL if none.
410 @param deriv first partial derivative functions, or NULL if none.
411 @param deriv2 second derivative functions, or NULL if none.
412 @return Returns 0 if the function was successfully added,
413 non-zero otherwise.
414 */
415
416
417 /**
418 Evaluate blackbox relation.
419 */
420 double blackbox_evaluate_residual(struct relation *r);
421
422 /*-----------------------------------------------------------------------------
423 GLASS BOX STUFF
424 */
425
426 ASC_DLLSPEC(int) CreateUserFunctionGlassBox(CONST char *name,
427 ExtEvalFunc *init,
428 ExtEvalFunc **value,
429 ExtEvalFunc **deriv,
430 ExtEvalFunc **deriv2,
431 ExtEvalFunc *final,
432 CONST unsigned long n_inputs, CONST unsigned long n_outputs,
433 CONST char *help
434 );
435 /**<
436 Adds an external function to the ASCEND system.
437 The name of the function is looked up. If it already exists, the
438 information will be updated. If the name was not found in the
439 external function library, then an external function node will be
440 created and added to the external function library. We make a
441 *copy* of the help string if it is provided. We also make a copy
442 of the name. Anyone desirous of ASCEND knowing about their
443 functions must use this protocol.
444
445 @param name Name of the function being added (or updated).
446 @param init Pointer to initialisation function, or NULL if none.
447 @param value array of evaluation function pointers,
448 or NULL if none.
449 @param deriv array of first partial
450 derivative functions, or NULL if none.
451 @param deriv2 array of second derivative
452 functions, or NULL if none.
453 @return Returns 0 if the function was successfully added,
454 non-zero otherwise.
455 */
456
457 /** Fetch glass initialization function. */
458 extern ExtEvalFunc *GetGlassBoxInit(struct ExternalFunc *efunc);
459 /** Get glass box residual function array. */
460 extern ExtEvalFunc **GetValueJumpTable(struct ExternalFunc *efunc);
461 /** Get glass box gradient function array. */
462 extern ExtEvalFunc **GetDerivJumpTable(struct ExternalFunc *efunc);
463 /** Get glass box hessian function array. */
464 extern ExtEvalFunc **GetDeriv2JumpTable(struct ExternalFunc *efunc);
465 /** Fetch black initialization function. */
466 extern ExtEvalFunc *GetGlassBoxFinal(struct ExternalFunc *efunc);
467
468
469
470
471
472 #endif /* ASC_EXTFUNC_H */

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