Annotation of OpenXM_contrib2/asir2018/builtin/bfaux.c, Revision 1.1
1.1 ! noro 1: /* $OpenXM$ */
! 2: #include "ca.h"
! 3: #include "parse.h"
! 4:
! 5: void Peval(), Psetprec(), Psetbprec(), Ptodouble(), Psetround();
! 6: void Pmpfr_ai();
! 7: void Pmpfr_eint(), Pmpfr_erf(), Pmpfr_erfc(), Pmpfr_li2();
! 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();
! 13: void Prk_ratmat();
! 14: void mp_sin(),mp_cos(),mp_tan(),mp_asin(),mp_acos(),mp_atan();
! 15: void mp_sinh(),mp_cosh(),mp_tanh(),mp_asinh(),mp_acosh(),mp_atanh();
! 16: void mp_exp(),mp_log(),mp_pow();
! 17: void mp_factorial(),mp_abs();
! 18:
! 19: struct ftab bf_tab[] = {
! 20: {"eval",Peval,-2},
! 21: {"setprec",Psetprec,-1},
! 22: {"setbprec",Psetbprec,-1},
! 23: {"setround",Psetround,-1},
! 24: {"todouble",Ptodouble,1},
! 25: {"mpfr_sin",mp_sin,-2},
! 26: {"mpfr_cos",mp_cos,-2},
! 27: {"mpfr_tan",mp_tan,-2},
! 28: {"mpfr_asin",mp_asin,-2},
! 29: {"mpfr_acos",mp_acos,-2},
! 30: {"mpfr_atan",mp_atan,-2},
! 31: {"mpfr_sinh",mp_sinh,-2},
! 32: {"mpfr_cosh",mp_cosh,-2},
! 33: {"mpfr_tanh",mp_tanh,-2},
! 34: {"mpfr_asinh",mp_asinh,-2},
! 35: {"mpfr_acosh",mp_acosh,-2},
! 36: {"mpfr_atanh",mp_atanh,-2},
! 37: {"mpfr_exp",mp_exp,-2},
! 38: {"mpfr_log",mp_log,-2},
! 39: {"mpfr_pow",mp_pow,-3},
! 40: {"mpfr_ai",Pmpfr_ai,-2},
! 41: {"mpfr_zeta",Pmpfr_zeta,-2},
! 42: {"mpfr_j0",Pmpfr_j0,-2},
! 43: {"mpfr_j1",Pmpfr_j1,-2},
! 44: {"mpfr_y0",Pmpfr_y0,-2},
! 45: {"mpfr_y1",Pmpfr_y1,-2},
! 46: {"mpfr_eint",Pmpfr_eint,-2},
! 47: {"mpfr_erf",Pmpfr_erf,-2},
! 48: {"mpfr_erfc",Pmpfr_erfc,-2},
! 49: {"mpfr_li2",Pmpfr_li2,-2},
! 50: {"mpfr_gamma",Pmpfr_gamma,-2},
! 51: {"mpfr_lngamma",Pmpfr_gamma,-2},
! 52: {"mpfr_digamma",Pmpfr_gamma,-2},
! 53: {"mpfr_floor",Pmpfr_floor,-2},
! 54: {"mpfr_ceil",Pmpfr_ceil,-2},
! 55: {"mpfr_round",Pmpfr_round,-2},
! 56: {"rk_ratmat",Prk_ratmat,7},
! 57: {0,0,0},
! 58: };
! 59:
! 60: int mpfr_roundmode = MPFR_RNDN;
! 61:
! 62: void todoublen(Num a,Num *rp)
! 63: {
! 64: double r,i;
! 65: Real real,imag;
! 66:
! 67: if ( !a ) {
! 68: *rp = 0;
! 69: return;
! 70: }
! 71: switch ( NID(a) ) {
! 72: case N_R: case N_Q: case N_B:
! 73: r = ToReal(a);
! 74: MKReal(r,real);
! 75: *rp = (Num)real;
! 76: break;
! 77: case N_C:
! 78: r = ToReal(((C)a)->r);
! 79: i = ToReal(((C)a)->i);
! 80: MKReal(r,real);
! 81: MKReal(i,imag);
! 82: reimtocplx((Num)real,(Num)imag,rp);
! 83: break;
! 84: default:
! 85: *rp = a;
! 86: break;
! 87: }
! 88: }
! 89:
! 90: void todoublep(P a,P *rp)
! 91: {
! 92: DCP dc,dcr,dcr0;
! 93:
! 94: if ( !a ) *rp = 0;
! 95: else if ( OID(a) == O_N ) todoublen((Num)a,(Num *)rp);
! 96: else {
! 97: for ( dcr0 = 0, dc = DC(a); dc; dc = NEXT(dc) ) {
! 98: NEXTDC(dcr0,dcr);
! 99: DEG(dcr) = DEG(dc);
! 100: todoublep(COEF(dc),&COEF(dcr));
! 101: }
! 102: NEXT(dcr) = 0;
! 103: MKP(VR(a),dcr0,*rp);
! 104: }
! 105: }
! 106:
! 107: void todoubler(R a,R *rp)
! 108: {
! 109: R b;
! 110:
! 111: if ( !a ) *rp = 0;
! 112: else if ( OID(a) <= O_P ) todoublep((P)a,(P *)rp);
! 113: else {
! 114: NEWR(b);
! 115: todoublep(a->nm,&b->nm);
! 116: todoublep(a->dn,&b->dn);
! 117: *rp = b;
! 118: }
! 119: }
! 120:
! 121: void todouble(Obj a,Obj *b)
! 122: {
! 123: Obj t;
! 124: LIST l;
! 125: V v;
! 126: int row,col,len;
! 127: VECT vect;
! 128: MAT mat;
! 129: int i,j;
! 130: NODE n0,n,nd;
! 131: MP m,mp,mp0;
! 132: DP d;
! 133:
! 134: if ( !a ) {
! 135: *b = 0;
! 136: return;
! 137: }
! 138: switch ( OID(a) ) {
! 139: case O_N:
! 140: todoublen((Num)a,(Num *)b);
! 141: break;
! 142: case O_P:
! 143: todoublep((P)a,(P *)b);
! 144: break;
! 145: case O_R:
! 146: todoubler((R)a,(R *)b);
! 147: break;
! 148: case O_LIST:
! 149: n0 = 0;
! 150: for ( nd = BDY((LIST)a); nd; nd = NEXT(nd) ) {
! 151: NEXTNODE(n0,n);
! 152: todouble((Obj)BDY(nd),(Obj *)&BDY(n));
! 153: }
! 154: if ( n0 )
! 155: NEXT(n) = 0;
! 156: MKLIST(l,n0);
! 157: *b = (Obj)l;
! 158: break;
! 159: case O_VECT:
! 160: len = ((VECT)a)->len;
! 161: MKVECT(vect,len);
! 162: for ( i = 0; i < len; i++ ) {
! 163: todouble((Obj)BDY((VECT)a)[i],(Obj *)&BDY(vect)[i]);
! 164: }
! 165: *b = (Obj)vect;
! 166: break;
! 167: case O_MAT:
! 168: row = ((MAT)a)->row;
! 169: col = ((MAT)a)->col;
! 170: MKMAT(mat,row,col);
! 171: for ( i = 0; i < row; i++ )
! 172: for ( j = 0; j < col; j++ ) {
! 173: todouble((Obj)BDY((MAT)a)[i][j],(Obj *)&BDY(mat)[i][j]);
! 174: }
! 175: *b = (Obj)mat;
! 176: break;
! 177: case O_DP:
! 178: mp0 = 0;
! 179: for ( m = BDY((DP)a); m; m = NEXT(m) ) {
! 180: todouble(C(m),&t);
! 181: if ( t ) {
! 182: NEXTMP(mp0,mp);
! 183: C(mp) = t;
! 184: mp->dl = m->dl;
! 185: }
! 186: }
! 187: if ( mp0 ) {
! 188: MKDP(NV((DP)a),mp0,d);
! 189: d->sugar = ((DP)a)->sugar;
! 190: *b = (Obj)d;
! 191: } else
! 192: *b = 0;
! 193:
! 194: break;
! 195: default:
! 196: error("todouble : invalid argument");
! 197: }
! 198: }
! 199:
! 200: void Ptodouble(NODE arg,Obj *rp)
! 201: {
! 202: todouble((Obj)ARG0(arg),rp);
! 203: }
! 204:
! 205: void Peval(NODE arg,Obj *rp)
! 206: {
! 207: long prec;
! 208:
! 209: asir_assert(ARG0(arg),O_R,"eval");
! 210: if ( argc(arg) == 2 ) {
! 211: prec = QTOS((Q)ARG1(arg))*3.32193;
! 212: if ( prec < MPFR_PREC_MIN ) prec = MPFR_PREC_MIN;
! 213: else if ( prec > MPFR_PREC_MAX ) prec = MPFR_PREC_MAX;
! 214: } else
! 215: prec = 0;
! 216: evalr(CO,(Obj)ARG0(arg),prec,rp);
! 217: }
! 218:
! 219: /* set/get decimal precision */
! 220:
! 221: void Psetprec(NODE arg,Obj *rp)
! 222: {
! 223: long p;
! 224: Z q;
! 225: long prec,dprec;
! 226:
! 227: prec = mpfr_get_default_prec();
! 228: /* decimal precision */
! 229: dprec = prec*0.30103;
! 230: STOQ(dprec,q); *rp = (Obj)q;
! 231: if ( arg ) {
! 232: asir_assert(ARG0(arg),O_N,"setprec");
! 233: p = QTOS((Q)ARG0(arg))*3.32193;
! 234: if ( p > 0 )
! 235: prec = p;
! 236: }
! 237: if ( prec < MPFR_PREC_MIN ) prec = MPFR_PREC_MIN;
! 238: else if ( prec > MPFR_PREC_MAX ) prec = MPFR_PREC_MAX;
! 239: mpfr_set_default_prec(prec);
! 240: }
! 241:
! 242: /* set/get bit precision */
! 243:
! 244: void Psetbprec(NODE arg,Obj *rp)
! 245: {
! 246: long p;
! 247: Z q;
! 248: long prec;
! 249:
! 250: prec = mpfr_get_default_prec();
! 251: STOQ(prec,q); *rp = (Obj)q;
! 252: if ( arg ) {
! 253: asir_assert(ARG0(arg),O_N,"setbprec");
! 254: p = QTOS((Q)ARG0(arg));
! 255: if ( p > 0 )
! 256: prec = p;
! 257: }
! 258: if ( prec < MPFR_PREC_MIN ) prec = MPFR_PREC_MIN;
! 259: else if ( prec > MPFR_PREC_MAX ) prec = MPFR_PREC_MAX;
! 260: mpfr_set_default_prec(prec);
! 261: }
! 262:
! 263: void Psetround(NODE arg,Z *rp)
! 264: {
! 265: int round;
! 266:
! 267: STOQ(mpfr_roundmode,*rp);
! 268: if ( arg ) {
! 269: asir_assert(ARG0(arg),O_N,"setround");
! 270: round = QTOS((Q)ARG0(arg));
! 271: switch ( round ) {
! 272: case 0:
! 273: mpfr_roundmode = MPFR_RNDN;
! 274: break;
! 275: case 1:
! 276: mpfr_roundmode = MPFR_RNDZ;
! 277: break;
! 278: case 2:
! 279: mpfr_roundmode = MPFR_RNDU;
! 280: break;
! 281: case 3:
! 282: mpfr_roundmode = MPFR_RNDD;
! 283: break;
! 284: case 4:
! 285: mpfr_roundmode = MPFR_RNDA;
! 286: break;
! 287: case 5:
! 288: mpfr_roundmode = MPFR_RNDF;
! 289: break;
! 290: case 6:
! 291: mpfr_roundmode = MPFR_RNDNA;
! 292: break;
! 293: default:
! 294: error("setround : invalid rounding mode");
! 295: break;
! 296: }
! 297: }
! 298: }
! 299:
! 300: Num tobf(Num a,int prec);
! 301:
! 302: void mp_pi(NODE arg,BF *rp)
! 303: {
! 304: int prec;
! 305: BF r;
! 306:
! 307: prec = arg ? QTOS((Q)ARG0(arg)) : 0;
! 308: NEWBF(r);
! 309: prec ? mpfr_init2(r->body,prec) : mpfr_init(r->body);
! 310: mpfr_const_pi(r->body,mpfr_roundmode);
! 311: if ( !cmpbf((Num)r,0) ) r = 0;
! 312: *rp = r;
! 313: }
! 314:
! 315: void mp_e(NODE arg,BF *rp)
! 316: {
! 317: int prec;
! 318: mpfr_t one;
! 319: BF r;
! 320:
! 321: prec = arg ? QTOS((Q)ARG0(arg)) : 0;
! 322: NEWBF(r);
! 323: prec ? mpfr_init2(r->body,prec) : mpfr_init(r->body);
! 324: mpfr_init(one);
! 325: mpfr_set_ui(one,1,mpfr_roundmode);
! 326: mpfr_exp(r->body,one,mpfr_roundmode);
! 327: if ( !cmpbf((Num)r,0) ) r = 0;
! 328: *rp = r;
! 329: }
! 330:
! 331: void mpfr_or_mpc(NODE arg,int (*mpfr_f)(),int (*mpc_f)(),Num *rp)
! 332: {
! 333: Num a;
! 334: int prec;
! 335: BF r,re,im;
! 336: C c;
! 337: mpc_t mpc,a1;
! 338:
! 339: prec = NEXT(arg) ? QTOS((Q)ARG1(arg)) : mpfr_get_default_prec();
! 340: a = tobf(ARG0(arg),prec);
! 341: if ( a && NID(a)==N_C ) {
! 342: mpc_init2(mpc,prec); mpc_init2(a1,prec);
! 343: re = (BF)((C)a)->r; im = (BF)((C)a)->i;
! 344: mpc_set_fr_fr(a1,re->body,im->body,mpfr_roundmode);
! 345: (*mpc_f)(mpc,a1,mpfr_roundmode);
! 346: MPFRTOBF(mpc_realref(mpc),re);
! 347: MPFRTOBF(mpc_imagref(mpc),im);
! 348: if ( !cmpbf((Num)re,0) ) re = 0;
! 349: if ( !cmpbf((Num)im,0) ) im = 0;
! 350: if ( !im )
! 351: *rp = (Num)re;
! 352: else {
! 353: NEWC(c); c->r = (Num)re; c->i = (Num)im;
! 354: *rp = (Num)c;
! 355: }
! 356: } else {
! 357: NEWBF(r);
! 358: mpfr_init2(r->body,prec);
! 359: (*mpfr_f)(r->body,((BF)a)->body,mpfr_roundmode);
! 360: if ( !cmpbf((Num)r,0) ) r = 0;
! 361: *rp = (Num)r;
! 362: }
! 363: }
! 364:
! 365: void mp_sin(NODE arg,Num *rp)
! 366: {
! 367: mpfr_or_mpc(arg,mpfr_sin,mpc_sin,rp);
! 368: }
! 369:
! 370: void mp_cos(NODE arg,Num *rp)
! 371: {
! 372: mpfr_or_mpc(arg,mpfr_cos,mpc_cos,rp);
! 373: }
! 374:
! 375: void mp_tan(NODE arg,Num *rp)
! 376: {
! 377: mpfr_or_mpc(arg,mpfr_tan,mpc_tan,rp);
! 378: }
! 379:
! 380: void mp_asin(NODE arg,Num *rp)
! 381: {
! 382: mpfr_or_mpc(arg,mpfr_asin,mpc_asin,rp);
! 383: }
! 384:
! 385: void mp_acos(NODE arg,Num *rp)
! 386: {
! 387: mpfr_or_mpc(arg,mpfr_acos,mpc_acos,rp);
! 388: }
! 389:
! 390: void mp_atan(NODE arg,Num *rp)
! 391: {
! 392: mpfr_or_mpc(arg,mpfr_atan,mpc_atan,rp);
! 393: }
! 394:
! 395: void mp_sinh(NODE arg,Num *rp)
! 396: {
! 397: mpfr_or_mpc(arg,mpfr_sinh,mpc_sinh,rp);
! 398: }
! 399:
! 400: void mp_cosh(NODE arg,Num *rp)
! 401: {
! 402: mpfr_or_mpc(arg,mpfr_cosh,mpc_cosh,rp);
! 403: }
! 404:
! 405: void mp_tanh(NODE arg,Num *rp)
! 406: {
! 407: mpfr_or_mpc(arg,mpfr_tanh,mpc_tanh,rp);
! 408: }
! 409:
! 410: void mp_asinh(NODE arg,Num *rp)
! 411: {
! 412: mpfr_or_mpc(arg,mpfr_asinh,mpc_asinh,rp);
! 413: }
! 414:
! 415: void mp_acosh(NODE arg,Num *rp)
! 416: {
! 417: mpfr_or_mpc(arg,mpfr_acosh,mpc_acosh,rp);
! 418: }
! 419:
! 420: void mp_atanh(NODE arg,Num *rp)
! 421: {
! 422: mpfr_or_mpc(arg,mpfr_atanh,mpc_atanh,rp);
! 423: }
! 424:
! 425: void mp_exp(NODE arg,Num *rp)
! 426: {
! 427: mpfr_or_mpc(arg,mpfr_exp,mpc_exp,rp);
! 428: }
! 429:
! 430: void mp_log(NODE arg,Num *rp)
! 431: {
! 432: mpfr_or_mpc(arg,mpfr_log,mpc_log,rp);
! 433: }
! 434:
! 435: void mp_abs(NODE arg,Num *rp)
! 436: {
! 437: mpfr_or_mpc(arg,mpfr_abs,mpc_abs,rp);
! 438: }
! 439:
! 440: void Pfac(NODE arg,Num *rp);
! 441:
! 442: void mp_factorial(NODE arg,Num *rp)
! 443: {
! 444: struct oNODE arg0;
! 445: Num a,a1;
! 446:
! 447: a = (Num)ARG0(arg);
! 448: if ( !a ) *rp = (Num)ONE;
! 449: else if ( INT(a) ) Pfac(arg,rp);
! 450: else {
! 451: addnum(0,a,(Num)ONE,&a1);
! 452: arg0.body = (pointer)a1;
! 453: arg0.next = arg->next;
! 454: Pmpfr_gamma(&arg0,rp);
! 455: }
! 456: }
! 457:
! 458: void mp_pow(NODE arg,Num *rp)
! 459: {
! 460: Num a,e;
! 461: int prec;
! 462: BF r,re,im;
! 463: C c;
! 464: mpc_t mpc,a1,e1;
! 465:
! 466: prec = NEXT(NEXT(arg)) ? QTOS((Q)ARG2(arg)) : mpfr_get_default_prec();
! 467: a = tobf(ARG0(arg),prec);
! 468: e = tobf(ARG1(arg),prec);
! 469: if ( NID(a) == N_C || NID(e) == N_C || MPFR_SIGN(((BF)a)->body) < 0 ) {
! 470: mpc_init2(mpc,prec); mpc_init2(a1,prec); mpc_init2(e1,prec);
! 471: if ( NID(a) == N_C ) {
! 472: re = (BF)((C)a)->r; im = (BF)((C)a)->i;
! 473: mpc_set_fr_fr(a1,re->body,im->body,mpfr_roundmode);
! 474: } else {
! 475: re = (BF)a;
! 476: mpc_set_fr(a1,re->body,mpfr_roundmode);
! 477: }
! 478: if ( NID(e) == N_C ) {
! 479: re = (BF)((C)e)->r; im = (BF)((C)e)->i;
! 480: mpc_set_fr_fr(e1,re->body,im->body,mpfr_roundmode);
! 481: } else {
! 482: re = (BF)e;
! 483: mpc_set_fr(e1,re->body,mpfr_roundmode);
! 484: }
! 485: mpc_pow(mpc,a1,e1,mpfr_roundmode);
! 486: MPFRTOBF(mpc_realref(mpc),re);
! 487: MPFRTOBF(mpc_imagref(mpc),im);
! 488: if ( !cmpbf((Num)re,0) ) re = 0;
! 489: if ( !cmpbf((Num)im,0) ) im = 0;
! 490: if ( !im )
! 491: *rp = (Num)re;
! 492: else {
! 493: NEWC(c); c->r = (Num)re; c->i = (Num)im;
! 494: *rp = (Num)c;
! 495: }
! 496: } else {
! 497: NEWBF(r);
! 498: mpfr_init2(r->body,prec);
! 499: mpfr_pow(r->body,((BF)a)->body,((BF)e)->body,mpfr_roundmode);
! 500: *rp = (Num)r;
! 501: }
! 502: }
! 503:
! 504: #define SETPREC \
! 505: (prec)=NEXT(arg)?QTOS((Q)ARG1(arg)):0;\
! 506: (prec)*=3.32193;\
! 507: (a)=tobf(ARG0(arg),prec);\
! 508: NEWBF(r);\
! 509: prec ? mpfr_init2(r->body,prec) : mpfr_init(r->body);
! 510:
! 511:
! 512: void Pmpfr_gamma(NODE arg,BF *rp)
! 513: {
! 514: Num a;
! 515: int prec;
! 516: BF r;
! 517:
! 518: SETPREC
! 519: mpfr_gamma(r->body,((BF)a)->body,mpfr_roundmode);
! 520: *rp = r;
! 521: }
! 522:
! 523: void Pmpfr_lngamma(NODE arg,BF *rp)
! 524: {
! 525: Num a;
! 526: int prec;
! 527: BF r;
! 528:
! 529: SETPREC
! 530: mpfr_lngamma(r->body,((BF)a)->body,mpfr_roundmode);
! 531: *rp = r;
! 532: }
! 533:
! 534: void Pmpfr_digamma(NODE arg,BF *rp)
! 535: {
! 536: Num a;
! 537: int prec;
! 538: BF r;
! 539:
! 540: SETPREC
! 541: mpfr_digamma(r->body,((BF)a)->body,mpfr_roundmode);
! 542: *rp = r;
! 543: }
! 544:
! 545: void Pmpfr_zeta(NODE arg,BF *rp)
! 546: {
! 547: Num a;
! 548: int prec;
! 549: BF r;
! 550:
! 551: SETPREC
! 552: mpfr_zeta(r->body,((BF)a)->body,mpfr_roundmode);
! 553: *rp = r;
! 554: }
! 555:
! 556: void Pmpfr_eint(NODE arg,BF *rp)
! 557: {
! 558: Num a;
! 559: int prec;
! 560: BF r;
! 561:
! 562: SETPREC
! 563: mpfr_eint(r->body,((BF)a)->body,mpfr_roundmode);
! 564: *rp = r;
! 565: }
! 566:
! 567: void Pmpfr_erf(NODE arg,BF *rp)
! 568: {
! 569: Num a;
! 570: int prec;
! 571: BF r;
! 572:
! 573: SETPREC
! 574: mpfr_erf(r->body,((BF)a)->body,mpfr_roundmode);
! 575: *rp = r;
! 576: }
! 577:
! 578: void Pmpfr_erfc(NODE arg,BF *rp)
! 579: {
! 580: Num a;
! 581: int prec;
! 582: BF r;
! 583:
! 584: SETPREC
! 585: mpfr_erfc(r->body,((BF)a)->body,mpfr_roundmode);
! 586: *rp = r;
! 587: }
! 588:
! 589: void Pmpfr_j0(NODE arg,BF *rp)
! 590: {
! 591: Num a;
! 592: int prec;
! 593: BF r;
! 594:
! 595: SETPREC
! 596: mpfr_j0(r->body,((BF)a)->body,mpfr_roundmode);
! 597: *rp = r;
! 598: }
! 599:
! 600: void Pmpfr_j1(NODE arg,BF *rp)
! 601: {
! 602: Num a;
! 603: int prec;
! 604: BF r;
! 605:
! 606: SETPREC
! 607: mpfr_j1(r->body,((BF)a)->body,mpfr_roundmode);
! 608: *rp = r;
! 609: }
! 610:
! 611: void Pmpfr_y0(NODE arg,BF *rp)
! 612: {
! 613: Num a;
! 614: int prec;
! 615: BF r;
! 616:
! 617: SETPREC
! 618: mpfr_y0(r->body,((BF)a)->body,mpfr_roundmode);
! 619: *rp = r;
! 620: }
! 621:
! 622: void Pmpfr_y1(NODE arg,BF *rp)
! 623: {
! 624: Num a;
! 625: int prec;
! 626: BF r;
! 627:
! 628: SETPREC
! 629: mpfr_y1(r->body,((BF)a)->body,mpfr_roundmode);
! 630: *rp = r;
! 631: }
! 632:
! 633: void Pmpfr_li2(NODE arg,BF *rp)
! 634: {
! 635: Num a;
! 636: int prec;
! 637: BF r;
! 638:
! 639: SETPREC
! 640: mpfr_li2(r->body,((BF)a)->body,mpfr_roundmode);
! 641: *rp = r;
! 642: }
! 643:
! 644: void Pmpfr_ai(NODE arg,BF *rp)
! 645: {
! 646: Num a;
! 647: int prec;
! 648: BF r;
! 649:
! 650: SETPREC
! 651: mpfr_ai(r->body,((BF)a)->body,mpfr_roundmode);
! 652: *rp = r;
! 653: }
! 654:
! 655: void Pmpfr_floor(NODE arg,Z *rp)
! 656: {
! 657: Num a;
! 658: long prec;
! 659: BF r;
! 660: mpz_t t;
! 661:
! 662: SETPREC
! 663: mpfr_floor(r->body,((BF)a)->body);
! 664: mpz_init(t);
! 665: mpfr_get_z(t,r->body,mpfr_roundmode);
! 666: MPZTOZ(t,*rp);
! 667: }
! 668:
! 669: void Pmpfr_ceil(NODE arg,Z *rp)
! 670: {
! 671: Num a;
! 672: long prec;
! 673: BF r;
! 674: mpz_t t;
! 675: Z rz;
! 676:
! 677: SETPREC
! 678: mpfr_ceil(r->body,((BF)a)->body);
! 679: mpz_init(t);
! 680: mpfr_get_z(t,r->body,mpfr_roundmode);
! 681: MPZTOZ(t,*rp);
! 682: }
! 683:
! 684: void Pmpfr_round(NODE arg,Z *rp)
! 685: {
! 686: Num a;
! 687: long prec;
! 688: BF r;
! 689: mpz_t t;
! 690:
! 691: SETPREC
! 692: mpfr_round(r->body,((BF)a)->body);
! 693: mpz_init(t);
! 694: mpfr_get_z(t,r->body,mpfr_roundmode);
! 695: MPZTOZ(t,*rp);
! 696: }
! 697:
! 698: double **almat_double(int n)
! 699: {
! 700: int i;
! 701: double **a;
! 702:
! 703: a = (double **)MALLOC(n*sizeof(double *));
! 704: for ( i = 0; i < n; i++ )
! 705: a[i] = (double *)MALLOC(n*sizeof(double));
! 706: return a;
! 707: }
! 708:
! 709: /*
! 710: * k <- (A(xi)-(sbeta-mn2/xi))f
! 711: * A(t) = (num[0]+num[1]t+...+num[d-1]*t^(d-1))/den(t)
! 712: */
! 713:
! 714: struct jv {
! 715: int j;
! 716: double v;
! 717: };
! 718:
! 719: struct smat {
! 720: int *rlen;
! 721: struct jv **row;
! 722: };
! 723:
! 724: void eval_pfaffian2(double *k,int n,int d,struct smat *num,P den,double xi,double *f)
! 725: {
! 726: struct smat ma;
! 727: struct jv *maj;
! 728: int i,j,l,s;
! 729: double t,dn;
! 730: P r;
! 731: Real u;
! 732:
! 733: memset(k,0,n*sizeof(double));
! 734: for ( i = d-1; i >= 0; i-- ) {
! 735: ma = num[i];
! 736: for ( j = 0; j < n; j++ ) {
! 737: maj = ma.row[j];
! 738: l = ma.rlen[j];
! 739: for ( t = 0, s = 0; s < l; s++, maj++ ) t += maj->v*f[maj->j];
! 740: k[j] = k[j]*xi+t;
! 741: }
! 742: }
! 743: MKReal(xi,u);
! 744: substp(CO,den,den->v,(P)u,&r); dn = ToReal(r);
! 745: for ( j = 0; j < n; j++ )
! 746: k[j] /= dn;
! 747: }
! 748:
! 749: void Prk_ratmat(NODE arg,LIST *rp)
! 750: {
! 751: VECT mat;
! 752: P den;
! 753: int ord;
! 754: double sbeta,x0,x1,xi,h,mn2,hd;
! 755: double a2,a3,a4,a5,a6;
! 756: double b21,b31,b32,b41,b42,b43,b51,b52,b53,b54,b61,b62,b63,b64,b65;
! 757: double c1,c2,c3,c4,c5,c6,c7;
! 758: VECT fv;
! 759: int step,j,i,k,n,d,len,s;
! 760: struct smat *num;
! 761: Obj **b;
! 762: MAT mati;
! 763: double *f,*w,*k1,*k2,*k3,*k4,*k5,*k6;
! 764: NODE nd,nd1;
! 765: Real x,t;
! 766: LIST l;
! 767:
! 768: ord = QTOS((Q)ARG0(arg));
! 769: mat = (VECT)ARG1(arg); den = (P)ARG2(arg);
! 770: x0 = ToReal((Num)ARG3(arg)); x1 = ToReal((Num)ARG4(arg));
! 771: step = QTOS((Q)ARG5(arg)); fv = (VECT)ARG6(arg);
! 772: h = (x1-x0)/step;
! 773:
! 774: n = fv->len;
! 775: d = mat->len;
! 776: num = (struct smat *)MALLOC(d*sizeof(struct smat));
! 777: for ( i = 0; i < d; i++ ) {
! 778: num[i].rlen = (int *)MALLOC_ATOMIC(n*sizeof(int));
! 779: num[i].row = (struct jv **)MALLOC(n*sizeof(struct jv *));
! 780: mati = (MAT)mat->body[i];
! 781: b = (Obj **)mati->body;
! 782: for ( j = 0; j < n; j++ ) {
! 783: for ( len = k = 0; k < n; k++ )
! 784: if ( b[j][k] ) len++;
! 785: num[i].rlen[j] = len;
! 786: if ( !len )
! 787: num[i].row[j] = 0;
! 788: else {
! 789: num[i].row[j] = (struct jv *)MALLOC_ATOMIC((len)*sizeof(struct jv));
! 790: for ( s = k = 0; k < n; k++ )
! 791: if ( b[j][k] ) {
! 792: num[i].row[j][s].j = k;
! 793: num[i].row[j][s].v = ToReal((Num)b[j][k]);
! 794: s++;
! 795: }
! 796: }
! 797: }
! 798: }
! 799: f = (double *)MALLOC_ATOMIC(n*sizeof(double));
! 800: for ( j = 0; j < n; j++ )
! 801: f[j] = ToReal((Num)fv->body[j]);
! 802: w = (double *)MALLOC_ATOMIC(n*sizeof(double));
! 803: k1 = (double *)MALLOC_ATOMIC(n*sizeof(double));
! 804: k2 = (double *)MALLOC_ATOMIC(n*sizeof(double));
! 805: k3 = (double *)MALLOC_ATOMIC(n*sizeof(double));
! 806: k4 = (double *)MALLOC_ATOMIC(n*sizeof(double));
! 807: k5 = (double *)MALLOC_ATOMIC(n*sizeof(double));
! 808: k6 = (double *)MALLOC(n*sizeof(double));
! 809: nd = 0;
! 810: switch ( ord ) {
! 811: case 4:
! 812: a2 = 1/2.0*h; b21 = 1/2.0*h;
! 813: a3 = 1/2.0*h; b31 = 0.0; b32 = 1/2.0*h;
! 814: a4 = 1.0*h; b41 = 0.0; b42 = 0.0; b43 = 1.0*h;
! 815: c1 = 1/6.0*h; c2 = 1/3.0*h; c3 = 1/3.0*h; c4 = 1/6.0*h;
! 816: for ( i = 0; i < step; i++ ) {
! 817: if ( !(i%100000) ) fprintf(stderr,"[%d]",i);
! 818: xi = x0+i*h;
! 819: eval_pfaffian2(k1,n,d,num,den,xi,f);
! 820: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b21*k1[j];
! 821: eval_pfaffian2(k2,n,d,num,den,xi+a2,w);
! 822: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b31*k1[j]+b32*k2[j];
! 823: eval_pfaffian2(k3,n,d,num,den,xi+a3,w);
! 824: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b41*k1[j]+b42*k2[j]+b43*k3[j];
! 825: eval_pfaffian2(k4,n,d,num,den,xi+a4,w);
! 826: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += c1*k1[j]+c2*k2[j]+c3*k3[j]+c4*k4[j];
! 827: memcpy(f,w,n*sizeof(double));
! 828: MKReal(f[0],t);
! 829: MKReal(xi+h,x);
! 830: nd1 = mknode(2,x,t);
! 831: MKLIST(l,nd1);
! 832: MKNODE(nd1,l,nd);
! 833: nd = nd1;
! 834: for ( hd = f[0], j = 0; j < n; j++ ) f[j] /= hd;
! 835: }
! 836: MKLIST(*rp,nd);
! 837: break;
! 838: case 5:
! 839: default:
! 840: a2 = 1/4.0*h; b21 = 1/4.0*h;
! 841: a3 = 1/4.0*h; b31 = 1/8.0*h; b32 = 1/8.0*h;
! 842: a4 = 1/2.0*h; b41 = 0.0; b42 = 0.0; b43 = 1/2.0*h;
! 843: a5 = 3/4.0*h; b51 = 3/16.0*h;b52 = -3/8.0*h; b53 = 3/8.0*h; b54 = 9/16.0*h;
! 844: a6 = 1.0*h; b61 = -3/7.0*h;b62 = 8/7.0*h; b63 = 6/7.0*h; b64 = -12/7.0*h; b65 = 8/7.0*h;
! 845: c1 = 7/90.0*h; c2 = 0.0; c3 = 16/45.0*h; c4 = 2/15.0*h; c5 = 16/45.0*h; c6 = 7/90.0*h;
! 846: for ( i = 0; i < step; i++ ) {
! 847: if ( !(i%100000) ) fprintf(stderr,"[%d]",i);
! 848: xi = x0+i*h;
! 849: eval_pfaffian2(k1,n,d,num,den,xi,f);
! 850: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b21*k1[j];
! 851: eval_pfaffian2(k2,n,d,num,den,xi+a2,w);
! 852: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b31*k1[j]+b32*k2[j];
! 853: eval_pfaffian2(k3,n,d,num,den,xi+a3,w);
! 854: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b41*k1[j]+b42*k2[j]+b43*k3[j];
! 855: eval_pfaffian2(k4,n,d,num,den,xi+a4,w);
! 856: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b51*k1[j]+b52*k2[j]+b53*k3[j]+b54*k4[j];
! 857: eval_pfaffian2(k5,n,d,num,den,xi+a5,w);
! 858: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += b61*k1[j]+b62*k2[j]+b63*k3[j]+b64*k4[j]+b65*k5[j];
! 859: eval_pfaffian2(k6,n,d,num,den,xi+a6,w);
! 860: memcpy(w,f,n*sizeof(double)); for ( j = 0; j < n; j++ ) w[j] += c1*k1[j]+c2*k2[j]+c3*k3[j]+c4*k4[j]+c5*k5[j]+c6*k6[j];
! 861: memcpy(f,w,n*sizeof(double));
! 862: MKReal(f[0],t);
! 863: MKReal(xi+h,x);
! 864: nd1 = mknode(2,x,t);
! 865: MKLIST(l,nd1);
! 866: MKNODE(nd1,l,nd);
! 867: nd = nd1;
! 868: for ( hd = f[0], j = 0; j < n; j++ ) f[j] /= hd;
! 869: }
! 870: MKLIST(*rp,nd);
! 871: break;
! 872: }
! 873: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>