1 |
/* |
2 |
* SLV: Ascend Numeric Solver |
3 |
* by Karl Michael Westerberg |
4 |
* Created: 2/6/90 |
5 |
* Version: $Revision: 1.8 $ |
6 |
* Version control file: $RCSfile: calc.h,v $ |
7 |
* Date last modified: $Date: 1997/07/21 17:01:04 $ |
8 |
* Last modified by: $Author: kt2g $ |
9 |
* |
10 |
* This file is part of the SLV solver. |
11 |
* |
12 |
* Copyright (C) 1990 Karl Michael Westerberg |
13 |
* Copyright (C) 1993 Joseph Zaher |
14 |
* Copyright (C) 1994 Joseph Zaher, Benjamin Andrew Allan |
15 |
* |
16 |
* The SLV solver is free software; you can redistribute |
17 |
* it and/or modify it under the terms of the GNU General Public License as |
18 |
* published by the Free Software Foundation; either version 2 of the |
19 |
* License, or (at your option) any later version. |
20 |
* |
21 |
* The SLV solver is distributed in hope that it will be |
22 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
24 |
* General Public License for more details. |
25 |
* |
26 |
* You should have received a copy of the GNU General Public License along with |
27 |
* the program; if not, write to the Free Software Foundation, Inc., 675 |
28 |
* Mass Ave, Cambridge, MA 02139 USA. Check the file named COPYING. |
29 |
* COPYING is found in ../compiler. |
30 |
*/ |
31 |
|
32 |
/*************************************************************************** |
33 |
*** Contents: Calculation module |
34 |
*** |
35 |
*** Authors: Karl Westerberg |
36 |
*** Joseph Zaher |
37 |
*** |
38 |
*** Dates: 06/90 - original version |
39 |
*** 08/93 - removed calc_D0, calc_D1, calc_D2, calc_Dn |
40 |
*** and added them as internal functions of the |
41 |
*** exprman module. |
42 |
*** 04/94 - enhanced error messaging |
43 |
*** |
44 |
*** Description: Operations are provided for computing unary and binary |
45 |
*** functions. First, second, and nth derivatives may |
46 |
*** also be computed for all of the functions featured. A |
47 |
*** global boolean variable calc_ok, which is declared |
48 |
*** external so that it may be monitored from other |
49 |
*** modules, will be set to FALSE in the event of a |
50 |
*** calculation error. Also, to suppress printing of error |
51 |
*** messages in the event of an error, set the global |
52 |
*** variable calc_print_errors to FALSE. |
53 |
***************************************************************************/ |
54 |
#ifndef calc__already_included |
55 |
#define calc__already_included |
56 |
|
57 |
extern int32 calc_ok; |
58 |
extern boolean calc_print_errors; |
59 |
/** |
60 |
*** The variable calc_ok will be set to FALSE whenever an undefined |
61 |
*** numerical calculation is attempted. In this case, if the variable |
62 |
*** calc_print_errors is set to TRUE, a description of the error will be |
63 |
*** printed to stderr. In order to monitor errors effectively, it is |
64 |
*** the responsibility of the user to set the calc_ok variable to TRUE |
65 |
*** before calling any of the functions below. |
66 |
**/ |
67 |
|
68 |
#define calc_ERF_COEF 1.1283791670955130 /* = 2 / sqrt(PI) */ |
69 |
#define calc_LOG10_COEF 0.4342944819032518 /* = log10(e) = 1/ln(10) */ |
70 |
#define calc_PI 3.1415926535897930 |
71 |
|
72 |
extern real64 calc_upower(real64, unsigned); |
73 |
extern real64 calc_factorial(unsigned); |
74 |
extern real64 calc_rec(); |
75 |
extern real64 calc_cube(); |
76 |
extern real64 calc_Dn_rec(); |
77 |
#ifdef HAVE_ERF |
78 |
extern real64 calc_erf_inv(); |
79 |
#endif /* HAVE_ERF */ |
80 |
extern real64 calc_lnm_inv(); |
81 |
extern int calc_is_int(); |
82 |
/** |
83 |
*** value = calc_upower(x,n) Compute x^n. |
84 |
*** value = calc_factorial(n) Compute n!. |
85 |
*** value = calc_rec(x) Compute 1/x. |
86 |
*** value = calc_cube(x) Compute x^3 with range check |
87 |
*** value = calc_Dn_rec(x,n) Compute n-th derivative of 1/x. |
88 |
*** value = calc_erf_inv(x) Compute inverse of erf. |
89 |
*** isint = calc_is_int(x) 0,1 ==> even/odd int, else ==> not an int. |
90 |
*** real64 value,x; |
91 |
*** unsigned n; |
92 |
*** int isint; |
93 |
**/ |
94 |
|
95 |
/** All of the following calc_XXXX_Di must resolve to C functions |
96 |
*** rather than macros because calc_func_Di takes the address of them. |
97 |
**/ |
98 |
|
99 |
#define calc_sin_D0 sin |
100 |
#define calc_sinh_D0 sinh |
101 |
#define calc_cos_D0 cos |
102 |
#define calc_cosh_D0 cosh |
103 |
extern real64 calc_tan_D0(); |
104 |
#define calc_tanh_D0 tanh |
105 |
extern real64 calc_arcsin_D0(); |
106 |
#define calc_arcsinh_D0 arcsinh |
107 |
extern real64 calc_arccos_D0(); |
108 |
extern real64 calc_arccosh_D0(); |
109 |
#define calc_arctan_D0 atan |
110 |
extern real64 calc_arctanh_D0(); |
111 |
#ifdef HAVE_ERF |
112 |
#define calc_erf_D0 erf |
113 |
#endif /* HAVE_ERF */ |
114 |
extern real64 calc_exp_D0(); |
115 |
extern real64 calc_ln_D0(); |
116 |
#define calc_lnm_D0 lnm |
117 |
extern real64 calc_log_D0(); |
118 |
#define calc_sqr_D0 sqr |
119 |
extern real64 calc_sqrt_D0(); |
120 |
#define calc_cbrt_D0 cbrt |
121 |
#define calc_fabs_D0 fabs |
122 |
/** |
123 |
*** value = calc_<uop>_D0(x) |
124 |
*** real64 value,x; |
125 |
*** |
126 |
*** Computes value of unary operator. |
127 |
**/ |
128 |
|
129 |
#define calc_sin_D1 cos |
130 |
#define calc_sinh_D1 cosh |
131 |
#define calc_cos_D1 dcos |
132 |
#define calc_cosh_D1 sinh |
133 |
extern real64 calc_tan_D1(double); |
134 |
#define calc_tanh_D1 dtanh |
135 |
extern real64 calc_arcsin_D1(double); |
136 |
#define calc_arcsinh_D1 darcsinh |
137 |
extern real64 calc_arccos_D1(double); |
138 |
extern real64 calc_arccosh_D1(double); |
139 |
#define calc_arctan_D1 datan |
140 |
extern real64 calc_arctanh_D1(double); |
141 |
#ifdef HAVE_ERF |
142 |
extern real64 calc_erf_D1(double); |
143 |
#endif /* HAVE_ERF */ |
144 |
#define calc_exp_D1 calc_exp_D0 |
145 |
#define calc_ln_D1 calc_rec |
146 |
#define calc_lnm_D1 dlnm |
147 |
extern real64 calc_log_D1(double); |
148 |
#define calc_sqr_D1 dsqr |
149 |
extern real64 calc_sqrt_D1(double); |
150 |
extern real64 calc_cbrt_D1(double); |
151 |
extern real64 calc_fabs_D1(double); |
152 |
/** |
153 |
*** value = calc_<uop>_D1(x) |
154 |
*** real64 value,x; |
155 |
*** |
156 |
*** Computes first derivative of unary operator. |
157 |
**/ |
158 |
|
159 |
|
160 |
#define calc_sin_D2 dcos |
161 |
#define calc_sinh_D2 sinh |
162 |
#define calc_cos_D2 dcos2 |
163 |
#define calc_cosh_D2 cosh |
164 |
extern real64 calc_tan_D2(); |
165 |
#define calc_tanh_D2 dtanh2 |
166 |
extern real64 calc_arcsin_D2(); |
167 |
#define calc_arcsinh_D2 darcsinh2 |
168 |
extern real64 calc_arccos_D2(); |
169 |
extern real64 calc_arccosh_D2(); |
170 |
#define calc_arctan_D2 datan2 |
171 |
extern real64 calc_arctanh_D2(); |
172 |
#ifdef HAVE_ERF |
173 |
extern real64 calc_erf_D2(); |
174 |
#endif /* HAVE_ERF */ |
175 |
#define calc_exp_D2 calc_exp_D0 |
176 |
extern real64 calc_ln_D2(); |
177 |
#define calc_lnm_D2 dlnm2 |
178 |
extern real64 calc_log_D2(); |
179 |
#define calc_sqr_D2 dsqr2 |
180 |
extern real64 calc_sqrt_D2(); |
181 |
extern real64 calc_cbrt_D2(); |
182 |
extern real64 calc_fabs_D2(); |
183 |
/** |
184 |
*** value = calc_<uop>_D2(x) |
185 |
*** real64 value,x; |
186 |
*** |
187 |
*** Computes second derivative of unary operator. |
188 |
**/ |
189 |
|
190 |
extern real64 calc_arcsin_Dn(); |
191 |
extern real64 calc_arccos_Dn(); |
192 |
extern real64 calc_arctan_Dn(); |
193 |
extern real64 calc_cos_Dn(); |
194 |
extern real64 calc_sin_Dn(); |
195 |
#ifdef HAVE_ERF |
196 |
extern real64 calc_erf_Dn(); |
197 |
#endif /* HAVE_ERF */ |
198 |
extern real64 calc_exp_Dn(); |
199 |
extern real64 calc_ln_Dn(); |
200 |
extern real64 calc_log_Dn(); |
201 |
extern real64 calc_sqr_Dn(); |
202 |
extern real64 calc_sqrt_Dn(); |
203 |
extern real64 calc_tan_Dn(); |
204 |
extern real64 calc_fabs_Dn(); |
205 |
/** |
206 |
*** value = calc_<uop>_Dn(x,n) |
207 |
*** real64 value,x; |
208 |
*** int n; n >= 0 |
209 |
*** |
210 |
*** Computes n-th derivative of unary operator. |
211 |
**/ |
212 |
|
213 |
#define calc_add_D0(x,y) ((x)+(y)) |
214 |
#define calc_sub_D0(x,y) ((x)-(y)) |
215 |
#define calc_mul_D0(x,y) ((x)*(y)) |
216 |
#define calc_div_D0(x,y) calc_mul_D0(x,calc_rec(y)) |
217 |
#define calc_ipow_D0(x,y) asc_ipow(x,(int)y) |
218 |
extern real64 calc_pow_D0(); |
219 |
/** |
220 |
*** value = calc_<binop>_D0(x,y) |
221 |
*** real64 value,x,y; |
222 |
*** |
223 |
*** Computes x <binop> y and returns the value. |
224 |
**/ |
225 |
|
226 |
#define calc_add_D1(x,y,wrt) (1.0) |
227 |
#define calc_sub_D1(x,y,wrt) (1.0 - 2.0*(wrt)) |
228 |
#define calc_mul_D1(x,y,wrt) ((wrt)==0 ? ((x),(y)) : ((y),(x))) |
229 |
extern real64 calc_div_D1(); |
230 |
#define calc_ipow_D1(x,y) asc_d1ipow(x,(int)y) |
231 |
extern real64 calc_pow_D1(); |
232 |
/** |
233 |
*** diff = calc_<binop>_D1(x,y,wrt) |
234 |
*** real64 diff,x,y; |
235 |
*** int wrt; 0 ==> w.r.t 1st arg, 1 ==> w.r.t. 2nd arg |
236 |
*** |
237 |
*** Computes derivative of x <binop> y w.r.t. x or y depending on wrt. |
238 |
**/ |
239 |
|
240 |
#define calc_add_D2(x,y,wrt1,wrt2) (0.0) |
241 |
#define calc_sub_D2(x,y,wrt1,wrt2) (0.0) |
242 |
#define calc_mul_D2(x,y,wrt1,wrt2) ((wrt1)!=(wrt2)?1.0:0.0) |
243 |
extern real64 calc_div_D2(); |
244 |
#define calc_ipow_D2(x,y) asc_d2ipow(x,(int)y) |
245 |
extern real64 calc_pow_D2(); |
246 |
/** |
247 |
*** diff2 = calc_<binop>_D2(x,y,wrt1,wrt2) |
248 |
*** real64 diff2,x,y; |
249 |
*** int wrt1,wrt2; 0 ==> w.r.t 1st arg, 1 ==> w.r.t. 2nd arg |
250 |
*** |
251 |
*** Computes 2nd derivative of x <binop> y w.r.t. x or y depending on |
252 |
*** wrt1 and wrt2. |
253 |
**/ |
254 |
|
255 |
extern real64 calc_add_Dn(); |
256 |
extern real64 calc_sub_Dn(); |
257 |
extern real64 calc_mul_Dn(); |
258 |
extern real64 calc_div_Dn(); |
259 |
extern real64 calc_pow_Dn(); |
260 |
/** |
261 |
*** diffn = calc_<binop>_Dn(x,y,nwrt0,nwrt1) |
262 |
*** real64 diffn,x,y; |
263 |
*** int nwrt0,nwrt1; |
264 |
*** |
265 |
*** Computes nwrt0'th derivative wrt x of the nwrt1'th derivative wrt y |
266 |
*** of x <binop> y. |
267 |
**/ |
268 |
|
269 |
#endif |