Annotation of OpenXM_contrib/gnuplot/standard.c, Revision 1.1
1.1 ! maekawa 1: #ifndef lint
! 2: static char *RCSid = "$Id: standard.c,v 1.24 1998/04/14 00:16:21 drd Exp $";
! 3: #endif
! 4:
! 5: /* GNUPLOT - standard.c */
! 6:
! 7: /*[
! 8: * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
! 9: *
! 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.
! 15: *
! 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,
! 20: * provided you
! 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
! 28: * software.
! 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.
! 32: *
! 33: * This software is provided "as is" without express or implied warranty
! 34: * to the extent permitted by applicable law.
! 35: ]*/
! 36:
! 37: #include "plot.h"
! 38: #include "setshow.h" /* for ang2rad */
! 39: #include "fnproto.h"
! 40:
! 41: extern struct value stack[STACK_DEPTH];
! 42: extern int s_p;
! 43: extern double zero;
! 44:
! 45: static double jzero __PROTO((double x));
! 46: static double pzero __PROTO((double x));
! 47: static double qzero __PROTO((double x));
! 48: static double yzero __PROTO((double x));
! 49: static double rj0 __PROTO((double x));
! 50: static double ry0 __PROTO((double x));
! 51: static double jone __PROTO((double x));
! 52: static double pone __PROTO((double x));
! 53: static double qone __PROTO((double x));
! 54: static double yone __PROTO((double x));
! 55: static double rj1 __PROTO((double x));
! 56: static double ry1 __PROTO((double x));
! 57:
! 58: /* The bessel function approximations here are from
! 59: * "Computer Approximations"
! 60: * by Hart, Cheney et al.
! 61: * John Wiley & Sons, 1968
! 62: */
! 63:
! 64: /* There appears to be a mistake in Hart, Cheney et al. on page 149.
! 65: * Where it list Qn(x)/x ~ P(z*z)/Q(z*z), z = 8/x, it should read
! 66: * Qn(x)/z ~ P(z*z)/Q(z*z), z = 8/x
! 67: * In the functions below, Qn(x) is implementated using the later
! 68: * equation.
! 69: * These bessel functions are accurate to about 1e-13
! 70: */
! 71:
! 72: #if (defined (ATARI) || defined (MTOS)) && defined(__PUREC__)
! 73: /* Sorry. But PUREC bugs here.
! 74: * These bessel functions are NOT accurate to about 1e-13
! 75: */
! 76:
! 77: #define PI_ON_FOUR 0.785398163397448309615661
! 78: #define PI_ON_TWO 1.570796326794896619231313
! 79: #define THREE_PI_ON_FOUR 2.356194490192344928846982
! 80: #define TWO_ON_PI 0.636619772367581343075535
! 81:
! 82: static double dzero = 0.0;
! 83:
! 84: /* jzero for x in [0,8]
! 85: * Index 5849, 19.22 digits precision
! 86: */
! 87: static double pjzero[] = {
! 88: 0.493378725179413356181681e+21,
! 89: -0.117915762910761053603844e+21,
! 90: 0.638205934107235656228943e+19,
! 91: -0.136762035308817138686542e+18,
! 92: 0.143435493914034611166432e+16,
! 93: -0.808522203485379387119947e+13,
! 94: 0.250715828553688194555516e+11,
! 95: -0.405041237183313270636066e+8,
! 96: 0.268578685698001498141585e+5
! 97: };
! 98:
! 99: static double qjzero[] = {
! 100: 0.493378725179413356211328e+21,
! 101: 0.542891838409228516020019e+19,
! 102: 0.302463561670946269862733e+17,
! 103: 0.112775673967979850705603e+15,
! 104: 0.312304311494121317257247e+12,
! 105: 0.669998767298223967181403e+9,
! 106: 0.111463609846298537818240e+7,
! 107: 0.136306365232897060444281e+4,
! 108: 0.1e+1
! 109: };
! 110:
! 111: /* pzero for x in [8,inf]
! 112: * Index 6548, 18.16 digits precision
! 113: */
! 114: static double ppzero[] = {
! 115: 0.227790901973046843022700e+5,
! 116: 0.413453866395807657967802e+5,
! 117: 0.211705233808649443219340e+5,
! 118: 0.348064864432492703474453e+4,
! 119: 0.153762019090083542957717e+3,
! 120: 0.889615484242104552360748e+0
! 121: };
! 122:
! 123: static double qpzero[] = {
! 124: 0.227790901973046843176842e+5,
! 125: 0.413704124955104166398920e+5,
! 126: 0.212153505618801157304226e+5,
! 127: 0.350287351382356082073561e+4,
! 128: 0.157111598580808936490685e+3,
! 129: 0.1e+1
! 130: };
! 131:
! 132: /* qzero for x in [8,inf]
! 133: * Index 6948, 18.33 digits precision
! 134: */
! 135: static double pqzero[] = {
! 136: -0.892266002008000940984692e+2,
! 137: -0.185919536443429938002522e+3,
! 138: -0.111834299204827376112621e+3,
! 139: -0.223002616662141984716992e+2,
! 140: -0.124410267458356384591379e+1,
! 141: -0.8803330304868075181663e-2,
! 142: };
! 143:
! 144: static double qqzero[] = {
! 145: 0.571050241285120619052476e+4,
! 146: 0.119511315434346136469526e+5,
! 147: 0.726427801692110188369134e+4,
! 148: 0.148872312322837565816135e+4,
! 149: 0.905937695949931258588188e+2,
! 150: 0.1e+1
! 151: };
! 152:
! 153:
! 154: /* yzero for x in [0,8]
! 155: * Index 6245, 18.78 digits precision
! 156: */
! 157: static double pyzero[] = {
! 158: -0.275028667862910958370193e+20,
! 159: 0.658747327571955492599940e+20,
! 160: -0.524706558111276494129735e+19,
! 161: 0.137562431639934407857134e+18,
! 162: -0.164860581718572947312208e+16,
! 163: 0.102552085968639428450917e+14,
! 164: -0.343637122297904037817103e+11,
! 165: 0.591521346568688965427383e+8,
! 166: -0.413703549793314855412524e+5
! 167: };
! 168:
! 169: static double qyzero[] = {
! 170: 0.372645883898616588198998e+21,
! 171: 0.419241704341083997390477e+19,
! 172: 0.239288304349978185743936e+17,
! 173: 0.916203803407518526248915e+14,
! 174: 0.261306575504108124956848e+12,
! 175: 0.579512264070072953738009e+9,
! 176: 0.100170264128890626566665e+7,
! 177: 0.128245277247899380417633e+4,
! 178: 0.1e+1
! 179: };
! 180:
! 181:
! 182: /* jone for x in [0,8]
! 183: * Index 6050, 20.98 digits precision
! 184: */
! 185: static double pjone[] = {
! 186: 0.581199354001606143928051e+21,
! 187: -0.667210656892491629802094e+20,
! 188: 0.231643358063400229793182e+19,
! 189: -0.358881756991010605074364e+17,
! 190: 0.290879526383477540973760e+15,
! 191: -0.132298348033212645312547e+13,
! 192: 0.341323418230170053909129e+10,
! 193: -0.469575353064299585976716e+7,
! 194: 0.270112271089232341485679e+4
! 195: };
! 196:
! 197: static double qjone[] = {
! 198: 0.116239870800321228785853e+22,
! 199: 0.118577071219032099983711e+20,
! 200: 0.609206139891752174610520e+17,
! 201: 0.208166122130760735124018e+15,
! 202: 0.524371026216764971540673e+12,
! 203: 0.101386351435867398996705e+10,
! 204: 0.150179359499858550592110e+7,
! 205: 0.160693157348148780197092e+4,
! 206: 0.1e+1
! 207: };
! 208:
! 209:
! 210: /* pone for x in [8,inf]
! 211: * Index 6749, 18.11 digits precision
! 212: */
! 213: static double ppone[] = {
! 214: 0.352246649133679798341724e+5,
! 215: 0.627588452471612812690057e+5,
! 216: 0.313539631109159574238670e+5,
! 217: 0.498548320605943384345005e+4,
! 218: 0.211152918285396238210572e+3,
! 219: 0.12571716929145341558495e+1
! 220: };
! 221:
! 222: static double qpone[] = {
! 223: 0.352246649133679798068390e+5,
! 224: 0.626943469593560511888834e+5,
! 225: 0.312404063819041039923016e+5,
! 226: 0.493039649018108897938610e+4,
! 227: 0.203077518913475932229357e+3,
! 228: 0.1e+1
! 229: };
! 230:
! 231: /* qone for x in [8,inf]
! 232: * Index 7149, 18.28 digits precision
! 233: */
! 234: static double pqone[] = {
! 235: 0.351175191430355282253332e+3,
! 236: 0.721039180490447503928086e+3,
! 237: 0.425987301165444238988699e+3,
! 238: 0.831898957673850827325226e+2,
! 239: 0.45681716295512267064405e+1,
! 240: 0.3532840052740123642735e-1
! 241: };
! 242:
! 243: static double qqone[] = {
! 244: 0.749173741718091277145195e+4,
! 245: 0.154141773392650970499848e+5,
! 246: 0.915223170151699227059047e+4,
! 247: 0.181118670055235135067242e+4,
! 248: 0.103818758546213372877664e+3,
! 249: 0.1e+1
! 250: };
! 251:
! 252:
! 253: /* yone for x in [0,8]
! 254: * Index 6444, 18.24 digits precision
! 255: */
! 256: static double pyone[] = {
! 257: -0.292382196153296254310105e+20,
! 258: 0.774852068218683964508809e+19,
! 259: -0.344104806308411444618546e+18,
! 260: 0.591516076049007061849632e+16,
! 261: -0.486331694256717507482813e+14,
! 262: 0.204969667374566218261980e+12,
! 263: -0.428947196885524880182182e+9,
! 264: 0.355692400983052605669132e+6
! 265: };
! 266:
! 267: static double qyone[] = {
! 268: 0.149131151130292035017408e+21,
! 269: 0.181866284170613498688507e+19,
! 270: 0.113163938269888452690508e+17,
! 271: 0.475517358888813771309277e+14,
! 272: 0.150022169915670898716637e+12,
! 273: 0.371666079862193028559693e+9,
! 274: 0.726914730719888456980191e+6,
! 275: 0.107269614377892552332213e+4,
! 276: 0.1e+1
! 277: };
! 278:
! 279: #else
! 280:
! 281: #define PI_ON_FOUR 0.78539816339744830961566084581987572
! 282: #define PI_ON_TWO 1.57079632679489661923131269163975144
! 283: #define THREE_PI_ON_FOUR 2.35619449019234492884698253745962716
! 284: #define TWO_ON_PI 0.63661977236758134307553505349005744
! 285:
! 286: static double dzero = 0.0;
! 287:
! 288: /* jzero for x in [0,8]
! 289: * Index 5849, 19.22 digits precision
! 290: */
! 291: static double GPFAR pjzero[] = {
! 292: 0.4933787251794133561816813446e+21,
! 293: -0.11791576291076105360384408e+21,
! 294: 0.6382059341072356562289432465e+19,
! 295: -0.1367620353088171386865416609e+18,
! 296: 0.1434354939140346111664316553e+16,
! 297: -0.8085222034853793871199468171e+13,
! 298: 0.2507158285536881945555156435e+11,
! 299: -0.4050412371833132706360663322e+8,
! 300: 0.2685786856980014981415848441e+5
! 301: };
! 302:
! 303: static double GPFAR qjzero[] = {
! 304: 0.4933787251794133562113278438e+21,
! 305: 0.5428918384092285160200195092e+19,
! 306: 0.3024635616709462698627330784e+17,
! 307: 0.1127756739679798507056031594e+15,
! 308: 0.3123043114941213172572469442e+12,
! 309: 0.669998767298223967181402866e+9,
! 310: 0.1114636098462985378182402543e+7,
! 311: 0.1363063652328970604442810507e+4,
! 312: 0.1e+1
! 313: };
! 314:
! 315: /* pzero for x in [8,inf]
! 316: * Index 6548, 18.16 digits precision
! 317: */
! 318: static double GPFAR ppzero[] = {
! 319: 0.2277909019730468430227002627e+5,
! 320: 0.4134538663958076579678016384e+5,
! 321: 0.2117052338086494432193395727e+5,
! 322: 0.348064864432492703474453111e+4,
! 323: 0.15376201909008354295771715e+3,
! 324: 0.889615484242104552360748e+0
! 325: };
! 326:
! 327: static double GPFAR qpzero[] = {
! 328: 0.2277909019730468431768423768e+5,
! 329: 0.4137041249551041663989198384e+5,
! 330: 0.2121535056188011573042256764e+5,
! 331: 0.350287351382356082073561423e+4,
! 332: 0.15711159858080893649068482e+3,
! 333: 0.1e+1
! 334: };
! 335:
! 336: /* qzero for x in [8,inf]
! 337: * Index 6948, 18.33 digits precision
! 338: */
! 339: static double GPFAR pqzero[] = {
! 340: -0.8922660020080009409846916e+2,
! 341: -0.18591953644342993800252169e+3,
! 342: -0.11183429920482737611262123e+3,
! 343: -0.2230026166621419847169915e+2,
! 344: -0.124410267458356384591379e+1,
! 345: -0.8803330304868075181663e-2,
! 346: };
! 347:
! 348: static double GPFAR qqzero[] = {
! 349: 0.571050241285120619052476459e+4,
! 350: 0.1195113154343461364695265329e+5,
! 351: 0.726427801692110188369134506e+4,
! 352: 0.148872312322837565816134698e+4,
! 353: 0.9059376959499312585881878e+2,
! 354: 0.1e+1
! 355: };
! 356:
! 357:
! 358: /* yzero for x in [0,8]
! 359: * Index 6245, 18.78 digits precision
! 360: */
! 361: static double GPFAR pyzero[] = {
! 362: -0.2750286678629109583701933175e+20,
! 363: 0.6587473275719554925999402049e+20,
! 364: -0.5247065581112764941297350814e+19,
! 365: 0.1375624316399344078571335453e+18,
! 366: -0.1648605817185729473122082537e+16,
! 367: 0.1025520859686394284509167421e+14,
! 368: -0.3436371222979040378171030138e+11,
! 369: 0.5915213465686889654273830069e+8,
! 370: -0.4137035497933148554125235152e+5
! 371: };
! 372:
! 373: static double GPFAR qyzero[] = {
! 374: 0.3726458838986165881989980739e+21,
! 375: 0.4192417043410839973904769661e+19,
! 376: 0.2392883043499781857439356652e+17,
! 377: 0.9162038034075185262489147968e+14,
! 378: 0.2613065755041081249568482092e+12,
! 379: 0.5795122640700729537380087915e+9,
! 380: 0.1001702641288906265666651753e+7,
! 381: 0.1282452772478993804176329391e+4,
! 382: 0.1e+1
! 383: };
! 384:
! 385:
! 386: /* jone for x in [0,8]
! 387: * Index 6050, 20.98 digits precision
! 388: */
! 389: static double GPFAR pjone[] = {
! 390: 0.581199354001606143928050809e+21,
! 391: -0.6672106568924916298020941484e+20,
! 392: 0.2316433580634002297931815435e+19,
! 393: -0.3588817569910106050743641413e+17,
! 394: 0.2908795263834775409737601689e+15,
! 395: -0.1322983480332126453125473247e+13,
! 396: 0.3413234182301700539091292655e+10,
! 397: -0.4695753530642995859767162166e+7,
! 398: 0.270112271089232341485679099e+4
! 399: };
! 400:
! 401: static double GPFAR qjone[] = {
! 402: 0.11623987080032122878585294e+22,
! 403: 0.1185770712190320999837113348e+20,
! 404: 0.6092061398917521746105196863e+17,
! 405: 0.2081661221307607351240184229e+15,
! 406: 0.5243710262167649715406728642e+12,
! 407: 0.1013863514358673989967045588e+10,
! 408: 0.1501793594998585505921097578e+7,
! 409: 0.1606931573481487801970916749e+4,
! 410: 0.1e+1
! 411: };
! 412:
! 413:
! 414: /* pone for x in [8,inf]
! 415: * Index 6749, 18.11 digits precision
! 416: */
! 417: static double GPFAR ppone[] = {
! 418: 0.352246649133679798341724373e+5,
! 419: 0.62758845247161281269005675e+5,
! 420: 0.313539631109159574238669888e+5,
! 421: 0.49854832060594338434500455e+4,
! 422: 0.2111529182853962382105718e+3,
! 423: 0.12571716929145341558495e+1
! 424: };
! 425:
! 426: static double GPFAR qpone[] = {
! 427: 0.352246649133679798068390431e+5,
! 428: 0.626943469593560511888833731e+5,
! 429: 0.312404063819041039923015703e+5,
! 430: 0.4930396490181088979386097e+4,
! 431: 0.2030775189134759322293574e+3,
! 432: 0.1e+1
! 433: };
! 434:
! 435: /* qone for x in [8,inf]
! 436: * Index 7149, 18.28 digits precision
! 437: */
! 438: static double GPFAR pqone[] = {
! 439: 0.3511751914303552822533318e+3,
! 440: 0.7210391804904475039280863e+3,
! 441: 0.4259873011654442389886993e+3,
! 442: 0.831898957673850827325226e+2,
! 443: 0.45681716295512267064405e+1,
! 444: 0.3532840052740123642735e-1
! 445: };
! 446:
! 447: static double GPFAR qqone[] = {
! 448: 0.74917374171809127714519505e+4,
! 449: 0.154141773392650970499848051e+5,
! 450: 0.91522317015169922705904727e+4,
! 451: 0.18111867005523513506724158e+4,
! 452: 0.1038187585462133728776636e+3,
! 453: 0.1e+1
! 454: };
! 455:
! 456:
! 457: /* yone for x in [0,8]
! 458: * Index 6444, 18.24 digits precision
! 459: */
! 460: static double GPFAR pyone[] = {
! 461: -0.2923821961532962543101048748e+20,
! 462: 0.7748520682186839645088094202e+19,
! 463: -0.3441048063084114446185461344e+18,
! 464: 0.5915160760490070618496315281e+16,
! 465: -0.4863316942567175074828129117e+14,
! 466: 0.2049696673745662182619800495e+12,
! 467: -0.4289471968855248801821819588e+9,
! 468: 0.3556924009830526056691325215e+6
! 469: };
! 470:
! 471: static double GPFAR qyone[] = {
! 472: 0.1491311511302920350174081355e+21,
! 473: 0.1818662841706134986885065935e+19,
! 474: 0.113163938269888452690508283e+17,
! 475: 0.4755173588888137713092774006e+14,
! 476: 0.1500221699156708987166369115e+12,
! 477: 0.3716660798621930285596927703e+9,
! 478: 0.726914730719888456980191315e+6,
! 479: 0.10726961437789255233221267e+4,
! 480: 0.1e+1
! 481: };
! 482:
! 483: #endif /* (ATARI || MTOS) && __PUREC__ */
! 484:
! 485: void f_real()
! 486: {
! 487: struct value a;
! 488: push( Gcomplex(&a,real(pop(&a)), 0.0) );
! 489: }
! 490:
! 491: void f_imag()
! 492: {
! 493: struct value a;
! 494: push( Gcomplex(&a,imag(pop(&a)), 0.0) );
! 495: }
! 496:
! 497:
! 498: /* ang2rad is 1 if we are in radians, or pi/180 if we are in degrees */
! 499:
! 500: void f_arg()
! 501: {
! 502: struct value a;
! 503: push( Gcomplex(&a,angle(pop(&a))/ang2rad, 0.0) );
! 504: }
! 505:
! 506: void f_conjg()
! 507: {
! 508: struct value a;
! 509: (void) pop(&a);
! 510: push( Gcomplex(&a,real(&a),-imag(&a) ));
! 511: }
! 512:
! 513: /* ang2rad is 1 if we are in radians, or pi/180 if we are in degrees */
! 514:
! 515: void f_sin()
! 516: {
! 517: struct value a;
! 518: (void) pop(&a);
! 519: push( Gcomplex(&a,sin(ang2rad*real(&a))*cosh(ang2rad*imag(&a)), cos(ang2rad*real(&a))*sinh(ang2rad*imag(&a))) );
! 520: }
! 521:
! 522: void f_cos()
! 523: {
! 524: struct value a;
! 525: (void) pop(&a);
! 526: push( Gcomplex(&a,cos(ang2rad*real(&a))*cosh(ang2rad*imag(&a)), -sin(ang2rad*real(&a))*sinh(ang2rad*imag(&a))));
! 527: }
! 528:
! 529: void f_tan()
! 530: {
! 531: struct value a;
! 532: register double den;
! 533: (void) pop(&a);
! 534: if (imag(&a) == 0.0)
! 535: push( Gcomplex(&a,tan(ang2rad*real(&a)),0.0) );
! 536: else {
! 537: den = cos(2*ang2rad*real(&a))+cosh(2*ang2rad*imag(&a));
! 538: if (den == 0.0) {
! 539: undefined = TRUE;
! 540: push( &a );
! 541: }
! 542: else
! 543: push( Gcomplex(&a,sin(2*ang2rad*real(&a))/den, sinh(2*ang2rad*imag(&a))/den) );
! 544: }
! 545: }
! 546:
! 547: void f_asin()
! 548: {
! 549: struct value a;
! 550: register double alpha, beta, x, y;
! 551: (void) pop(&a);
! 552: x = real(&a); y = imag(&a);
! 553: if (y == 0.0 && fabs(x) <= 1.0) {
! 554: push( Gcomplex(&a,asin(x)/ang2rad,0.0) );
! 555: } else if (x == 0.0) {
! 556: push( Gcomplex(&a, 0.0, -log(-y+sqrt(y*y+1))/ang2rad) );
! 557: } else {
! 558: beta = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
! 559: if (beta > 1) beta = 1; /* Avoid rounding error problems */
! 560: alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
! 561: push( Gcomplex(&a,asin(beta)/ang2rad, -log(alpha + sqrt(alpha*alpha-1))/ang2rad) );
! 562: }
! 563: }
! 564:
! 565: void f_acos()
! 566: {
! 567: struct value a;
! 568: register double x, y;
! 569: (void) pop(&a);
! 570: x = real(&a); y = imag(&a);
! 571: if (y == 0.0 && fabs(x) <= 1.0) {
! 572: /* real result */
! 573: push( Gcomplex(&a,acos(x)/ang2rad,0.0) );
! 574: } else {
! 575: double alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
! 576: double beta = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
! 577: if (beta > 1)
! 578: beta = 1; /* Avoid rounding error problems */
! 579: else if (beta < -1)
! 580: beta = -1;
! 581: push( Gcomplex(&a,acos(beta)/ang2rad, log(alpha + sqrt(alpha*alpha-1))/ang2rad));
! 582: }
! 583: }
! 584:
! 585: void f_atan()
! 586: {
! 587: struct value a;
! 588: register double x, y, u, v, w, z;
! 589: (void) pop(&a);
! 590: x = real(&a); y = imag(&a);
! 591: if (y == 0.0)
! 592: push( Gcomplex(&a,atan(x)/ang2rad, 0.0) );
! 593: else if (x == 0.0 && fabs(y) >= 1.0) {
! 594: undefined = TRUE;
! 595: push(Gcomplex(&a,0.0, 0.0));
! 596: } else {
! 597: if (x >= 0) {
! 598: u = x;
! 599: v = y;
! 600: } else {
! 601: u = -x;
! 602: v = -y;
! 603: }
! 604:
! 605: z = atan(2*u/(1-u*u-v*v));
! 606: w = log((u*u+(v+1)*(v+1))/(u*u+(v-1)*(v-1)))/4;
! 607: if (z < 0)
! 608: z = z + 2*PI_ON_TWO;
! 609: if (x < 0) {
! 610: z = -z;
! 611: w = -w;
! 612: }
! 613: push( Gcomplex(&a,0.5*z/ang2rad, w) );
! 614: }
! 615: }
! 616:
! 617: /* real parts only */
! 618: void f_atan2()
! 619: {
! 620: struct value a;
! 621: double x;
! 622: double y;
! 623:
! 624: x = real(pop(&a));
! 625: y = real(pop(&a));
! 626:
! 627: if (x == 0.0 && y == 0.0) {
! 628: undefined = TRUE;
! 629: push(Ginteger(&a,0));
! 630: }
! 631: push(Gcomplex(&a,atan2(y,x)/ang2rad,0.0));
! 632: }
! 633:
! 634:
! 635: void f_sinh()
! 636: {
! 637: struct value a;
! 638: (void) pop(&a);
! 639: push( Gcomplex(&a,sinh(real(&a))*cos(imag(&a)), cosh(real(&a))*sin(imag(&a))) );
! 640: }
! 641:
! 642: void f_cosh()
! 643: {
! 644: struct value a;
! 645: (void) pop(&a);
! 646: push( Gcomplex(&a,cosh(real(&a))*cos(imag(&a)), sinh(real(&a))*sin(imag(&a))) );
! 647: }
! 648:
! 649: void f_tanh()
! 650: {
! 651: struct value a;
! 652: register double den;
! 653: (void) pop(&a);
! 654: den = cosh(2*real(&a)) + cos(2*imag(&a));
! 655: push( Gcomplex(&a,sinh(2*real(&a))/den, sin(2*imag(&a))/den) );
! 656: }
! 657:
! 658: void f_asinh()
! 659: {
! 660: struct value a; /* asinh(z) = -I*asin(I*z) */
! 661: register double alpha, beta, x, y;
! 662: (void) pop(&a);
! 663: x = -imag(&a); y = real(&a);
! 664: if (y == 0.0 && fabs(x) <= 1.0) {
! 665: push( Gcomplex(&a, 0.0, -asin(x)/ang2rad) );
! 666: } else if (y == 0.0) {
! 667: push( Gcomplex(&a, 0.0, 0.0) );
! 668: undefined = TRUE;
! 669: } else if (x == 0.0) {
! 670: push( Gcomplex(&a, log(y+sqrt(y*y+1))/ang2rad, 0.0) );
! 671: } else {
! 672: beta = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
! 673: alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
! 674: push( Gcomplex(&a, log(alpha + sqrt(alpha*alpha-1))/ang2rad, -asin(beta)/ang2rad) );
! 675: }
! 676: }
! 677:
! 678: void f_acosh()
! 679: {
! 680: struct value a;
! 681: register double alpha, beta, x, y; /* acosh(z) = I*acos(z) */
! 682: (void) pop(&a);
! 683: x = real(&a); y = imag(&a);
! 684: if (y == 0.0 && fabs(x) <= 1.0) {
! 685: push( Gcomplex(&a, 0.0, acos(x)/ang2rad) );
! 686: } else if (y == 0) {
! 687: push( Gcomplex(&a, log(x+sqrt(x*x-1))/ang2rad, 0.0) );
! 688: } else {
! 689: alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
! 690: beta = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
! 691: push( Gcomplex(&a, log(alpha + sqrt(alpha*alpha-1))/ang2rad, acos(beta)/ang2rad));
! 692: }
! 693: }
! 694:
! 695: void f_atanh()
! 696: {
! 697: struct value a;
! 698: register double x, y, u, v, w, z; /* atanh(z) = -I*atan(I*z) */
! 699: (void) pop(&a);
! 700: x = -imag(&a); y = real(&a);
! 701: if (y == 0.0)
! 702: push( Gcomplex(&a, 0.0, -atan(x)/ang2rad) );
! 703: else if (x == 0.0 && fabs(y) >= 1.0) {
! 704: undefined = TRUE;
! 705: push(Gcomplex(&a,0.0, 0.0));
! 706: } else {
! 707: if (x >= 0) {
! 708: u = x;
! 709: v = y;
! 710: } else {
! 711: u = -x;
! 712: v = -y;
! 713: }
! 714:
! 715: z = atan(2*u/(1-u*u-v*v));
! 716: w = log((u*u+(v+1)*(v+1))/(u*u+(v-1)*(v-1)))/4;
! 717: if (z < 0)
! 718: z = z + 2*PI_ON_TWO;
! 719: if (x < 0) {
! 720: z = -z;
! 721: w = -w;
! 722: }
! 723: push( Gcomplex(&a, w, -0.5*z/ang2rad) );
! 724: }
! 725: }
! 726:
! 727: void f_int()
! 728: {
! 729: struct value a;
! 730: push( Ginteger(&a,(int)real(pop(&a))) );
! 731: }
! 732:
! 733:
! 734: void f_abs()
! 735: {
! 736: struct value a;
! 737: (void) pop(&a);
! 738: switch (a.type) {
! 739: case INTGR:
! 740: push( Ginteger(&a,abs(a.v.int_val)) );
! 741: break;
! 742: case CMPLX:
! 743: push( Gcomplex(&a,magnitude(&a), 0.0) );
! 744: }
! 745: }
! 746:
! 747: void f_sgn()
! 748: {
! 749: struct value a;
! 750: (void) pop(&a);
! 751: switch(a.type) {
! 752: case INTGR:
! 753: push( Ginteger(&a,(a.v.int_val > 0) ? 1 :
! 754: (a.v.int_val < 0) ? -1 : 0) );
! 755: break;
! 756: case CMPLX:
! 757: push( Ginteger(&a,(a.v.cmplx_val.real > 0.0) ? 1 :
! 758: (a.v.cmplx_val.real < 0.0) ? -1 : 0) );
! 759: break;
! 760: }
! 761: }
! 762:
! 763:
! 764: void f_sqrt()
! 765: {
! 766: struct value a;
! 767: register double mag;
! 768: (void) pop(&a);
! 769: mag = sqrt(magnitude(&a));
! 770: if (imag(&a) == 0.0) {
! 771: if (real(&a) < 0.0)
! 772: push( Gcomplex(&a,0.0,mag) );
! 773: else
! 774: push( Gcomplex(&a,mag, 0.0) );
! 775: } else {
! 776: /* -pi < ang < pi, so real(sqrt(z)) >= 0 */
! 777: double ang = angle(&a) / 2.0;
! 778: push( Gcomplex(&a,mag*cos(ang), mag*sin(ang)) );
! 779: }
! 780: }
! 781:
! 782:
! 783: void f_exp()
! 784: {
! 785: struct value a;
! 786: register double mag, ang;
! 787: (void) pop(&a);
! 788: mag = gp_exp(real(&a));
! 789: ang = imag(&a);
! 790: push( Gcomplex(&a,mag*cos(ang), mag*sin(ang)) );
! 791: }
! 792:
! 793:
! 794: void f_log10()
! 795: {
! 796: struct value a;
! 797: (void) pop(&a);
! 798: push( Gcomplex(&a,log(magnitude(&a))/M_LN10, angle(&a)/M_LN10) );
! 799: }
! 800:
! 801:
! 802: void f_log()
! 803: {
! 804: struct value a;
! 805: (void) pop(&a);
! 806: push( Gcomplex(&a,log(magnitude(&a)), angle(&a)) );
! 807: }
! 808:
! 809:
! 810: void f_floor()
! 811: {
! 812: struct value a;
! 813:
! 814: (void) pop(&a);
! 815: switch (a.type) {
! 816: case INTGR:
! 817: push( Ginteger(&a,(int)floor((double)a.v.int_val)));
! 818: break;
! 819: case CMPLX:
! 820: push( Ginteger(&a,(int)floor(a.v.cmplx_val.real)));
! 821: }
! 822: }
! 823:
! 824:
! 825: void f_ceil()
! 826: {
! 827: struct value a;
! 828:
! 829: (void) pop(&a);
! 830: switch (a.type) {
! 831: case INTGR:
! 832: push( Ginteger(&a,(int)ceil((double)a.v.int_val)));
! 833: break;
! 834: case CMPLX:
! 835: push( Ginteger(&a,(int)ceil(a.v.cmplx_val.real)));
! 836: }
! 837: }
! 838:
! 839: /* bessel function approximations */
! 840: static double jzero(x)
! 841: double x;
! 842: {
! 843: double p, q, x2;
! 844: int n;
! 845:
! 846: x2 = x * x;
! 847: p = pjzero[8];
! 848: q = qjzero[8];
! 849: for (n=7; n>=0; n--) {
! 850: p = p*x2 + pjzero[n];
! 851: q = q*x2 + qjzero[n];
! 852: }
! 853: return(p/q);
! 854: }
! 855:
! 856: static double pzero(x)
! 857: double x;
! 858: {
! 859: double p, q, z, z2;
! 860: int n;
! 861:
! 862: z = 8.0 / x;
! 863: z2 = z * z;
! 864: p = ppzero[5];
! 865: q = qpzero[5];
! 866: for (n=4; n>=0; n--) {
! 867: p = p*z2 + ppzero[n];
! 868: q = q*z2 + qpzero[n];
! 869: }
! 870: return(p/q);
! 871: }
! 872:
! 873: static double qzero(x)
! 874: double x;
! 875: {
! 876: double p, q, z, z2;
! 877: int n;
! 878:
! 879: z = 8.0 / x;
! 880: z2 = z * z;
! 881: p = pqzero[5];
! 882: q = qqzero[5];
! 883: for (n=4; n>=0; n--) {
! 884: p = p*z2 + pqzero[n];
! 885: q = q*z2 + qqzero[n];
! 886: }
! 887: return(p/q);
! 888: }
! 889:
! 890: static double yzero(x)
! 891: double x;
! 892: {
! 893: double p, q, x2;
! 894: int n;
! 895:
! 896: x2 = x * x;
! 897: p = pyzero[8];
! 898: q = qyzero[8];
! 899: for (n=7; n>=0; n--) {
! 900: p = p*x2 + pyzero[n];
! 901: q = q*x2 + qyzero[n];
! 902: }
! 903: return(p/q);
! 904: }
! 905:
! 906: static double rj0(x)
! 907: double x;
! 908: {
! 909: if ( x <= 0.0 )
! 910: x = -x;
! 911: if ( x < 8.0 )
! 912: return(jzero(x));
! 913: else
! 914: return( sqrt(TWO_ON_PI/x) *
! 915: (pzero(x)*cos(x-PI_ON_FOUR) - 8.0/x*qzero(x)*sin(x-PI_ON_FOUR)) );
! 916:
! 917: }
! 918:
! 919: static double ry0(x)
! 920: double x;
! 921: {
! 922: if ( x < 0.0 )
! 923: return(dzero/dzero); /* error */
! 924: if ( x < 8.0 )
! 925: return( yzero(x) + TWO_ON_PI*rj0(x)*log(x) );
! 926: else
! 927: return( sqrt(TWO_ON_PI/x) *
! 928: (pzero(x)*sin(x-PI_ON_FOUR) +
! 929: (8.0/x)*qzero(x)*cos(x-PI_ON_FOUR)) );
! 930:
! 931: }
! 932:
! 933:
! 934: static double jone(x)
! 935: double x;
! 936: {
! 937: double p, q, x2;
! 938: int n;
! 939:
! 940: x2 = x * x;
! 941: p = pjone[8];
! 942: q = qjone[8];
! 943: for (n=7; n>=0; n--) {
! 944: p = p*x2 + pjone[n];
! 945: q = q*x2 + qjone[n];
! 946: }
! 947: return(p/q);
! 948: }
! 949:
! 950: static double pone(x)
! 951: double x;
! 952: {
! 953: double p, q, z, z2;
! 954: int n;
! 955:
! 956: z = 8.0 / x;
! 957: z2 = z * z;
! 958: p = ppone[5];
! 959: q = qpone[5];
! 960: for (n=4; n>=0; n--) {
! 961: p = p*z2 + ppone[n];
! 962: q = q*z2 + qpone[n];
! 963: }
! 964: return(p/q);
! 965: }
! 966:
! 967: static double qone(x)
! 968: double x;
! 969: {
! 970: double p, q, z, z2;
! 971: int n;
! 972:
! 973: z = 8.0 / x;
! 974: z2 = z * z;
! 975: p = pqone[5];
! 976: q = qqone[5];
! 977: for (n=4; n>=0; n--) {
! 978: p = p*z2 + pqone[n];
! 979: q = q*z2 + qqone[n];
! 980: }
! 981: return(p/q);
! 982: }
! 983:
! 984: static double yone(x)
! 985: double x;
! 986: {
! 987: double p, q, x2;
! 988: int n;
! 989:
! 990: x2 = x * x;
! 991: p = 0.0;
! 992: q = qyone[8];
! 993: for (n=7; n>=0; n--) {
! 994: p = p*x2 + pyone[n];
! 995: q = q*x2 + qyone[n];
! 996: }
! 997: return(p/q);
! 998: }
! 999:
! 1000: static double rj1(x)
! 1001: double x;
! 1002: {
! 1003: double v,w;
! 1004: v = x;
! 1005: if ( x < 0.0 )
! 1006: x = -x;
! 1007: if ( x < 8.0 )
! 1008: return(v*jone(x));
! 1009: else {
! 1010: w = sqrt(TWO_ON_PI/x) *
! 1011: (pone(x)*cos(x-THREE_PI_ON_FOUR) -
! 1012: 8.0/x*qone(x)*sin(x-THREE_PI_ON_FOUR)) ;
! 1013: if (v < 0.0)
! 1014: w = -w;
! 1015: return( w );
! 1016: }
! 1017: }
! 1018:
! 1019: static double ry1(x)
! 1020: double x;
! 1021: {
! 1022: if ( x <= 0.0 )
! 1023: return(dzero/dzero); /* error */
! 1024: if ( x < 8.0 )
! 1025: return( x*yone(x) + TWO_ON_PI*(rj1(x)*log(x) - 1.0/x) );
! 1026: else
! 1027: return( sqrt(TWO_ON_PI/x) *
! 1028: (pone(x)*sin(x-THREE_PI_ON_FOUR) +
! 1029: (8.0/x)*qone(x)*cos(x-THREE_PI_ON_FOUR)) );
! 1030: }
! 1031:
! 1032:
! 1033: void f_besj0()
! 1034: {
! 1035: struct value a;
! 1036: (void) pop(&a);
! 1037: if (fabs(imag(&a)) > zero)
! 1038: int_error("can only do bessel functions of reals",NO_CARET);
! 1039: push( Gcomplex(&a,rj0(real(&a)),0.0) );
! 1040: }
! 1041:
! 1042:
! 1043: void f_besj1()
! 1044: {
! 1045: struct value a;
! 1046: (void) pop(&a);
! 1047: if (fabs(imag(&a)) > zero)
! 1048: int_error("can only do bessel functions of reals",NO_CARET);
! 1049: push( Gcomplex(&a,rj1(real(&a)),0.0) );
! 1050: }
! 1051:
! 1052:
! 1053: void f_besy0()
! 1054: {
! 1055: struct value a;
! 1056: (void) pop(&a);
! 1057: if (fabs(imag(&a)) > zero)
! 1058: int_error("can only do bessel functions of reals",NO_CARET);
! 1059: if (real(&a) > 0.0)
! 1060: push( Gcomplex(&a,ry0(real(&a)),0.0) );
! 1061: else {
! 1062: push( Gcomplex(&a,0.0,0.0) );
! 1063: undefined = TRUE ;
! 1064: }
! 1065: }
! 1066:
! 1067:
! 1068: void f_besy1()
! 1069: {
! 1070: struct value a;
! 1071: (void) pop(&a);
! 1072: if (fabs(imag(&a)) > zero)
! 1073: int_error("can only do bessel functions of reals",NO_CARET);
! 1074: if (real(&a) > 0.0)
! 1075: push( Gcomplex(&a,ry1(real(&a)),0.0) );
! 1076: else {
! 1077: push( Gcomplex(&a,0.0,0.0) );
! 1078: undefined = TRUE ;
! 1079: }
! 1080: }
! 1081:
! 1082:
! 1083: /* functions for accessing fields from tm structure, for time series
! 1084: * they are all the same, so define a macro
! 1085: */
! 1086:
! 1087: #define TIMEFUNC(name, field) \
! 1088: void name() { \
! 1089: struct value a; struct tm tm; \
! 1090: (void) pop(&a); ggmtime(&tm, real(&a)); \
! 1091: push(Gcomplex(&a, (double)tm.field, 0.0)); \
! 1092: }
! 1093:
! 1094: TIMEFUNC(f_tmsec, tm_sec)
! 1095: TIMEFUNC(f_tmmin, tm_min)
! 1096: TIMEFUNC(f_tmhour, tm_hour)
! 1097: TIMEFUNC(f_tmmday, tm_mday)
! 1098: TIMEFUNC(f_tmmon, tm_mon)
! 1099: TIMEFUNC(f_tmyear, tm_year)
! 1100: TIMEFUNC(f_tmwday, tm_wday)
! 1101: TIMEFUNC(f_tmyday, tm_yday)
! 1102:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>