1 |
/* |
2 |
* Function module |
3 |
* by Tom Epperly |
4 |
* Version: $Revision: 1.16 $ |
5 |
* Version control file: $RCSfile: func.h,v $ |
6 |
* Date last modified: $Date: 2001/01/31 22:23:57 $ |
7 |
* Last modified by: $Author: ballan $ |
8 |
* |
9 |
* This file is part of the Ascend Language Interpreter. |
10 |
* |
11 |
* Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly |
12 |
* |
13 |
* The Ascend Language Interpreter is free software; you can redistribute |
14 |
* it and/or modify it under the terms of the GNU General Public License as |
15 |
* published by the Free Software Foundation; either version 2 of the |
16 |
* License, or (at your option) any later version. |
17 |
* |
18 |
* The Ascend Language Interpreter is distributed in hope that it will be |
19 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
21 |
* General Public License for more details. |
22 |
* |
23 |
* You should have received a copy of the GNU General Public License |
24 |
* along with the program; if not, write to the Free Software Foundation, |
25 |
* Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named |
26 |
* COPYING. |
27 |
* |
28 |
* Revision notes: |
29 |
* If CHRIS_FUNC defined, auxillary quantities to func structure. |
30 |
* 2/96 baa Probably somebody should properly set these evaluation |
31 |
* defined below based on math.h when possible. |
32 |
* |
33 |
*/ |
34 |
|
35 |
/** @file |
36 |
* Function module. |
37 |
* <pre> |
38 |
* When #including func.h, make sure these files are #included first: |
39 |
* #include "utilities/ascConfig.h" |
40 |
* #include "fractions.h" |
41 |
* #include "compiler.h" |
42 |
* #include "dimen.h" |
43 |
* #include "functype.h" |
44 |
* </pre> |
45 |
* @todo Complete documentation of func.h. |
46 |
*/ |
47 |
|
48 |
#ifndef __FUNC_H_SEEN__ |
49 |
#define __FUNC_H_SEEN__ |
50 |
|
51 |
/* |
52 |
* the following should be ifdefed to deal with math.h values |
53 |
*/ |
54 |
#define F_ERF_COEF 1.1283791670955130 /**< = 2 / sqrt(PI) */ |
55 |
#define F_LOG10_COEF 0.4342944819032518 /**< = log10(e) = 1/ln(10) */ |
56 |
#define F_PI 3.1415926535897932385E0 |
57 |
#define F_PI_HALF 1.5707963267948966192E0 |
58 |
#define F_LIM_EXP 709.78 /**< approximately ln(maxdouble) */ |
59 |
#define F_LIM_CUBE 5.6438030941223618e101 /**< cbrt(maxdouble)*/ |
60 |
#define F_LIM_SQR 1.0e154 /**< sqrt(maxdouble) */ |
61 |
|
62 |
#ifdef __STDC__ |
63 |
#if __STDC__ |
64 |
/** |
65 |
* stdc==1 --> erf, cbrt not defined in headers. user should link |
66 |
* against a library that does provide them. ASCEND is research |
67 |
* code: we aren't going to waste time reimplementing these basic |
68 |
* functions. |
69 |
*/ |
70 |
extern double DLEXPORT cbrt(double); |
71 |
#ifdef HAVE_ERF |
72 |
extern double erf(double); |
73 |
#endif /* HAVE_ERF */ |
74 |
#endif /* __STDC__ == 1*/ |
75 |
/**< |
76 |
* in the case where __STDC__ is defined but == 0, system headers |
77 |
* should provide cbrt, erf. |
78 |
*/ |
79 |
#endif /* stdc defined */ |
80 |
|
81 |
extern CONST struct Func *LookupFunc(CONST char *name); |
82 |
/**< |
83 |
* <!-- const struct Func *LookupFunc(name) --> |
84 |
* <!-- const char *name; (ascend name, not C) --> |
85 |
* Lookup the function with the given name. If no match is found, it |
86 |
* returns NULL. name is the ASCEND name, not C name. |
87 |
* <pre> |
88 |
* Currently defined: |
89 |
* "exp" e^x |
90 |
* "ln" natural logarithm of x |
91 |
* "log" logarithm of x base 10 |
92 |
* "sin" sine of x |
93 |
* "cos" cosine of x |
94 |
* "tan" tangent of x |
95 |
* "sqr" x*x |
96 |
* "sqrt" the square root of x |
97 |
* "arcsin" the inverse sine of x |
98 |
* "arccos" the inverse cosine of x |
99 |
* "arctan" the inverse tangent of x |
100 |
* |
101 |
* "erf" the error function |
102 |
* "lnm" modified natural log: |
103 |
* x>epsilon? ln(x): x/epsilon +ln(epsilon) -1 |
104 |
* "sinh" hyperbolic sine |
105 |
* "cosh" hyperbolic cosine |
106 |
* "tanh" hyperbolic tangent |
107 |
* "arcsinh" inv hyperbolic sine |
108 |
* "arccosh" inv hyperbolic cosine |
109 |
* "arctanh" inv hyperbolic tangent |
110 |
* |
111 |
* "cube" the cube of x |
112 |
* "cbrt" the cube root of x |
113 |
* "abs" absolute value of x |
114 |
* |
115 |
* "hold" returns the current value of x. |
116 |
* </pre> |
117 |
* The last 10 are not fully supported for chris.[ch] |
118 |
* All functions return principal (postive) values if there is a choice. |
119 |
* None of them perform range checking. ln(-1) -> float error. |
120 |
*/ |
121 |
|
122 |
extern CONST struct Func *LookupFuncById(enum Func_enum id); |
123 |
/**< |
124 |
* <!-- const struct Func *LookupFuncById(id) --> |
125 |
* <!-- enum Func_emum id; --> |
126 |
* Lookups a function by its enumerated type rather than by a string as |
127 |
* in the above function. |
128 |
*/ |
129 |
|
130 |
extern double FuncGetLnmEpsilon(void); |
131 |
/**< |
132 |
* Return the current epsilon for the modified log function lnm. |
133 |
*/ |
134 |
#define FuncGetLnmEpsilon() (g_lnm_epsilon) |
135 |
|
136 |
extern void FuncSetLnmEpsilon(double e); |
137 |
/**< |
138 |
* Change the current epsilon for the modified log function lnm. |
139 |
* epsilon > 0.0. |
140 |
*/ |
141 |
extern double g_lnm_epsilon; |
142 |
#define FuncSetLnmEpsilon(e) \ |
143 |
(e>(double)0.0 ? g_lnm_epsilon=e : FPRINTF(ASCERR,"bad lnm eps")) |
144 |
|
145 |
/**< |
146 |
* declare cbrt() and erf() since some vendors put |
147 |
* these functions in odd headers |
148 |
*/ |
149 |
extern double DLEXPORT cbrt(double); |
150 |
#ifdef HAVE_ERF |
151 |
extern double erf(double); |
152 |
#endif /* HAVE_ERF */ |
153 |
|
154 |
#ifdef NDEBUG |
155 |
#define ascnint(d) (((int) (d)>=0.0 ? floor((d) + 0.5) : -floor(0.5 - (d)))) |
156 |
/**< |
157 |
* Converts a double to the nearest integer (release version). |
158 |
* @param d double, the real number to convert. |
159 |
* @return The nearest integer as an int. |
160 |
*/ |
161 |
#else |
162 |
#define ascnint(a) ascnintF(a) |
163 |
/**< |
164 |
* Converts a double to the nearest integer (debug version). |
165 |
* @param d double, the real number to convert. |
166 |
* @return The nearest integer as an int. |
167 |
*/ |
168 |
extern int DLEXPORT ascnintF(double); |
169 |
/**< |
170 |
* Implementation function for debug version of ascnint(). |
171 |
* Do not call this function directly - use ascnint() instead. |
172 |
*/ |
173 |
|
174 |
#endif |
175 |
|
176 |
extern double DLEXPORT dln(double x); |
177 |
extern double DLEXPORT dln2(double x); |
178 |
extern double DLEXPORT dlog(double x); |
179 |
extern double DLEXPORT dlog2(double x); |
180 |
extern double DLEXPORT lnm(double x); |
181 |
extern double DLEXPORT dlnm(double x); |
182 |
extern double DLEXPORT dlnm2(double x); |
183 |
/**< |
184 |
* Modified natural log function and derivatives. |
185 |
* <pre> |
186 |
* |
187 |
* ( ln(x) if x.ge.epsilon |
188 |
* lnm(x)= ( |
189 |
* ( x/epsilon + ln(epsilon) - 1 otherwise |
190 |
* |
191 |
* |
192 |
* ( 1/x if x.ge.epsilon |
193 |
* d( lnm(x) )/dx = ( |
194 |
* ( 1/epsilon otherwise |
195 |
* |
196 |
* |
197 |
* ( -1/x^2 if x.ge.epsilon |
198 |
* d^2( lnm(x) )/dx^2 = ( |
199 |
* ( 0 otherwise |
200 |
* |
201 |
* epsilon determined by FuncGet/SetLnmEpsilon. |
202 |
* </pre> |
203 |
*/ |
204 |
|
205 |
extern double DLEXPORT dtanh(double x); |
206 |
extern double DLEXPORT dtanh2(double x); |
207 |
extern double DLEXPORT arcsinh(double x); |
208 |
extern double DLEXPORT arccosh(double x); |
209 |
extern double DLEXPORT arctanh(double x); |
210 |
extern double DLEXPORT darcsinh(double x); |
211 |
extern double DLEXPORT darcsinh2(double x); |
212 |
extern double DLEXPORT darccosh(double x); |
213 |
extern double DLEXPORT darccosh2(double x); |
214 |
extern double DLEXPORT darctanh(double x); |
215 |
extern double DLEXPORT darctanh2(double x); |
216 |
/**< |
217 |
* Zero, first and second partials of (inverse) hyperbolic functions. |
218 |
*/ |
219 |
|
220 |
extern double DLEXPORT sqr(double x); |
221 |
extern double DLEXPORT dsqr(double x); |
222 |
extern double DLEXPORT dsqr2(double x); |
223 |
extern double DLEXPORT cube(double x); |
224 |
extern double DLEXPORT dcube(double x); |
225 |
extern double DLEXPORT dcube2(double x); |
226 |
/**< |
227 |
* Zero, first and second partials of x for sqr, cube. |
228 |
*/ |
229 |
|
230 |
extern double DLEXPORT asc_ipow(double a, int n); |
231 |
extern double DLEXPORT asc_d1ipow(double a, int n); |
232 |
extern double DLEXPORT asc_d2ipow(double a, int n); |
233 |
/**< |
234 |
* Integer power function, a^n, and its first and second derivatives. |
235 |
* d = asc_ipow(a,n); |
236 |
* d1 = asc_d1ipow(a,n); |
237 |
* d2 = asc_d2ipow(a,n); |
238 |
* |
239 |
* Special cases ipow: |
240 |
* a^0 = 1, 0^n = 0, 0^0=1 -- the last is mathematically undefined, |
241 |
* so this function should not be called with 0.0,0. |
242 |
* |
243 |
* Special cases d1ipow,d2ipow: |
244 |
*/ |
245 |
|
246 |
extern double DLEXPORT hold(double x); |
247 |
/**< |
248 |
* Returns the value it is passed. |
249 |
* The primary purpose is as an operator so we can write |
250 |
* equations of the form x = hold(x) which act essentially |
251 |
* as a fixed flag when a solver is partitioning. |
252 |
* If x is fixed, the equation is singular. |
253 |
* hold(x) is a constant value, so its derivatives are 0. |
254 |
*/ |
255 |
|
256 |
extern double DLEXPORT dsqrt(double x); |
257 |
extern double DLEXPORT dsqrt2(double x); |
258 |
extern double DLEXPORT dcbrt(double x); |
259 |
extern double DLEXPORT dcbrt2(double x); |
260 |
extern double DLEXPORT dfabs(double x); |
261 |
extern double DLEXPORT dfabs2(double x); |
262 |
extern double DLEXPORT dhold(double x); |
263 |
#define dhold2 dhold |
264 |
/**< |
265 |
* first and second partials of sqrt cbrt fabs hold |
266 |
* dfabs is undefined at 0. We take the standard kluge: d(abs(x=0))/dx=0 |
267 |
* dfabs2(x) = 0. It might be thought of as infinite at x=0, but not here. |
268 |
* dhold, dhold2 = 0 for all x. |
269 |
*/ |
270 |
|
271 |
extern double DLEXPORT dasin(double x); |
272 |
extern double DLEXPORT dasin2(double x); |
273 |
extern double DLEXPORT dcos(double x); |
274 |
extern double DLEXPORT dcos2(double x); |
275 |
extern double DLEXPORT dacos(double x); |
276 |
extern double DLEXPORT dacos2(double x); |
277 |
extern double DLEXPORT dtan(double x); |
278 |
extern double DLEXPORT dtan2(double x); |
279 |
extern double DLEXPORT datan(double x); |
280 |
extern double DLEXPORT datan2(double x); |
281 |
/**< |
282 |
* First and second partials of the cosine, tangent, arctangent functions |
283 |
*/ |
284 |
|
285 |
#ifdef HAVE_ERF |
286 |
extern double DLEXPORT derf(double x); |
287 |
extern double DLEXPORT derf2(double x); |
288 |
#endif /* HAVE_ERF */ |
289 |
/**< |
290 |
* First and second derivatives of erf() |
291 |
*/ |
292 |
|
293 |
extern CONST char *FuncName(CONST struct Func *f); |
294 |
/**< |
295 |
* <!-- const char *FuncName(f) --> |
296 |
* <!-- const struct Func *f; --> |
297 |
* Return the ASCEND language name of the function. |
298 |
* Not a symchar. |
299 |
*/ |
300 |
|
301 |
extern CONST char *FuncCName(CONST struct Func *f); |
302 |
/**< |
303 |
* <!-- const char *FuncCName(f) --> |
304 |
* <!-- const struct Func *f; --> |
305 |
* Return the C language name of the function, if any. |
306 |
*/ |
307 |
|
308 |
extern CONST char *FuncDeriv1CName(CONST struct Func *f); |
309 |
/**< |
310 |
* <!-- const char *FuncDerive1CName(f) --> |
311 |
* <!-- const struct Func *f; --> |
312 |
* Return the C language name of the function first derivative, if any. |
313 |
*/ |
314 |
|
315 |
extern CONST char *FuncDeriv2CName(CONST struct Func *f); |
316 |
/**< |
317 |
* <!-- const char *FuncName(f) --> |
318 |
* <!-- const struct Func *f; --> |
319 |
* Return the C language name of the function second derivative, if any. |
320 |
*/ |
321 |
|
322 |
extern enum Func_enum FuncId(CONST struct Func *f); |
323 |
/**< |
324 |
* <!-- enum Func_enum FuncId(f) --> |
325 |
* <!-- const struct Func *f; --> |
326 |
* Return the identification of the function. |
327 |
*/ |
328 |
|
329 |
extern CONST dim_type *FuncDimens(CONST struct Func *f); |
330 |
/**< |
331 |
* <!-- dim_type *FuncDimens(f) --> |
332 |
* <!-- const struct Func *f; --> |
333 |
* Return the dimensionality required for the arg of the function. |
334 |
* sin, cos, tan -> P. |
335 |
* arc(sin,cos,tan),exp,ln,log,lnm,erf ->dimensionless. |
336 |
* sqrt->wilddimension (user must check for even poweredness of arg) |
337 |
* as this may be the case for an infinite # of different dims. |
338 |
* sqr ->wilddimension (sqr, abs, cube anything you like.) |
339 |
*/ |
340 |
|
341 |
extern double FuncEval(CONST struct Func *f, double u); |
342 |
/**< |
343 |
* <!-- double FuncEval(f,u) --> |
344 |
* <!-- const struct Func *f; --> |
345 |
* <!-- double u; --> |
346 |
* Return f(u). |
347 |
*/ |
348 |
|
349 |
extern double FuncEvalSafe(CONST struct Func *f, |
350 |
double u, |
351 |
enum safe_err *not_safe); |
352 |
/**< |
353 |
* <!-- double FuncEval(f,u,not_safe) --> |
354 |
* <!-- const struct Func *f; --> |
355 |
* <!-- double u; --> |
356 |
* <!-- enum safe_err *not_safe; --> |
357 |
* Return f(u) (safe version). |
358 |
*/ |
359 |
|
360 |
extern double FuncDeriv(CONST struct Func *f, double u); |
361 |
/**< |
362 |
* <!-- double FuncDeriv(f,u) --> |
363 |
* <!-- const struct Func *f; --> |
364 |
* <!-- double u; --> |
365 |
* Return df/du evaluated at u. |
366 |
*/ |
367 |
|
368 |
extern double FuncDerivSafe(CONST struct Func *f, |
369 |
double u, |
370 |
enum safe_err *not_safe); |
371 |
/**< |
372 |
* <!-- double FuncDerivSafe(f,u,not_safe) --> |
373 |
* <!-- const struct Func *f; --> |
374 |
* <!-- double u; --> |
375 |
* <!-- enum safe_err *not_safe; --> |
376 |
* Return df/du evaluated at u (safe version). |
377 |
*/ |
378 |
|
379 |
extern double FuncDeriv2(CONST struct Func *f, double u); |
380 |
/**< |
381 |
* <!-- double FuncDeriv2(f,u) --> |
382 |
* <!-- const struct Func *f; --> |
383 |
* <!-- double u; --> |
384 |
* Return the second derivative (d^2f/du^2) evaluated at u. |
385 |
*/ |
386 |
|
387 |
extern double FuncDeriv2Safe(CONST struct Func *f, |
388 |
double u, |
389 |
enum safe_err *not_safe); |
390 |
/**< |
391 |
* <!-- double FuncDeriv2(f,u,not_safe) --> |
392 |
* <!-- const struct Func *f; --> |
393 |
* <!-- double u; --> |
394 |
* <!-- enum safe_err *not_safe; --> |
395 |
* Return the second derivative (d^2f/du^2) evaluated at u (safe version). |
396 |
*/ |
397 |
|
398 |
#ifdef CHRIS_FUNC |
399 |
|
400 |
extern struct Interval FuncRange(CONST struct Func *f, struct Interval i); |
401 |
/**< |
402 |
* <!-- struct Interval FuncRange(f,i) --> |
403 |
* <!-- const struct Func *f; --> |
404 |
* <!-- struct Interval i; --> |
405 |
* Return a bound on the range of the function over the given interval. |
406 |
*/ |
407 |
|
408 |
extern void FuncSlope(CONST struct Func *f, |
409 |
unsigned long nvar, |
410 |
struct Interval *center, |
411 |
struct Interval *range, |
412 |
struct Interval *slope); |
413 |
/**< |
414 |
* <!-- struct Interval FuncSlope(f,nvar,center,range,slope) --> |
415 |
* <!-- const struct Func *f; --> |
416 |
* <!-- unsigned long nvar; --> |
417 |
* <!-- struct Interval *center,*range; --> |
418 |
* <!-- struct Interval slope[]; --> |
419 |
* Perform the interval slope calculation. |
420 |
*/ |
421 |
|
422 |
extern struct Interval FuncIDeriv(CONST struct Func *f, struct Interval i); |
423 |
/**< |
424 |
* <!-- struct Interval FuncIDeriv(f,i) --> |
425 |
* <!-- const struct Func *f --> |
426 |
* <!-- struct Interval i; --> |
427 |
*/ |
428 |
|
429 |
extern double ArgMin(CONST struct Func *f, double lower, double upper); |
430 |
/**< |
431 |
* <!-- double ArgMin(f,lower,upper) --> |
432 |
* <!-- const struct Func *f; --> |
433 |
* <!-- double lower,upper; --> |
434 |
* Return the arg min of the function over the range. |
435 |
*/ |
436 |
|
437 |
extern double ArgMax(CONST struct Func *f, double lower, double upper); |
438 |
/**< |
439 |
* <!-- double ArgMax(f,lower,upper) --> |
440 |
* <!-- CONST struct Func *f; --> |
441 |
* <!-- double lower,upper; --> |
442 |
* Return the arg max of the function over the range. |
443 |
*/ |
444 |
|
445 |
extern double ConvexEnv(CONST struct Func *f, double x, |
446 |
double lower, double upper); |
447 |
/**< |
448 |
* <!-- double ConvexEnv(f,x,lower,upper) --> |
449 |
* <!-- CONST struct Func *f; --> |
450 |
* <!-- double x,lower,upper; --> |
451 |
* Return the value of the convex envelope of the function at the value |
452 |
* x which ranges from lower to upper. |
453 |
*/ |
454 |
|
455 |
extern double ConvexEnvDeriv(CONST struct Func *f, double x, |
456 |
double lower, double upper); |
457 |
/**< |
458 |
* <!-- double ConvexEnvDeriv(f,x,lower,upper) --> |
459 |
* <!-- CONST struct Func *f; --> |
460 |
* <!-- double x,lower,upper; --> |
461 |
* Return the derivative of the convex envelope of the function at the |
462 |
* value x which ranges from lower to upper. |
463 |
*/ |
464 |
|
465 |
extern double ConcaveEnv(CONST struct Func *f, double x, |
466 |
double lower, double upper); |
467 |
/**< |
468 |
* <!-- double ConcaveEnv(f,x,lower,upper) --> |
469 |
* <!-- CONST struct Func *f; --> |
470 |
* <!-- double x,lower,upper; --> |
471 |
* Return the value of the concave envelope of the function at the value |
472 |
* x which ranges from lower to upper. |
473 |
*/ |
474 |
|
475 |
extern double ConcaveEnvDeriv(CONST struct Func *f, double x, |
476 |
double lower, double upper); |
477 |
/**< |
478 |
* <!-- double ConcaveEnvDeriv(f,x,lower,upper) --> |
479 |
* <!-- CONST struct Func *f; --> |
480 |
* <!-- double x,lower,upper; --> |
481 |
* Return the derivative of the concave envelope of the function at the |
482 |
* value x which ranges from lower to upper. |
483 |
*/ |
484 |
|
485 |
#endif /* CHRIS_FUNC */ |
486 |
|
487 |
#endif /* __FUNC_H_SEEN__ */ |
488 |
|