39#define EXTRAPRECISION 4
43#define auxr1 (((mpfr_t *)(AT.auxr_))[0])
44#define auxr2 (((mpfr_t *)(AT.auxr_))[1])
45#define auxr3 (((mpfr_t *)(AT.auxr_))[2])
46#define auxr4 (((mpfr_t *)(AT.auxr_))[3])
47#define auxr5 (((mpfr_t *)(AT.auxr_))[4])
51int PackFloat(WORD *,mpf_t);
52int UnpackFloat(mpf_t,WORD *);
53void RatToFloat(mpf_t, UWORD *,
int);
54void FormtoZ(mpz_t,UWORD *,WORD);
65void IntegerToFloatr(mpfr_t result, UWORD *formlong,
int longsize)
69 FormtoZ(z,formlong,longsize);
70 mpfr_set_z(result,z,RND);
81void RatToFloatr(mpfr_t result, UWORD *formrat,
int ratsize)
87 if ( ratsize < 0 ) { ratsize = -ratsize; sgn = 1; }
88 nnum = nden = (ratsize-1)/2;
89 num = formrat; den = formrat+nnum;
90 while ( nnum > 1 && num[nnum-1] == 0 ) { nnum--; }
91 while ( nden > 1 && den[nden-1] == 0 ) { nden--; }
92 IntegerToFloatr(auxr4,num,nnum);
93 IntegerToFloatr(auxr5,den,nden);
94 mpfr_div(result,auxr4,auxr5,RND);
95 if ( sgn > 0 ) mpfr_neg(result,result,RND);
108void SetfFloatPrecision(LONG prec)
113 mpfr_prec_t fprec = prec + 1;
114 mpfr_set_default_prec(fprec);
116 int totnum = AM.totalnumberofthreads, id;
119 totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
121 for (
id = 0;
id < totnum;
id++ ) {
122 AB[id]->T.auxr_ = (
void *)Malloc1(
sizeof(mpfr_t)*5,
"AB[id]->T.auxr_");
123 a = (mpfr_t *)AB[
id]->T.auxr_;
128 mpfr_inits2(fprec,a[0],a[1],a[2],a[3],a[4],(mpfr_ptr)0);
131 AT.auxr_ = (
void *)Malloc1(
sizeof(mpfr_t)*5,
"AT.auxr_");
132 mpfr_inits2(fprec,auxr1,auxr2,auxr3,auxr4,auxr5,(mpfr_ptr)0);
141void ClearfFloat(
void)
144 int totnum = AM.totalnumberofthreads, id;
147 totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
149 if ( AB[0]->T.auxr_ ) {
150 for (
id = 0;
id < totnum;
id++ ) {
151 a = (mpfr_t *)AB[
id]->T.auxr_;
152 mpfr_clears(a[0],a[1],a[2],a[3],a[4],(mpfr_ptr)0);
153 M_free(AB[
id]->T.auxr_,
"AB[id]->T.auxr_");
159 mpfr_clears(auxr1,auxr2,auxr3,auxr4,auxr5,(mpfr_ptr)0);
160 M_free(AT.auxr_,
"AT.auxr_");
180int GetFloatArgument(PHEAD mpfr_t f_out,WORD *fun,
int par)
182 WORD *term, *tn, *t, *tstop, first, ncoef, *arg, *argp, abspar;
185 while ( arg < fun+fun[1] && abspar > 1 ) { abspar--; NEXTARG(arg) }
186 if ( arg >= fun+fun[1] || abspar!= 1 )
return(-1);
188 argp = arg; NEXTARG(argp);
if ( argp != fun+fun[1] )
return(-1);
191 if ( *arg == -SNUMBER ) {
192 mpfr_set_si(f_out,(LONG)(arg[1]),RND);
194 else if ( *arg == -SYMBOL && ( arg[1] == PISYMBOL ) ) {
195 mpfr_const_pi(f_out,RND);
197 else if ( *arg == -INDEX && arg[1] >= 0 && arg[1] < AM.OffsetIndex ) {
198 mpfr_set_ui(f_out,(ULONG)(arg[1]),RND);
203 else if ( arg[0] != arg[ARGHEAD]+ARGHEAD ) {
208 tstop = tn-ABS(tn[-1]);
211 while ( t <= tstop ) {
213 if ( first ) RatToFloatr(f_out,(UWORD *)tstop,tn[-1]);
215 RatToFloatr(auxr4,(UWORD *)tstop,tn[-1]);
216 mpfr_mul(f_out,f_out,auxr4,RND);
220 else if ( *t == FLOATFUN ) {
221 if ( t+t[1] != tstop )
return(-1);
222 if ( UnpackFloat(aux5,t) < 0 )
return(-1);
224 mpfr_set_f(f_out,aux5,RND);
228 mpfr_set_f(auxr4,aux5,RND);
229 mpfr_mul(f_out,f_out,auxr4,RND);
234 mpfr_neg(f_out,f_out,RND);
237 if ( ncoef == 3 && tn[-2] == 1 && tn[-3] == 1 )
return(0);
241 MLOCK(ErrorMessageLock);
242 MesPrint(
"Unnormalized argument in GetFloatArgument: %a",*term,term);
243 MUNLOCK(ErrorMessageLock);
246 else if ( t[0] == SYMBOL && t[1] == 4 && t[2] == PISYMBOL && t[3] == 1 ) {
248 mpfr_const_pi(f_out,RND);
252 mpfr_const_pi(auxr5,RND);
253 mpfr_mul(f_out,f_out,auxr5,RND);
275int GetPiArgument(PHEAD WORD *arg)
277 UWORD *coef, *co, *tco, twelve, *numer, *denom, *c, *d;
278 WORD i, ii, i2, iflip, nc, nd, *t, *tn, *tstop;
283 if ( *arg == -SNUMBER && arg[1] == 0 )
return(0);
284 if ( *arg == -SYMBOL && arg[1] == PISYMBOL )
return(12);
285 if ( *arg < 0 )
return(-1);
286 if ( arg[ARGHEAD] != *arg-ARGHEAD )
return(-1);
288 tn = arg+*arg; tstop = tn - ABS(tn[-1]);
289 if ( *t != SYMBOL || t[1] != 4 || t[2] != PISYMBOL || t[3] != 1
290 || t+t[1] != tstop )
return(-1);
295 co = coef = NumberMalloc(
"GetPiArgument");
296 tco = (UWORD *)tstop;
297 i = tn[-1];
if ( i < 0 ) { i = -i; iflip = 1; }
else iflip = 0;
302 Mully(BHEAD co,&ii,&twelve,1);
307 numer = co; denom = numer + i;
310 if ( denom[i2--] != 0 ) {
311 NumberFree(co,
"GetPiArgument");
317 NumberFree(co,
"GetPiArgument");
327 c = NumberMalloc(
"GetPiArgument");
328 d = NumberMalloc(
"GetPiArgument");
330 DivLong(numer,i,&twelve,1,c,&nc,d,&nd);
332 NumberFree(d,
"GetPiArgument");
333 NumberFree(c,
"GetPiArgument");
335 NumberFree(co,
"GetPiArgument");
336 if ( iflip && rem != 0 ) rem = 24-rem;
368int EvaluateFun(PHEAD WORD *term, WORD level, WORD *pars)
370 WORD *t, *tstop, *tt, *tnext, *newterm, i;
371 WORD *oldworkpointer = AT.WorkPointer, nsize, nsgn, nsgn2;
372 int retval = 0, first = 1, pimul;
374 tstop = term + *term; tstop -= ABS(tstop[-1]);
375 if ( AT.WorkPointer < term+*term ) AT.WorkPointer = term + *term;
377 mpfr_set_ui(auxr2,1L,RND);
378 while ( t < tstop ) {
379 if ( pars[2] == *t ) {
384 tnext = t+t[1]; tt = t+FUNHEAD; NEXTARG(tt);
386 for ( WORD* ti = t+2; ti < t+t[1]; ti+=2 ) {
387 if( ( *ti == PISYMBOL || *ti == EESYMBOL || *ti == EMSYMBOL )
388 && ( pars[2] == ALLFUNCTIONS || pars[3] == *ti ) ) {
389 if ( *ti == PISYMBOL )
390 mpfr_const_pi(auxr3,RND);
391 else if ( *ti == EESYMBOL ) {
392 mpfr_set_ui(auxr3,1,RND);
393 mpfr_exp(auxr3,auxr3,RND);
395 else if ( *ti == EMSYMBOL )
396 mpfr_const_euler(auxr3,RND);
398 mpfr_pow_si(auxr3,auxr3,ti[1],RND);
399 mpfr_mul(auxr2,auxr2,auxr3,RND);
406 if ( tt != tnext && *t != AGMFUNCTION && *t != ATAN2FUNCTION)
goto nextfun;
407 if ( *t == SINFUNCTION ) {
408 pimul = GetPiArgument(BHEAD t+FUNHEAD);
409 if ( pimul >= 0 && pimul < 24 ) {
410 if ( pimul == 0 || pimul == 12 )
goto getout;
411 if ( pimul > 12 ) { pimul = 24-pimul; nsgn = -1; }
413 if ( pimul > 6 ) pimul = 12-pimul;
417 mpfr_sqrt_ui(auxr3,3L,RND);
418 mpfr_sub_ui(auxr3,auxr3,1L,RND);
419 mpfr_sqrt_ui(auxr1,2L,RND);
420 mpfr_div_ui(auxr1,auxr1,4L,RND);
421 mpfr_mul(auxr3,auxr3,auxr1,RND);
422 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
423 mpfr_mul(auxr2,auxr2,auxr3,RND);
427 mpfr_div_ui(auxr2,auxr2,2L,RND);
428 if ( nsgn < 0 ) mpfr_neg(auxr2,auxr2,RND);
432 mpfr_sqrt_ui(auxr3,2L,RND);
433 mpfr_div_ui(auxr3,auxr3,2L,RND);
434 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
435 mpfr_mul(auxr2,auxr2,auxr3,RND);
439 mpfr_sqrt_ui(auxr3,3L,RND);
440 mpfr_div_ui(auxr3,auxr3,2L,RND);
441 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
442 mpfr_mul(auxr2,auxr2,auxr3,RND);
446 mpfr_sqrt_ui(auxr3,3L,RND);
447 mpfr_add_ui(auxr3,auxr3,1L,RND);
448 mpfr_sqrt_ui(auxr1,2L,RND);
449 mpfr_div_ui(auxr1,auxr1,4L,RND);
450 mpfr_mul(auxr3,auxr3,auxr1,RND);
451 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
452 mpfr_mul(auxr2,auxr2,auxr3,RND);
456 if ( nsgn < 0 ) mpfr_neg(auxr2,auxr2,RND);
463 else if ( *t == COSFUNCTION ) {
464 pimul = GetPiArgument(BHEAD t+FUNHEAD);
465 if ( pimul >= 0 && pimul < 24 ) {
466 if ( pimul > 12 ) pimul = 24-pimul;
467 if ( pimul > 6 ) { pimul = 12-pimul; nsgn = -1; }
469 if ( pimul == 6 )
goto getout;
480 else if ( *t == TANFUNCTION ) {
481 pimul = GetPiArgument(BHEAD t+FUNHEAD);
482 if ( pimul >= 0 && pimul < 24 ) {
483 if ( pimul == 6 || pimul == 18 )
goto nextfun;
484 if ( pimul == 0 || pimul == 12 )
goto getout;
485 if ( pimul > 12 ) { pimul = 24-pimul; nsgn = -1; }
487 if ( pimul > 6 ) { pimul = 12-pimul; nsgn = -nsgn; }
490 mpfr_sqrt_ui(auxr3,3L,RND);
491 mpfr_sub_ui(auxr3,auxr3,2L,RND);
492 if ( nsgn > 0 ) mpfr_neg(auxr3,auxr3,RND);
493 mpfr_mul(auxr2,auxr2,auxr3,RND);
496 mpfr_sqrt_ui(auxr3,3L,RND);
497 mpfr_div_ui(auxr3,auxr3,3L,RND);
498 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
499 mpfr_mul(auxr2,auxr2,auxr3,RND);
504 mpfr_sqrt_ui(auxr3,3L,RND);
505 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
506 mpfr_mul(auxr2,auxr2,auxr3,RND);
509 mpfr_sqrt_ui(auxr3,3L,RND);
510 mpfr_add_ui(auxr3,auxr3,2L,RND);
511 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
512 mpfr_mul(auxr2,auxr2,auxr3,RND);
520 if ( *t == AGMFUNCTION || *t == ATAN2FUNCTION ) {
521 if ( GetFloatArgument(BHEAD auxr1,t,1) < 0 )
goto nextfun;
522 if ( GetFloatArgument(BHEAD auxr3,t,-2) < 0 )
goto nextfun;
524 else if ( GetFloatArgument(BHEAD auxr1,t,-1) < 0 )
goto nextfun;
525 nsgn = mpfr_sgn(auxr1);
529 if ( nsgn < 0 )
goto nextfun;
530 if ( nsgn == 0 )
goto getout;
531 else mpfr_sqrt(auxr3,auxr1,RND);
532 mpfr_mul(auxr2,auxr2,auxr3,RND);
535 if ( nsgn <= 0 )
goto nextfun;
536 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
537 else mpfr_log(auxr3,auxr1,RND);
538 mpfr_mul(auxr2,auxr2,auxr3,RND);
541 mpfr_exp(auxr3,auxr1,RND);
542 mpfr_mul(auxr2,auxr2,auxr3,RND);
545 if ( nsgn == 0 )
goto getout;
546 mpfr_abs(auxr3,auxr1,RND);
547 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
548 mpfr_li2(auxr3,auxr1,RND);
549 mpfr_mul(auxr2,auxr2,auxr3,RND);
555 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] <= 0 )
goto nextfun;
556 if ( t[FUNHEAD] == t[1]-FUNHEAD && ABS(t[t[1]-1]) ==
557 t[FUNHEAD]-ARGHEAD-1 && t[t[1]-1] < 0 ) {
558 nsize = (-t[t[1]-1]-1)/2;
559 if ( t[t[1]-1-nsize] == 1 ) {
560 for ( i = 1; i < nsize; i++ ) {
561 if ( t[t[1]-1-nsize+i] != 0 )
break;
563 if ( i >= nsize )
goto nextfun;
566 mpfr_gamma(auxr3,auxr1,RND);
567 mpfr_mul(auxr2,auxr2,auxr3,RND);
570 nsgn = mpfr_sgn(auxr1);
571 nsgn2 = mpfr_sgn(auxr3);
572 if ( nsgn == 0 || nsgn2 == 0)
goto getout;
573 if ( nsgn < 0 || nsgn2 < 0 )
goto nextfun;
574 mpfr_agm(auxr3,auxr1,auxr3,RND);
575 mpfr_mul(auxr2,auxr2,auxr3,RND);
578 if ( nsgn == 0 )
goto getout;
579 mpfr_sinh(auxr3,auxr1,RND);
580 mpfr_mul(auxr2,auxr2,auxr3,RND);
583 mpfr_cosh(auxr3,auxr1,RND);
584 mpfr_mul(auxr2,auxr2,auxr3,RND);
587 if ( nsgn == 0 )
goto getout;
588 mpfr_tanh(auxr3,auxr1,RND);
589 mpfr_mul(auxr2,auxr2,auxr3,RND);
592 if ( nsgn == 0 )
goto getout;
593 mpfr_asinh(auxr3,auxr1,RND);
594 mpfr_mul(auxr2,auxr2,auxr3,RND);
597 if ( mpfr_cmp_ui(auxr1,1L) < 0 )
goto nextfun;
598 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
599 mpfr_acosh(auxr3,auxr1,RND);
600 mpfr_mul(auxr2,auxr2,auxr3,RND);
603 if ( nsgn == 0 )
goto getout;
604 mpfr_abs(auxr3,auxr1,RND);
605 if ( mpfr_cmp_ui(auxr3,1L) >= 0 )
goto nextfun;
606 mpfr_atanh(auxr3,auxr1,RND);
607 mpfr_mul(auxr2,auxr2,auxr3,RND);
610 if ( nsgn == 0 )
goto getout;
611 mpfr_abs(auxr3,auxr1,RND);
612 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
613 mpfr_asin(auxr3,auxr1,RND);
614 mpfr_mul(auxr2,auxr2,auxr3,RND);
617 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
618 mpfr_abs(auxr3,auxr1,RND);
619 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
620 mpfr_acos(auxr3,auxr1,RND);
621 mpfr_mul(auxr2,auxr2,auxr3,RND);
624 if ( nsgn == 0 )
goto getout;
625 mpfr_atan(auxr3,auxr1,RND);
626 mpfr_mul(auxr2,auxr2,auxr3,RND);
629 nsgn = mpfr_sgn(auxr1);
630 nsgn2 = mpfr_sgn(auxr3);
632 if ( nsgn == 0 && nsgn2 >= 0)
goto getout;
633 mpfr_atan2(auxr3,auxr1,auxr3,RND);
634 mpfr_mul(auxr2,auxr2,auxr3,RND);
637 mpfr_sin(auxr3,auxr1,RND);
638 mpfr_mul(auxr2,auxr2,auxr3,RND);
641 mpfr_cos(auxr3,auxr1,RND);
642 mpfr_mul(auxr2,auxr2,auxr3,RND);
645 mpfr_tan(auxr3,auxr1,RND);
646 mpfr_mul(auxr2,auxr2,auxr3,RND);
656 else if ( pars[2] == ALLFUNCTIONS ) {
660 if ( t[1] == FUNHEAD )
goto nextfun;
694 if ( first == 1 )
return(
Generator(BHEAD term,level));
695 mpfr_get_f(aux4,auxr2,RND);
702 nsize = term[*term-1];
703 if ( nsize < 0 ) { nsize = -nsize; nsgn = -1; }
705 if ( aux4->_mp_size < 0 ) {
706 aux4->_mp_size = -aux4->_mp_size;
711 if ( tstop[0] != 1 ) {
712 mpf_mul_ui(aux4,aux4,(ULONG)((UWORD)tstop[0]));
714 if ( tstop[1] != 1 ) {
715 mpf_div_ui(aux4,aux4,(ULONG)((UWORD)tstop[1]));
719 RatToFloat(aux5,(UWORD *)tstop,nsize);
720 mpf_mul(aux4,aux4,aux5);
727 while ( t < tstop ) {
728 if ( *t == FLOATFUN ) {
730 mpf_mul(aux4,aux4,aux5);
738 newterm = AT.WorkPointer;
740 while ( t < tstop ) {
741 if ( *t == 0 || *t == FLOATFUN ) t += t[1];
743 i = t[1]; NCOPY(tt,t,i);
748 *tt++ = 1; *tt++ = 1; *tt++ = 3*nsgn;
749 *newterm = tt-newterm;
753 AT.WorkPointer = oldworkpointer;
int Generator(PHEAD WORD *, WORD)