2 static char *RCSid() { return RCSid("$Id: standard.c,v 1.25 2006/07/14 00:30:41 sfeam Exp $"); }
5 /* GNUPLOT - standard.c */
8 * Copyright 1986 - 1993, 1998, 2004 Thomas Williams, Colin Kelley
10 * Permission to use, copy, and distribute this software and its
11 * documentation for any purpose with or without fee is hereby granted,
12 * provided that the above copyright notice appear in all copies and
13 * that both that copyright notice and this permission notice appear
14 * in supporting documentation.
16 * Permission to modify the software is granted, but not the right to
17 * distribute the complete modified source code. Modifications are to
18 * be distributed as patches to the released version. Permission to
19 * distribute binaries produced by compiling modified sources is granted,
21 * 1. distribute the corresponding source modifications from the
22 * released version in the form of a patch file along with the binaries,
23 * 2. add special version identification to distinguish your version
24 * in addition to the base release version number,
25 * 3. provide your name and address as the primary contact for the
26 * support of your modified version, and
27 * 4. retain our contact information in regard to use of the base
29 * Permission to distribute the released version of the source code along
30 * with corresponding source modifications in the form of a patch file is
31 * granted with same provisions 2 through 4 for binary distributions.
33 * This software is provided "as is" without express or implied warranty
34 * to the extent permitted by applicable law.
39 #include "gadgets.h" /* for 'ang2rad' and 'zero' */
40 #include "gp_time.h" /* needed by f_tmsec() and friendsa */
41 #include "util.h" /* for int_error() */
43 static double jzero __PROTO((double x));
44 static double pzero __PROTO((double x));
45 static double qzero __PROTO((double x));
46 static double yzero __PROTO((double x));
47 static double rj0 __PROTO((double x));
48 static double ry0 __PROTO((double x));
49 static double jone __PROTO((double x));
50 static double pone __PROTO((double x));
51 static double qone __PROTO((double x));
52 static double yone __PROTO((double x));
53 static double rj1 __PROTO((double x));
54 static double ry1 __PROTO((double x));
56 /* The bessel function approximations here are from
57 * "Computer Approximations"
58 * by Hart, Cheney et al.
59 * John Wiley & Sons, 1968
62 /* There appears to be a mistake in Hart, Cheney et al. on page 149.
63 * Where it list Qn(x)/x ~ P(z*z)/Q(z*z), z = 8/x, it should read
64 * Qn(x)/z ~ P(z*z)/Q(z*z), z = 8/x
65 * In the functions below, Qn(x) is implementated using the later
67 * These bessel functions are accurate to about 1e-13
70 #if (defined (ATARI) || defined (MTOS)) && defined(__PUREC__)
71 /* Sorry. But PUREC bugs here.
72 * These bessel functions are NOT accurate to about 1e-13
75 #define PI_ON_FOUR 0.785398163397448309615661
76 #define PI_ON_TWO 1.570796326794896619231313
77 #define THREE_PI_ON_FOUR 2.356194490192344928846982
78 #define TWO_ON_PI 0.636619772367581343075535
80 static double dzero = 0.0;
82 /* jzero for x in [0,8]
83 * Index 5849, 19.22 digits precision
85 static double pjzero[] = {
86 0.493378725179413356181681e+21,
87 -0.117915762910761053603844e+21,
88 0.638205934107235656228943e+19,
89 -0.136762035308817138686542e+18,
90 0.143435493914034611166432e+16,
91 -0.808522203485379387119947e+13,
92 0.250715828553688194555516e+11,
93 -0.405041237183313270636066e+8,
94 0.268578685698001498141585e+5
97 static double qjzero[] = {
98 0.493378725179413356211328e+21,
99 0.542891838409228516020019e+19,
100 0.302463561670946269862733e+17,
101 0.112775673967979850705603e+15,
102 0.312304311494121317257247e+12,
103 0.669998767298223967181403e+9,
104 0.111463609846298537818240e+7,
105 0.136306365232897060444281e+4,
109 /* pzero for x in [8,inf]
110 * Index 6548, 18.16 digits precision
112 static double ppzero[] = {
113 0.227790901973046843022700e+5,
114 0.413453866395807657967802e+5,
115 0.211705233808649443219340e+5,
116 0.348064864432492703474453e+4,
117 0.153762019090083542957717e+3,
118 0.889615484242104552360748e+0
121 static double qpzero[] = {
122 0.227790901973046843176842e+5,
123 0.413704124955104166398920e+5,
124 0.212153505618801157304226e+5,
125 0.350287351382356082073561e+4,
126 0.157111598580808936490685e+3,
130 /* qzero for x in [8,inf]
131 * Index 6948, 18.33 digits precision
133 static double pqzero[] = {
134 -0.892266002008000940984692e+2,
135 -0.185919536443429938002522e+3,
136 -0.111834299204827376112621e+3,
137 -0.223002616662141984716992e+2,
138 -0.124410267458356384591379e+1,
139 -0.8803330304868075181663e-2,
142 static double qqzero[] = {
143 0.571050241285120619052476e+4,
144 0.119511315434346136469526e+5,
145 0.726427801692110188369134e+4,
146 0.148872312322837565816135e+4,
147 0.905937695949931258588188e+2,
152 /* yzero for x in [0,8]
153 * Index 6245, 18.78 digits precision
155 static double pyzero[] = {
156 -0.275028667862910958370193e+20,
157 0.658747327571955492599940e+20,
158 -0.524706558111276494129735e+19,
159 0.137562431639934407857134e+18,
160 -0.164860581718572947312208e+16,
161 0.102552085968639428450917e+14,
162 -0.343637122297904037817103e+11,
163 0.591521346568688965427383e+8,
164 -0.413703549793314855412524e+5
167 static double qyzero[] = {
168 0.372645883898616588198998e+21,
169 0.419241704341083997390477e+19,
170 0.239288304349978185743936e+17,
171 0.916203803407518526248915e+14,
172 0.261306575504108124956848e+12,
173 0.579512264070072953738009e+9,
174 0.100170264128890626566665e+7,
175 0.128245277247899380417633e+4,
180 /* jone for x in [0,8]
181 * Index 6050, 20.98 digits precision
183 static double pjone[] = {
184 0.581199354001606143928051e+21,
185 -0.667210656892491629802094e+20,
186 0.231643358063400229793182e+19,
187 -0.358881756991010605074364e+17,
188 0.290879526383477540973760e+15,
189 -0.132298348033212645312547e+13,
190 0.341323418230170053909129e+10,
191 -0.469575353064299585976716e+7,
192 0.270112271089232341485679e+4
195 static double qjone[] = {
196 0.116239870800321228785853e+22,
197 0.118577071219032099983711e+20,
198 0.609206139891752174610520e+17,
199 0.208166122130760735124018e+15,
200 0.524371026216764971540673e+12,
201 0.101386351435867398996705e+10,
202 0.150179359499858550592110e+7,
203 0.160693157348148780197092e+4,
208 /* pone for x in [8,inf]
209 * Index 6749, 18.11 digits precision
211 static double ppone[] = {
212 0.352246649133679798341724e+5,
213 0.627588452471612812690057e+5,
214 0.313539631109159574238670e+5,
215 0.498548320605943384345005e+4,
216 0.211152918285396238210572e+3,
217 0.12571716929145341558495e+1
220 static double qpone[] = {
221 0.352246649133679798068390e+5,
222 0.626943469593560511888834e+5,
223 0.312404063819041039923016e+5,
224 0.493039649018108897938610e+4,
225 0.203077518913475932229357e+3,
229 /* qone for x in [8,inf]
230 * Index 7149, 18.28 digits precision
232 static double pqone[] = {
233 0.351175191430355282253332e+3,
234 0.721039180490447503928086e+3,
235 0.425987301165444238988699e+3,
236 0.831898957673850827325226e+2,
237 0.45681716295512267064405e+1,
238 0.3532840052740123642735e-1
241 static double qqone[] = {
242 0.749173741718091277145195e+4,
243 0.154141773392650970499848e+5,
244 0.915223170151699227059047e+4,
245 0.181118670055235135067242e+4,
246 0.103818758546213372877664e+3,
251 /* yone for x in [0,8]
252 * Index 6444, 18.24 digits precision
254 static double pyone[] = {
255 -0.292382196153296254310105e+20,
256 0.774852068218683964508809e+19,
257 -0.344104806308411444618546e+18,
258 0.591516076049007061849632e+16,
259 -0.486331694256717507482813e+14,
260 0.204969667374566218261980e+12,
261 -0.428947196885524880182182e+9,
262 0.355692400983052605669132e+6
265 static double qyone[] = {
266 0.149131151130292035017408e+21,
267 0.181866284170613498688507e+19,
268 0.113163938269888452690508e+17,
269 0.475517358888813771309277e+14,
270 0.150022169915670898716637e+12,
271 0.371666079862193028559693e+9,
272 0.726914730719888456980191e+6,
273 0.107269614377892552332213e+4,
279 #define PI_ON_FOUR 0.78539816339744830961566084581987572
280 #define PI_ON_TWO 1.57079632679489661923131269163975144
281 #define THREE_PI_ON_FOUR 2.35619449019234492884698253745962716
282 #define TWO_ON_PI 0.63661977236758134307553505349005744
284 static double dzero = 0.0;
286 /* jzero for x in [0,8]
287 * Index 5849, 19.22 digits precision
289 static double GPFAR pjzero[] = {
290 0.4933787251794133561816813446e+21,
291 -0.11791576291076105360384408e+21,
292 0.6382059341072356562289432465e+19,
293 -0.1367620353088171386865416609e+18,
294 0.1434354939140346111664316553e+16,
295 -0.8085222034853793871199468171e+13,
296 0.2507158285536881945555156435e+11,
297 -0.4050412371833132706360663322e+8,
298 0.2685786856980014981415848441e+5
301 static double GPFAR qjzero[] = {
302 0.4933787251794133562113278438e+21,
303 0.5428918384092285160200195092e+19,
304 0.3024635616709462698627330784e+17,
305 0.1127756739679798507056031594e+15,
306 0.3123043114941213172572469442e+12,
307 0.669998767298223967181402866e+9,
308 0.1114636098462985378182402543e+7,
309 0.1363063652328970604442810507e+4,
313 /* pzero for x in [8,inf]
314 * Index 6548, 18.16 digits precision
316 static double GPFAR ppzero[] = {
317 0.2277909019730468430227002627e+5,
318 0.4134538663958076579678016384e+5,
319 0.2117052338086494432193395727e+5,
320 0.348064864432492703474453111e+4,
321 0.15376201909008354295771715e+3,
322 0.889615484242104552360748e+0
325 static double GPFAR qpzero[] = {
326 0.2277909019730468431768423768e+5,
327 0.4137041249551041663989198384e+5,
328 0.2121535056188011573042256764e+5,
329 0.350287351382356082073561423e+4,
330 0.15711159858080893649068482e+3,
334 /* qzero for x in [8,inf]
335 * Index 6948, 18.33 digits precision
337 static double GPFAR pqzero[] = {
338 -0.8922660020080009409846916e+2,
339 -0.18591953644342993800252169e+3,
340 -0.11183429920482737611262123e+3,
341 -0.2230026166621419847169915e+2,
342 -0.124410267458356384591379e+1,
343 -0.8803330304868075181663e-2,
346 static double GPFAR qqzero[] = {
347 0.571050241285120619052476459e+4,
348 0.1195113154343461364695265329e+5,
349 0.726427801692110188369134506e+4,
350 0.148872312322837565816134698e+4,
351 0.9059376959499312585881878e+2,
356 /* yzero for x in [0,8]
357 * Index 6245, 18.78 digits precision
359 static double GPFAR pyzero[] = {
360 -0.2750286678629109583701933175e+20,
361 0.6587473275719554925999402049e+20,
362 -0.5247065581112764941297350814e+19,
363 0.1375624316399344078571335453e+18,
364 -0.1648605817185729473122082537e+16,
365 0.1025520859686394284509167421e+14,
366 -0.3436371222979040378171030138e+11,
367 0.5915213465686889654273830069e+8,
368 -0.4137035497933148554125235152e+5
371 static double GPFAR qyzero[] = {
372 0.3726458838986165881989980739e+21,
373 0.4192417043410839973904769661e+19,
374 0.2392883043499781857439356652e+17,
375 0.9162038034075185262489147968e+14,
376 0.2613065755041081249568482092e+12,
377 0.5795122640700729537380087915e+9,
378 0.1001702641288906265666651753e+7,
379 0.1282452772478993804176329391e+4,
384 /* jone for x in [0,8]
385 * Index 6050, 20.98 digits precision
387 static double GPFAR pjone[] = {
388 0.581199354001606143928050809e+21,
389 -0.6672106568924916298020941484e+20,
390 0.2316433580634002297931815435e+19,
391 -0.3588817569910106050743641413e+17,
392 0.2908795263834775409737601689e+15,
393 -0.1322983480332126453125473247e+13,
394 0.3413234182301700539091292655e+10,
395 -0.4695753530642995859767162166e+7,
396 0.270112271089232341485679099e+4
399 static double GPFAR qjone[] = {
400 0.11623987080032122878585294e+22,
401 0.1185770712190320999837113348e+20,
402 0.6092061398917521746105196863e+17,
403 0.2081661221307607351240184229e+15,
404 0.5243710262167649715406728642e+12,
405 0.1013863514358673989967045588e+10,
406 0.1501793594998585505921097578e+7,
407 0.1606931573481487801970916749e+4,
412 /* pone for x in [8,inf]
413 * Index 6749, 18.11 digits precision
415 static double GPFAR ppone[] = {
416 0.352246649133679798341724373e+5,
417 0.62758845247161281269005675e+5,
418 0.313539631109159574238669888e+5,
419 0.49854832060594338434500455e+4,
420 0.2111529182853962382105718e+3,
421 0.12571716929145341558495e+1
424 static double GPFAR qpone[] = {
425 0.352246649133679798068390431e+5,
426 0.626943469593560511888833731e+5,
427 0.312404063819041039923015703e+5,
428 0.4930396490181088979386097e+4,
429 0.2030775189134759322293574e+3,
433 /* qone for x in [8,inf]
434 * Index 7149, 18.28 digits precision
436 static double GPFAR pqone[] = {
437 0.3511751914303552822533318e+3,
438 0.7210391804904475039280863e+3,
439 0.4259873011654442389886993e+3,
440 0.831898957673850827325226e+2,
441 0.45681716295512267064405e+1,
442 0.3532840052740123642735e-1
445 static double GPFAR qqone[] = {
446 0.74917374171809127714519505e+4,
447 0.154141773392650970499848051e+5,
448 0.91522317015169922705904727e+4,
449 0.18111867005523513506724158e+4,
450 0.1038187585462133728776636e+3,
455 /* yone for x in [0,8]
456 * Index 6444, 18.24 digits precision
458 static double GPFAR pyone[] = {
459 -0.2923821961532962543101048748e+20,
460 0.7748520682186839645088094202e+19,
461 -0.3441048063084114446185461344e+18,
462 0.5915160760490070618496315281e+16,
463 -0.4863316942567175074828129117e+14,
464 0.2049696673745662182619800495e+12,
465 -0.4289471968855248801821819588e+9,
466 0.3556924009830526056691325215e+6
469 static double GPFAR qyone[] = {
470 0.1491311511302920350174081355e+21,
471 0.1818662841706134986885065935e+19,
472 0.113163938269888452690508283e+17,
473 0.4755173588888137713092774006e+14,
474 0.1500221699156708987166369115e+12,
475 0.3716660798621930285596927703e+9,
476 0.726914730719888456980191315e+6,
477 0.10726961437789255233221267e+4,
481 #endif /* (ATARI || MTOS) && __PUREC__ */
483 #if (GP_STRING_VARS > 1)
485 * Make all the following internal routines perform autoconversion
486 * from string to numeric value.
488 #define pop(x) pop_or_convert_from_string(x)
492 f_real(union argument *arg)
496 (void) arg; /* avoid -Wunused warning */
497 push(Gcomplex(&a, real(pop(&a)), 0.0));
501 f_imag(union argument *arg)
505 (void) arg; /* avoid -Wunused warning */
506 push(Gcomplex(&a, imag(pop(&a)), 0.0));
510 /* ang2rad is 1 if we are in radians, or pi/180 if we are in degrees */
512 f_arg(union argument *arg)
516 (void) arg; /* avoid -Wunused warning */
517 push(Gcomplex(&a, angle(pop(&a)) / ang2rad, 0.0));
521 f_conjg(union argument *arg)
525 (void) arg; /* avoid -Wunused warning */
527 push(Gcomplex(&a, real(&a), -imag(&a)));
530 /* ang2rad is 1 if we are in radians, or pi/180 if we are in degrees */
533 f_sin(union argument *arg)
537 (void) arg; /* avoid -Wunused warning */
539 push(Gcomplex(&a, sin(ang2rad * real(&a)) * cosh(ang2rad * imag(&a)), cos(ang2rad * real(&a)) * sinh(ang2rad * imag(&a))));
543 f_cos(union argument *arg)
547 (void) arg; /* avoid -Wunused warning */
549 push(Gcomplex(&a, cos(ang2rad * real(&a)) * cosh(ang2rad * imag(&a)), -sin(ang2rad * real(&a)) * sinh(ang2rad * imag(&a))));
553 f_tan(union argument *arg)
558 (void) arg; /* avoid -Wunused warning */
561 push(Gcomplex(&a, tan(ang2rad * real(&a)), 0.0));
563 den = cos(2 * ang2rad * real(&a)) + cosh(2 * ang2rad * imag(&a));
568 push(Gcomplex(&a, sin(2 * ang2rad * real(&a)) / den, sinh(2 * ang2rad * imag(&a)) / den));
573 f_asin(union argument *arg)
576 double alpha, beta, x, y;
578 (void) arg; /* avoid -Wunused warning */
582 if (y == 0.0 && fabs(x) <= 1.0) {
583 push(Gcomplex(&a, asin(x) / ang2rad, 0.0));
584 } else if (x == 0.0) {
585 push(Gcomplex(&a, 0.0, -log(-y + sqrt(y * y + 1)) / ang2rad));
587 beta = sqrt((x + 1) * (x + 1) + y * y) / 2 - sqrt((x - 1) * (x - 1) + y * y) / 2;
589 beta = 1; /* Avoid rounding error problems */
590 alpha = sqrt((x + 1) * (x + 1) + y * y) / 2 + sqrt((x - 1) * (x - 1) + y * y) / 2;
591 push(Gcomplex(&a, asin(beta) / ang2rad, -log(alpha + sqrt(alpha * alpha - 1)) / ang2rad));
596 f_acos(union argument *arg)
601 (void) arg; /* avoid -Wunused warning */
605 if (y == 0.0 && fabs(x) <= 1.0) {
607 push(Gcomplex(&a, acos(x) / ang2rad, 0.0));
609 double alpha = sqrt((x + 1) * (x + 1) + y * y) / 2
610 + sqrt((x - 1) * (x - 1) + y * y) / 2;
611 double beta = sqrt((x + 1) * (x + 1) + y * y) / 2
612 - sqrt((x - 1) * (x - 1) + y * y) / 2;
614 beta = 1; /* Avoid rounding error problems */
617 push(Gcomplex(&a, (y > 0? -1: 1)*acos(beta) / ang2rad,
618 log(alpha + sqrt(alpha * alpha - 1)) / ang2rad));
623 f_atan(union argument *arg)
626 double x, y, u, v, w, z;
628 (void) arg; /* avoid -Wunused warning */
633 push(Gcomplex(&a, atan(x) / ang2rad, 0.0));
634 else if (x == 0.0 && fabs(y) >= 1.0) {
636 push(Gcomplex(&a, 0.0, 0.0));
646 z = atan(2 * u / (1 - u * u - v * v));
647 w = log((u * u + (v + 1) * (v + 1)) / (u * u + (v - 1) * (v - 1))) / 4;
649 z = z + 2 * PI_ON_TWO;
654 push(Gcomplex(&a, 0.5 * z / ang2rad, w));
658 /* real parts only */
660 f_atan2(union argument *arg)
666 (void) arg; /* avoid -Wunused warning */
670 if (x == 0.0 && y == 0.0) {
672 push(Ginteger(&a, 0));
674 push(Gcomplex(&a, atan2(y, x) / ang2rad, 0.0));
679 f_sinh(union argument *arg)
683 (void) arg; /* avoid -Wunused warning */
685 push(Gcomplex(&a, sinh(real(&a)) * cos(imag(&a)), cosh(real(&a)) * sin(imag(&a))));
689 f_cosh(union argument *arg)
693 (void) arg; /* avoid -Wunused warning */
695 push(Gcomplex(&a, cosh(real(&a)) * cos(imag(&a)), sinh(real(&a)) * sin(imag(&a))));
699 f_tanh(union argument *arg)
703 double real_2arg, imag_2arg;
705 (void) arg; /* avoid -Wunused warning */
708 real_2arg = 2. * real(&a);
709 imag_2arg = 2. * imag(&a);
712 if (-fabs(real_2arg) < E_MINEXP) {
713 push(Gcomplex(&a, real_2arg < 0 ? -1.0 : 1.0, 0.0));
718 int old_errno = errno;
720 if (exp(-fabs(real_2arg)) == 0.0) {
721 /* some libm's will raise a silly ERANGE in cosh() and sin() */
723 push(Gcomplex(&a, real_2arg < 0 ? -1.0 : 1.0, 0.0));
729 den = cosh(real_2arg) + cos(imag_2arg);
730 push(Gcomplex(&a, sinh(real_2arg) / den, sin(imag_2arg) / den));
734 f_asinh(union argument *arg)
736 struct value a; /* asinh(z) = -I*asin(I*z) */
737 double alpha, beta, x, y;
739 (void) arg; /* avoid -Wunused warning */
743 if (y == 0.0 && fabs(x) <= 1.0) {
744 push(Gcomplex(&a, 0.0, -asin(x) / ang2rad));
745 } else if (y == 0.0) {
746 push(Gcomplex(&a, 0.0, 0.0));
748 } else if (x == 0.0) {
749 push(Gcomplex(&a, log(y + sqrt(y * y + 1)) / ang2rad, 0.0));
751 beta = sqrt((x + 1) * (x + 1) + y * y) / 2 - sqrt((x - 1) * (x - 1) + y * y) / 2;
752 alpha = sqrt((x + 1) * (x + 1) + y * y) / 2 + sqrt((x - 1) * (x - 1) + y * y) / 2;
753 push(Gcomplex(&a, log(alpha + sqrt(alpha * alpha - 1)) / ang2rad, -asin(beta) / ang2rad));
758 f_acosh(union argument *arg)
761 double alpha, beta, x, y; /* acosh(z) = I*acos(z) */
763 (void) arg; /* avoid -Wunused warning */
767 if (y == 0.0 && fabs(x) <= 1.0) {
768 push(Gcomplex(&a, 0.0, acos(x) / ang2rad));
770 push(Gcomplex(&a, log(x + sqrt(x * x - 1)) / ang2rad, 0.0));
772 alpha = sqrt((x + 1) * (x + 1) + y * y) / 2
773 + sqrt((x - 1) * (x - 1) + y * y) / 2;
774 beta = sqrt((x + 1) * (x + 1) + y * y) / 2
775 - sqrt((x - 1) * (x - 1) + y * y) / 2;
776 push(Gcomplex(&a, log(alpha + sqrt(alpha * alpha - 1)) / ang2rad,
777 (y<0 ? -1 : 1) * acos(beta) / ang2rad));
782 f_atanh(union argument *arg)
785 double x, y, u, v, w, z; /* atanh(z) = -I*atan(I*z) */
787 (void) arg; /* avoid -Wunused warning */
792 push(Gcomplex(&a, 0.0, -atan(x) / ang2rad));
793 else if (x == 0.0 && fabs(y) >= 1.0) {
795 push(Gcomplex(&a, 0.0, 0.0));
805 z = atan(2 * u / (1 - u * u - v * v));
806 w = log((u * u + (v + 1) * (v + 1)) / (u * u + (v - 1) * (v - 1))) / 4;
808 z = z + 2 * PI_ON_TWO;
813 push(Gcomplex(&a, w, -0.5 * z / ang2rad));
818 f_int(union argument *arg)
822 (void) arg; /* avoid -Wunused warning */
823 push(Ginteger(&a, (int) real(pop(&a))));
826 #define BAD_DEFAULT default: int_error(NO_CARET, "internal error : argument neither INT or CMPLX")
829 f_abs(union argument *arg)
833 (void) arg; /* avoid -Wunused warning */
837 push(Ginteger(&a, abs(a.v.int_val)));
840 push(Gcomplex(&a, magnitude(&a), 0.0));
847 f_sgn(union argument *arg)
851 (void) arg; /* avoid -Wunused warning */
855 push(Ginteger(&a, (a.v.int_val > 0) ? 1 :
856 (a.v.int_val < 0) ? -1 : 0));
859 push(Ginteger(&a, (a.v.cmplx_val.real > 0.0) ? 1 :
860 (a.v.cmplx_val.real < 0.0) ? -1 : 0));
868 f_sqrt(union argument *arg)
873 (void) arg; /* avoid -Wunused warning */
875 mag = sqrt(magnitude(&a));
876 if (imag(&a) == 0.0) {
878 push(Gcomplex(&a, 0.0, mag));
880 push(Gcomplex(&a, mag, 0.0));
882 /* -pi < ang < pi, so real(sqrt(z)) >= 0 */
883 double ang = angle(&a) / 2.0;
884 push(Gcomplex(&a, mag * cos(ang), mag * sin(ang)));
890 f_exp(union argument *arg)
895 (void) arg; /* avoid -Wunused warning */
897 mag = gp_exp(real(&a));
899 push(Gcomplex(&a, mag * cos(ang), mag * sin(ang)));
904 f_log10(union argument *arg)
908 (void) arg; /* avoid -Wunused warning */
910 if (magnitude(&a) == 0.0) {
914 push(Gcomplex(&a, log(magnitude(&a)) / M_LN10, angle(&a) / M_LN10));
919 f_log(union argument *arg)
923 (void) arg; /* avoid -Wunused warning */
925 if (magnitude(&a) == 0.0) {
929 push(Gcomplex(&a, log(magnitude(&a)), angle(&a)));
934 f_floor(union argument *arg)
938 (void) arg; /* avoid -Wunused warning */
942 push(Ginteger(&a, (int) floor((double) a.v.int_val)));
945 push(Ginteger(&a, (int) floor(a.v.cmplx_val.real)));
953 f_ceil(union argument *arg)
957 (void) arg; /* avoid -Wunused warning */
961 push(Ginteger(&a, (int) ceil((double) a.v.int_val)));
964 push(Ginteger(&a, (int) ceil(a.v.cmplx_val.real)));
970 #if (GP_STRING_VARS > 1)
971 /* Terminate the autoconversion from string to numeric values */
975 /* EAM - replacement for defined(foo) + f_pushv + f_isvar
976 * implements exists("foo") instead
979 f_exists(union argument *arg)
981 #ifdef GP_STRING_VARS
984 (void) arg; /* avoid -Wunused warning */
987 if (a.type == STRING) {
988 struct udvt_entry *udv = add_udv_by_name(a.v.string_val);
990 push(Ginteger(&a, udv->udv_undef ? 0 : 1));
992 push(Ginteger(&a, 0));
997 /* bessel function approximations */
1007 for (n = 7; n >= 0; n--) {
1008 p = p * x2 + pjzero[n];
1009 q = q * x2 + qjzero[n];
1024 for (n = 4; n >= 0; n--) {
1025 p = p * z2 + ppzero[n];
1026 q = q * z2 + qpzero[n];
1041 for (n = 4; n >= 0; n--) {
1042 p = p * z2 + pqzero[n];
1043 q = q * z2 + qqzero[n];
1057 for (n = 7; n >= 0; n--) {
1058 p = p * x2 + pyzero[n];
1059 q = q * x2 + qyzero[n];
1072 return (sqrt(TWO_ON_PI / x) *
1073 (pzero(x) * cos(x - PI_ON_FOUR) - 8.0 / x * qzero(x) * sin(x - PI_ON_FOUR)));
1081 return (dzero / dzero); /* error */
1083 return (yzero(x) + TWO_ON_PI * rj0(x) * log(x));
1085 return (sqrt(TWO_ON_PI / x) *
1086 (pzero(x) * sin(x - PI_ON_FOUR) +
1087 (8.0 / x) * qzero(x) * cos(x - PI_ON_FOUR)));
1101 for (n = 7; n >= 0; n--) {
1102 p = p * x2 + pjone[n];
1103 q = q * x2 + qjone[n];
1118 for (n = 4; n >= 0; n--) {
1119 p = p * z2 + ppone[n];
1120 q = q * z2 + qpone[n];
1135 for (n = 4; n >= 0; n--) {
1136 p = p * z2 + pqone[n];
1137 q = q * z2 + qqone[n];
1151 for (n = 7; n >= 0; n--) {
1152 p = p * x2 + pyone[n];
1153 q = q * x2 + qyone[n];
1166 return (v * jone(x));
1168 w = sqrt(TWO_ON_PI / x) *
1169 (pone(x) * cos(x - THREE_PI_ON_FOUR) -
1170 8.0 / x * qone(x) * sin(x - THREE_PI_ON_FOUR));
1181 return (dzero / dzero); /* error */
1183 return (x * yone(x) + TWO_ON_PI * (rj1(x) * log(x) - 1.0 / x));
1185 return (sqrt(TWO_ON_PI / x) *
1186 (pone(x) * sin(x - THREE_PI_ON_FOUR) +
1187 (8.0 / x) * qone(x) * cos(x - THREE_PI_ON_FOUR)));
1191 /* FIXME HBB 20010726: should bessel functions really call int_error,
1192 * right in the middle of evaluating some mathematical expression?
1193 * Couldn't they just flag 'undefined', or ignore the real part of the
1194 * complex number? */
1197 f_besj0(union argument *arg)
1201 (void) arg; /* avoid -Wunused warning */
1203 if (fabs(imag(&a)) > zero)
1204 int_error(NO_CARET, "can only do bessel functions of reals");
1205 push(Gcomplex(&a, rj0(real(&a)), 0.0));
1210 f_besj1(union argument *arg)
1214 (void) arg; /* avoid -Wunused warning */
1216 if (fabs(imag(&a)) > zero)
1217 int_error(NO_CARET, "can only do bessel functions of reals");
1218 push(Gcomplex(&a, rj1(real(&a)), 0.0));
1223 f_besy0(union argument *arg)
1227 (void) arg; /* avoid -Wunused warning */
1229 if (fabs(imag(&a)) > zero)
1230 int_error(NO_CARET, "can only do bessel functions of reals");
1232 push(Gcomplex(&a, ry0(real(&a)), 0.0));
1234 push(Gcomplex(&a, 0.0, 0.0));
1241 f_besy1(union argument *arg)
1245 (void) arg; /* avoid -Wunused warning */
1247 if (fabs(imag(&a)) > zero)
1248 int_error(NO_CARET, "can only do bessel functions of reals");
1250 push(Gcomplex(&a, ry1(real(&a)), 0.0));
1252 push(Gcomplex(&a, 0.0, 0.0));
1258 /* functions for accessing fields from tm structure, for time series
1259 * they are all the same, so define a macro
1261 #define TIMEFUNC(name, field) \
1263 name(union argument *arg) \
1268 (void) arg; /* avoid -Wunused warning */ \
1270 ggmtime(&tm, real(&a)); \
1271 push(Gcomplex(&a, (double)tm.field, 0.0)); \
1274 TIMEFUNC( f_tmsec, tm_sec)
1275 TIMEFUNC( f_tmmin, tm_min)
1276 TIMEFUNC( f_tmhour, tm_hour)
1277 TIMEFUNC( f_tmmday, tm_mday)
1278 TIMEFUNC( f_tmmon, tm_mon)
1279 TIMEFUNC( f_tmyear, tm_year)
1280 TIMEFUNC( f_tmwday, tm_wday)
1281 TIMEFUNC( f_tmyday, tm_yday)