[BACK]Return to bfaux.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / builtin

Annotation of OpenXM_contrib2/asir2000/builtin/bfaux.c, Revision 1.10

1.10    ! noro        1: /* $OpenXM: OpenXM_contrib2/asir2000/builtin/bfaux.c,v 1.9 2015/08/17 05:18:36 noro Exp $ */
1.1       noro        2: #include "ca.h"
                      3: #include "parse.h"
                      4:
1.4       noro        5: void Peval(), Psetprec(), Psetbprec(), Ptodouble(), Psetround();
1.8       noro        6: void Pmpfr_ai();
1.9       noro        7: void Pmpfr_eint(), Pmpfr_erf(), Pmpfr_erfc(), Pmpfr_li2();
1.8       noro        8: void Pmpfr_zeta();
                      9: void Pmpfr_j0(), Pmpfr_j1();
                     10: void Pmpfr_y0(), Pmpfr_y1();
                     11: void Pmpfr_gamma(), Pmpfr_lngamma(), Pmpfr_digamma();
                     12: void Pmpfr_floor(), Pmpfr_round(), Pmpfr_ceil();
1.1       noro       13:
                     14: struct ftab bf_tab[] = {
                     15:        {"eval",Peval,-2},
                     16:        {"setprec",Psetprec,-1},
1.3       noro       17:        {"setbprec",Psetbprec,-1},
1.4       noro       18:        {"setround",Psetround,-1},
1.1       noro       19:        {"todouble",Ptodouble,1},
1.8       noro       20:        {"mpfr_ai",Pmpfr_ai,-2},
                     21:        {"mpfr_zeta",Pmpfr_zeta,-2},
                     22:        {"mpfr_j0",Pmpfr_j0,-2},
                     23:        {"mpfr_j1",Pmpfr_j1,-2},
                     24:        {"mpfr_y0",Pmpfr_y0,-2},
                     25:        {"mpfr_y1",Pmpfr_y1,-2},
                     26:        {"mpfr_eint",Pmpfr_eint,-2},
                     27:        {"mpfr_erf",Pmpfr_erf,-2},
1.9       noro       28:        {"mpfr_erfc",Pmpfr_erfc,-2},
1.8       noro       29:        {"mpfr_li2",Pmpfr_li2,-2},
1.5       noro       30:        {"mpfr_gamma",Pmpfr_gamma,-2},
1.8       noro       31:        {"mpfr_lngamma",Pmpfr_gamma,-2},
                     32:        {"mpfr_digamma",Pmpfr_gamma,-2},
                     33:        {"mpfr_floor",Pmpfr_floor,-2},
                     34:        {"mpfr_ceil",Pmpfr_ceil,-2},
                     35:        {"mpfr_round",Pmpfr_round,-2},
1.1       noro       36:        {0,0,0},
                     37: };
                     38:
1.4       noro       39: int mpfr_roundmode = MPFR_RNDN;
                     40:
1.1       noro       41: void Ptodouble(NODE arg,Num *rp)
                     42: {
                     43:        double r,i;
                     44:        Real real,imag;
                     45:        Num num;
                     46:
                     47:        asir_assert(ARG0(arg),O_N,"todouble");
                     48:        num = (Num)ARG0(arg);
                     49:        if ( !num ) {
                     50:                *rp = 0;
                     51:                return;
                     52:        }
                     53:        switch ( NID(num) ) {
                     54:                case N_R: case N_Q: case N_B:
                     55:                        r = ToReal(num);
                     56:                        MKReal(r,real);
                     57:                        *rp = (Num)real;
                     58:                        break;
                     59:                case N_C:
                     60:                        r = ToReal(((C)num)->r);
                     61:                        i = ToReal(((C)num)->i);
                     62:                        MKReal(r,real);
                     63:                        MKReal(i,imag);
                     64:                        reimtocplx((Num)real,(Num)imag,rp);
                     65:                        break;
                     66:                default:
                     67:                        *rp = num;
                     68:                        break;
                     69:        }
                     70: }
                     71:
1.4       noro       72: void Peval(NODE arg,Obj *rp)
1.1       noro       73: {
                     74:   int prec;
                     75:
                     76:        asir_assert(ARG0(arg),O_R,"eval");
                     77:   if ( argc(arg) == 2 ) {
1.3       noro       78:          prec = QTOS((Q)ARG1(arg))*3.32193;
1.1       noro       79:     if ( prec < MPFR_PREC_MIN ) prec = MPFR_PREC_MIN;
                     80:     else if ( prec > MPFR_PREC_MAX ) prec = MPFR_PREC_MAX;
                     81:   } else
                     82:     prec = 0;
1.2       noro       83:        evalr(CO,(Obj)ARG0(arg),prec,rp);
1.1       noro       84: }
                     85:
1.3       noro       86: /* set/get decimal precision */
1.1       noro       87:
                     88: void Psetprec(NODE arg,Obj *rp)
                     89: {
                     90:        int p;
                     91:        Q q;
1.3       noro       92:        int prec,dprec;
                     93:
                     94:   prec = mpfr_get_default_prec();
                     95:   /* decimal precision */
                     96:   dprec = prec*0.30103;
                     97:   STOQ(dprec,q); *rp = (Obj)q;
                     98:        if ( arg ) {
                     99:                asir_assert(ARG0(arg),O_N,"setprec");
                    100:                prec = QTOS((Q)ARG0(arg))*3.32193;
                    101:                if ( p > 0 )
                    102:                        prec = p;
                    103:        }
                    104:   if ( prec < MPFR_PREC_MIN ) prec = MPFR_PREC_MIN;
                    105:   else if ( prec > MPFR_PREC_MAX ) prec = MPFR_PREC_MAX;
                    106:        mpfr_set_default_prec(prec);
                    107: }
1.1       noro      108:
1.3       noro      109: /* set/get bit precision */
1.1       noro      110:
1.3       noro      111: void Psetbprec(NODE arg,Obj *rp)
                    112: {
                    113:        int p;
                    114:        Q q;
                    115:        int prec;
                    116:
                    117:   prec = mpfr_get_default_prec();
                    118:   STOQ(prec,q); *rp = (Obj)q;
1.1       noro      119:        if ( arg ) {
1.3       noro      120:                asir_assert(ARG0(arg),O_N,"setbprec");
                    121:                prec = QTOS((Q)ARG0(arg));
1.1       noro      122:                if ( p > 0 )
                    123:                        prec = p;
                    124:        }
                    125:   if ( prec < MPFR_PREC_MIN ) prec = MPFR_PREC_MIN;
                    126:   else if ( prec > MPFR_PREC_MAX ) prec = MPFR_PREC_MAX;
                    127:        mpfr_set_default_prec(prec);
                    128: }
                    129:
1.4       noro      130: void Psetround(NODE arg,Q *rp)
                    131: {
                    132:   int round;
                    133:
                    134:   STOQ(mpfr_roundmode,*rp);
                    135:   if ( arg ) {
                    136:                asir_assert(ARG0(arg),O_N,"setround");
                    137:     round = QTOS((Q)ARG0(arg));
                    138:     switch ( round ) {
                    139:     case 0:
                    140:       mpfr_roundmode = MPFR_RNDN;
                    141:       break;
                    142:     case 1:
                    143:       mpfr_roundmode = MPFR_RNDZ;
                    144:       break;
                    145:     case 2:
                    146:       mpfr_roundmode = MPFR_RNDU;
                    147:       break;
                    148:     case 3:
                    149:       mpfr_roundmode = MPFR_RNDD;
                    150:       break;
                    151:     case 4:
                    152:       mpfr_roundmode = MPFR_RNDA;
                    153:       break;
                    154:     case 5:
                    155:       mpfr_roundmode = MPFR_RNDF;
                    156:       break;
                    157:     case 6:
                    158:       mpfr_roundmode = MPFR_RNDNA;
                    159:       break;
                    160:     default:
                    161:       error("setround : invalid rounding mode");
                    162:       break;
                    163:     }
                    164:   }
                    165: }
                    166:
1.1       noro      167: Num tobf(Num a,int prec);
                    168:
                    169: void mp_pi(NODE arg,BF *rp)
                    170: {
1.10    ! noro      171:   int prec;
1.1       noro      172:        BF r;
                    173:
                    174:        prec = arg ? QTOS((Q)ARG0(arg)) : 0;
                    175:        NEWBF(r);
                    176:        prec ? mpfr_init2(r->body,prec) : mpfr_init(r->body);
1.4       noro      177:        mpfr_const_pi(r->body,mpfr_roundmode);
1.10    ! noro      178:   if ( !cmpbf((Num)r,0) ) r = 0;
        !           179:   *rp = r;
1.1       noro      180: }
                    181:
                    182: void mp_e(NODE arg,BF *rp)
                    183: {
1.10    ! noro      184:   int prec;
1.1       noro      185:        mpfr_t one;
                    186:        BF r;
                    187:
                    188:        prec = arg ? QTOS((Q)ARG0(arg)) : 0;
                    189:        NEWBF(r);
                    190:        prec ? mpfr_init2(r->body,prec) : mpfr_init(r->body);
                    191:        mpfr_init(one);
1.4       noro      192:        mpfr_set_ui(one,1,mpfr_roundmode);
                    193:        mpfr_exp(r->body,one,mpfr_roundmode);
1.10    ! noro      194:   if ( !cmpbf((Num)r,0) ) r = 0;
        !           195:   *rp = r;
1.1       noro      196: }
                    197:
1.10    ! noro      198: void mpfr_or_mpc(NODE arg,int (*mpfr_f)(),int (*mpc_f)(),Num *rp)
1.1       noro      199: {
                    200:        Num a;
1.10    ! noro      201:   int prec;
        !           202:        BF r,re,im;
        !           203:   C c;
        !           204:   mpc_t mpc,a1;
1.1       noro      205:
1.10    ! noro      206:        prec = NEXT(arg) ? QTOS((Q)ARG1(arg)) : mpfr_get_default_prec();
1.1       noro      207:        a = tobf(ARG0(arg),prec);
1.10    ! noro      208:   if ( a && NID(a)==N_C ) {
        !           209:     mpc_init2(mpc,prec); mpc_init2(a1,prec);
        !           210:     re = (BF)((C)a)->r; im = (BF)((C)a)->i;
        !           211:     mpc_set_fr_fr(a1,re->body,im->body,mpfr_roundmode);
        !           212:     (*mpc_f)(mpc,a1,mpfr_roundmode);
        !           213:     MPFRTOBF(mpc_realref(mpc),re);
        !           214:     MPFRTOBF(mpc_imagref(mpc),im);
        !           215:     if ( !cmpbf((Num)re,0) ) re = 0;
        !           216:     if ( !cmpbf((Num)im,0) ) im = 0;
        !           217:     if ( !im )
        !           218:       *rp = (Num)re;
        !           219:     else {
        !           220:       NEWC(c); c->r = (Num)re; c->i = (Num)im;
        !           221:       *rp = (Num)c;
        !           222:     }
        !           223:   } else {
        !           224:          NEWBF(r);
        !           225:          mpfr_init2(r->body,prec);
        !           226:          (*mpfr_f)(r->body,((BF)a)->body,mpfr_roundmode);
        !           227:     if ( !cmpbf((Num)r,0) ) r = 0;
        !           228:     *rp = (Num)r;
        !           229:   }
1.1       noro      230: }
                    231:
1.10    ! noro      232: void mp_sin(NODE arg,Num *rp)
1.1       noro      233: {
1.10    ! noro      234:   mpfr_or_mpc(arg,mpfr_sin,mpc_sin,rp);
        !           235: }
1.1       noro      236:
1.10    ! noro      237: void mp_cos(NODE arg,Num *rp)
        !           238: {
        !           239:   mpfr_or_mpc(arg,mpfr_cos,mpc_cos,rp);
1.1       noro      240: }
                    241:
1.10    ! noro      242: void mp_tan(NODE arg,Num *rp)
1.1       noro      243: {
1.10    ! noro      244:   mpfr_or_mpc(arg,mpfr_tan,mpc_tan,rp);
        !           245: }
1.1       noro      246:
1.10    ! noro      247: void mp_asin(NODE arg,Num *rp)
        !           248: {
        !           249:   mpfr_or_mpc(arg,mpfr_asin,mpc_asin,rp);
1.1       noro      250: }
                    251:
1.10    ! noro      252: void mp_acos(NODE arg,Num *rp)
1.1       noro      253: {
1.10    ! noro      254:   mpfr_or_mpc(arg,mpfr_acos,mpc_acos,rp);
        !           255: }
1.1       noro      256:
1.10    ! noro      257: void mp_atan(NODE arg,Num *rp)
        !           258: {
        !           259:   mpfr_or_mpc(arg,mpfr_atan,mpc_atan,rp);
1.1       noro      260: }
                    261:
1.10    ! noro      262: void mp_sinh(NODE arg,Num *rp)
1.1       noro      263: {
1.10    ! noro      264:   mpfr_or_mpc(arg,mpfr_sinh,mpc_sinh,rp);
1.1       noro      265: }
                    266:
1.10    ! noro      267: void mp_cosh(NODE arg,Num *rp)
1.1       noro      268: {
1.10    ! noro      269:   mpfr_or_mpc(arg,mpfr_cosh,mpc_cosh,rp);
1.1       noro      270: }
                    271:
1.10    ! noro      272: void mp_tanh(NODE arg,Num *rp)
1.1       noro      273: {
1.10    ! noro      274:   mpfr_or_mpc(arg,mpfr_tanh,mpc_tanh,rp);
1.1       noro      275: }
                    276:
1.10    ! noro      277: void mp_asinh(NODE arg,Num *rp)
1.1       noro      278: {
1.10    ! noro      279:   mpfr_or_mpc(arg,mpfr_asinh,mpc_asinh,rp);
1.1       noro      280: }
                    281:
1.10    ! noro      282: void mp_acosh(NODE arg,Num *rp)
1.1       noro      283: {
1.10    ! noro      284:   mpfr_or_mpc(arg,mpfr_acosh,mpc_acosh,rp);
1.1       noro      285: }
                    286:
1.10    ! noro      287: void mp_atanh(NODE arg,Num *rp)
1.1       noro      288: {
1.10    ! noro      289:   mpfr_or_mpc(arg,mpfr_atanh,mpc_atanh,rp);
1.1       noro      290: }
                    291:
1.10    ! noro      292: void mp_exp(NODE arg,Num *rp)
1.1       noro      293: {
1.10    ! noro      294:   mpfr_or_mpc(arg,mpfr_exp,mpc_exp,rp);
1.1       noro      295: }
                    296:
1.10    ! noro      297: void mp_log(NODE arg,Num *rp)
1.1       noro      298: {
1.10    ! noro      299:   mpfr_or_mpc(arg,mpfr_log,mpc_log,rp);
1.1       noro      300: }
                    301:
1.10    ! noro      302: void mp_pow(NODE arg,Num *rp)
1.1       noro      303: {
                    304:        Num a,e;
1.10    ! noro      305:   int prec;
        !           306:        BF r,re,im;
        !           307:   C c;
        !           308:   mpc_t mpc,a1,e1;
1.1       noro      309:
1.10    ! noro      310:        prec = NEXT(NEXT(arg)) ? QTOS((Q)ARG2(arg)) : mpfr_get_default_prec();
1.1       noro      311:        a = tobf(ARG0(arg),prec);
                    312:        e = tobf(ARG1(arg),prec);
1.10    ! noro      313:   if ( NID(a) == N_C || NID(e) == N_C || MPFR_SIGN(((BF)a)->body) < 0 ) {
        !           314:     mpc_init2(mpc,prec); mpc_init2(a1,prec); mpc_init2(e1,prec);
        !           315:     if ( NID(a) == N_C ) {
        !           316:       re = (BF)((C)a)->r; im = (BF)((C)a)->i;
        !           317:       mpc_set_fr_fr(a1,re->body,im->body,mpfr_roundmode);
        !           318:     } else {
        !           319:       re = (BF)a;
        !           320:       mpc_set_fr(a1,re->body,mpfr_roundmode);
        !           321:     }
        !           322:     if ( NID(e) == N_C ) {
        !           323:       re = (BF)((C)e)->r; im = (BF)((C)e)->i;
        !           324:       mpc_set_fr_fr(e1,re->body,im->body,mpfr_roundmode);
        !           325:     } else {
        !           326:       re = (BF)e;
        !           327:       mpc_set_fr(e1,re->body,mpfr_roundmode);
        !           328:     }
        !           329:     mpc_pow(mpc,a1,e1,mpfr_roundmode);
        !           330:     MPFRTOBF(mpc_realref(mpc),re);
        !           331:     MPFRTOBF(mpc_imagref(mpc),im);
        !           332:     if ( !cmpbf((Num)re,0) ) re = 0;
        !           333:     if ( !cmpbf((Num)im,0) ) im = 0;
        !           334:     if ( !im )
        !           335:       *rp = (Num)re;
        !           336:     else {
        !           337:       NEWC(c); c->r = (Num)re; c->i = (Num)im;
        !           338:       *rp = (Num)c;
        !           339:     }
        !           340:   } else {
        !           341:          NEWBF(r);
        !           342:          mpfr_init2(r->body,prec);
        !           343:          mpfr_pow(r->body,((BF)a)->body,((BF)e)->body,mpfr_roundmode);
        !           344:     *rp = (Num)r;
        !           345:   }
1.1       noro      346: }
1.5       noro      347:
1.8       noro      348: #define SETPREC \
                    349:  (prec)=NEXT(arg)?QTOS((Q)ARG1(arg)):0;\
                    350:  (prec)*=3.32193;\
                    351:  (a)=tobf(ARG0(arg),prec);\
                    352:  NEWBF(r);\
                    353:  prec ? mpfr_init2(r->body,prec) : mpfr_init(r->body);
                    354:
                    355:
1.5       noro      356: void Pmpfr_gamma(NODE arg,BF *rp)
                    357: {
                    358:        Num a;
                    359:   int prec;
                    360:        BF r;
                    361:
1.8       noro      362:   SETPREC
1.5       noro      363:        mpfr_gamma(r->body,((BF)a)->body,mpfr_roundmode);
                    364:   *rp = r;
                    365: }
1.6       takayama  366:
1.8       noro      367: void Pmpfr_lngamma(NODE arg,BF *rp)
                    368: {
                    369:        Num a;
                    370:   int prec;
                    371:        BF r;
                    372:
                    373:   SETPREC
                    374:        mpfr_lngamma(r->body,((BF)a)->body,mpfr_roundmode);
                    375:   *rp = r;
                    376: }
                    377:
                    378: void Pmpfr_digamma(NODE arg,BF *rp)
                    379: {
                    380:        Num a;
                    381:   int prec;
                    382:        BF r;
                    383:
                    384:   SETPREC
                    385:        mpfr_digamma(r->body,((BF)a)->body,mpfr_roundmode);
                    386:   *rp = r;
                    387: }
                    388:
                    389: void Pmpfr_zeta(NODE arg,BF *rp)
                    390: {
                    391:        Num a;
                    392:   int prec;
                    393:        BF r;
                    394:
                    395:   SETPREC
                    396:        mpfr_zeta(r->body,((BF)a)->body,mpfr_roundmode);
                    397:   *rp = r;
                    398: }
                    399:
                    400: void Pmpfr_eint(NODE arg,BF *rp)
                    401: {
                    402:        Num a;
                    403:   int prec;
                    404:        BF r;
                    405:
                    406:   SETPREC
                    407:        mpfr_eint(r->body,((BF)a)->body,mpfr_roundmode);
                    408:   *rp = r;
                    409: }
                    410:
                    411: void Pmpfr_erf(NODE arg,BF *rp)
                    412: {
                    413:        Num a;
                    414:   int prec;
                    415:        BF r;
                    416:
                    417:   SETPREC
                    418:        mpfr_erf(r->body,((BF)a)->body,mpfr_roundmode);
                    419:   *rp = r;
                    420: }
                    421:
1.9       noro      422: void Pmpfr_erfc(NODE arg,BF *rp)
                    423: {
                    424:        Num a;
                    425:   int prec;
                    426:        BF r;
                    427:
                    428:   SETPREC
                    429:        mpfr_erfc(r->body,((BF)a)->body,mpfr_roundmode);
                    430:   *rp = r;
                    431: }
                    432:
1.8       noro      433: void Pmpfr_j0(NODE arg,BF *rp)
                    434: {
                    435:        Num a;
                    436:   int prec;
                    437:        BF r;
                    438:
                    439:   SETPREC
                    440:        mpfr_j0(r->body,((BF)a)->body,mpfr_roundmode);
                    441:   *rp = r;
                    442: }
                    443:
                    444: void Pmpfr_j1(NODE arg,BF *rp)
                    445: {
                    446:        Num a;
                    447:   int prec;
                    448:        BF r;
                    449:
                    450:   SETPREC
                    451:        mpfr_j1(r->body,((BF)a)->body,mpfr_roundmode);
                    452:   *rp = r;
                    453: }
                    454:
                    455: void Pmpfr_y0(NODE arg,BF *rp)
                    456: {
                    457:        Num a;
                    458:   int prec;
                    459:        BF r;
                    460:
                    461:   SETPREC
                    462:        mpfr_y0(r->body,((BF)a)->body,mpfr_roundmode);
                    463:   *rp = r;
                    464: }
                    465:
                    466: void Pmpfr_y1(NODE arg,BF *rp)
                    467: {
                    468:        Num a;
                    469:   int prec;
                    470:        BF r;
                    471:
                    472:   SETPREC
                    473:        mpfr_y1(r->body,((BF)a)->body,mpfr_roundmode);
                    474:   *rp = r;
                    475: }
                    476:
                    477: void Pmpfr_li2(NODE arg,BF *rp)
                    478: {
                    479:        Num a;
                    480:   int prec;
                    481:        BF r;
                    482:
                    483:   SETPREC
                    484:        mpfr_li2(r->body,((BF)a)->body,mpfr_roundmode);
                    485:   *rp = r;
                    486: }
                    487:
                    488: void Pmpfr_ai(NODE arg,BF *rp)
                    489: {
                    490:        Num a;
                    491:   int prec;
                    492:        BF r;
                    493:
                    494:   SETPREC
                    495:        mpfr_ai(r->body,((BF)a)->body,mpfr_roundmode);
                    496:   *rp = r;
                    497: }
                    498:
1.7       takayama  499: void Pmpfr_floor(NODE arg,Q *rp)
1.6       takayama  500: {
                    501:        Num a;
                    502:   int prec;
                    503:        BF r;
1.7       takayama  504:        mpz_t t;
                    505:        GZ rz;
1.6       takayama  506:
1.8       noro      507:   SETPREC
1.6       takayama  508:        mpfr_floor(r->body,((BF)a)->body);
1.7       takayama  509:        mpz_init(t);
                    510:        mpfr_get_z(t,r->body,mpfr_roundmode);
                    511:        MPZTOGZ(t,rz);
                    512:        *rp = gztoz(rz);
                    513: }
                    514:
1.8       noro      515: void Pmpfr_ceil(NODE arg,Q *rp)
                    516: {
                    517:        Num a;
                    518:   int prec;
                    519:        BF r;
                    520:        mpz_t t;
                    521:        GZ rz;
                    522:
                    523:   SETPREC
                    524:        mpfr_ceil(r->body,((BF)a)->body);
                    525:        mpz_init(t);
                    526:        mpfr_get_z(t,r->body,mpfr_roundmode);
                    527:        MPZTOGZ(t,rz);
                    528:        *rp = gztoz(rz);
                    529: }
                    530:
1.7       takayama  531: void Pmpfr_round(NODE arg,Q *rp)
                    532: {
                    533:        Num a;
                    534:   int prec;
                    535:        BF r;
                    536:        mpz_t t;
                    537:        GZ rz;
                    538:
1.8       noro      539:   SETPREC
1.7       takayama  540:        mpfr_round(r->body,((BF)a)->body);
                    541:        mpz_init(t);
                    542:        mpfr_get_z(t,r->body,mpfr_roundmode);
                    543:        MPZTOGZ(t,rz);
                    544:        *rp = gztoz(rz);
1.6       takayama  545: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>