[BACK]Return to standard.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/standard.c, Revision 1.1.1.2

1.1       maekawa     1: #ifndef lint
1.1.1.2 ! maekawa     2: static char *RCSid = "$Id: standard.c,v 1.5 1998/12/07 22:09:07 lhecking Exp $";
1.1       maekawa     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>