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);
242 MLOCK(ErrorMessageLock);
243 MesPrint(
"!>Unnormalized argument in GetFloatArgument: %a",*term,term);
244 MUNLOCK(ErrorMessageLock);
248 else if ( t[0] == SYMBOL && t[1] == 4 && t[2] == PISYMBOL && t[3] == 1 ) {
250 mpfr_const_pi(f_out,RND);
254 mpfr_const_pi(auxr5,RND);
255 mpfr_mul(f_out,f_out,auxr5,RND);
277int GetPiArgument(PHEAD WORD *arg)
279 UWORD *coef, *co, *tco, twelve, *numer, *denom, *c, *d;
280 WORD i, ii, i2, iflip, nc, nd, *t, *tn, *tstop;
285 if ( *arg == -SNUMBER && arg[1] == 0 )
return(0);
286 if ( *arg == -SYMBOL && arg[1] == PISYMBOL )
return(12);
287 if ( *arg < 0 )
return(-1);
288 if ( arg[ARGHEAD] != *arg-ARGHEAD )
return(-1);
290 tn = arg+*arg; tstop = tn - ABS(tn[-1]);
291 if ( *t != SYMBOL || t[1] != 4 || t[2] != PISYMBOL || t[3] != 1
292 || t+t[1] != tstop )
return(-1);
297 co = coef = NumberMalloc(
"GetPiArgument");
298 tco = (UWORD *)tstop;
299 i = tn[-1];
if ( i < 0 ) { i = -i; iflip = 1; }
else iflip = 0;
304 Mully(BHEAD co,&ii,&twelve,1);
309 numer = co; denom = numer + i;
312 if ( denom[i2--] != 0 ) {
313 NumberFree(co,
"GetPiArgument");
319 NumberFree(co,
"GetPiArgument");
329 c = NumberMalloc(
"GetPiArgument");
330 d = NumberMalloc(
"GetPiArgument");
332 DivLong(numer,i,&twelve,1,c,&nc,d,&nd);
334 NumberFree(d,
"GetPiArgument");
335 NumberFree(c,
"GetPiArgument");
337 NumberFree(co,
"GetPiArgument");
338 if ( iflip && rem != 0 ) rem = 24-rem;
370int EvaluateFun(PHEAD WORD *term, WORD level, WORD *pars)
372 WORD *t, *tstop, *tt, *tnext, *newterm, i;
373 WORD *oldworkpointer = AT.WorkPointer, nsize, nsgn, nsgn2;
374 int retval = 0, first = 1, pimul;
376 tstop = term + *term; tstop -= ABS(tstop[-1]);
377 if ( AT.WorkPointer < term+*term ) AT.WorkPointer = term + *term;
379 mpfr_set_ui(auxr2,1L,RND);
380 while ( t < tstop ) {
381 if ( pars[2] == *t ) {
386 tnext = t+t[1]; tt = t+FUNHEAD; NEXTARG(tt);
388 for ( WORD* ti = t+2; ti < t+t[1]; ti+=2 ) {
389 if( ( *ti == PISYMBOL || *ti == EESYMBOL || *ti == EMSYMBOL )
390 && ( pars[2] == ALLFUNCTIONS || pars[3] == *ti ) ) {
391 if ( *ti == PISYMBOL )
392 mpfr_const_pi(auxr3,RND);
393 else if ( *ti == EESYMBOL ) {
394 mpfr_set_ui(auxr3,1,RND);
395 mpfr_exp(auxr3,auxr3,RND);
397 else if ( *ti == EMSYMBOL )
398 mpfr_const_euler(auxr3,RND);
400 mpfr_pow_si(auxr3,auxr3,ti[1],RND);
401 mpfr_mul(auxr2,auxr2,auxr3,RND);
408 if ( tt != tnext && *t != AGMFUNCTION && *t != ATAN2FUNCTION)
goto nextfun;
409 if ( *t == SINFUNCTION ) {
410 pimul = GetPiArgument(BHEAD t+FUNHEAD);
411 if ( pimul >= 0 && pimul < 24 ) {
412 if ( pimul == 0 || pimul == 12 )
goto getout;
413 if ( pimul > 12 ) { pimul = 24-pimul; nsgn = -1; }
415 if ( pimul > 6 ) pimul = 12-pimul;
419 mpfr_sqrt_ui(auxr3,3L,RND);
420 mpfr_sub_ui(auxr3,auxr3,1L,RND);
421 mpfr_sqrt_ui(auxr1,2L,RND);
422 mpfr_div_ui(auxr1,auxr1,4L,RND);
423 mpfr_mul(auxr3,auxr3,auxr1,RND);
424 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
425 mpfr_mul(auxr2,auxr2,auxr3,RND);
429 mpfr_div_ui(auxr2,auxr2,2L,RND);
430 if ( nsgn < 0 ) mpfr_neg(auxr2,auxr2,RND);
434 mpfr_sqrt_ui(auxr3,2L,RND);
435 mpfr_div_ui(auxr3,auxr3,2L,RND);
436 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
437 mpfr_mul(auxr2,auxr2,auxr3,RND);
441 mpfr_sqrt_ui(auxr3,3L,RND);
442 mpfr_div_ui(auxr3,auxr3,2L,RND);
443 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
444 mpfr_mul(auxr2,auxr2,auxr3,RND);
448 mpfr_sqrt_ui(auxr3,3L,RND);
449 mpfr_add_ui(auxr3,auxr3,1L,RND);
450 mpfr_sqrt_ui(auxr1,2L,RND);
451 mpfr_div_ui(auxr1,auxr1,4L,RND);
452 mpfr_mul(auxr3,auxr3,auxr1,RND);
453 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
454 mpfr_mul(auxr2,auxr2,auxr3,RND);
458 if ( nsgn < 0 ) mpfr_neg(auxr2,auxr2,RND);
465 else if ( *t == COSFUNCTION ) {
466 pimul = GetPiArgument(BHEAD t+FUNHEAD);
467 if ( pimul >= 0 && pimul < 24 ) {
468 if ( pimul > 12 ) pimul = 24-pimul;
469 if ( pimul > 6 ) { pimul = 12-pimul; nsgn = -1; }
471 if ( pimul == 6 )
goto getout;
482 else if ( *t == TANFUNCTION ) {
483 pimul = GetPiArgument(BHEAD t+FUNHEAD);
484 if ( pimul >= 0 && pimul < 24 ) {
485 if ( pimul == 6 || pimul == 18 )
goto nextfun;
486 if ( pimul == 0 || pimul == 12 )
goto getout;
487 if ( pimul > 12 ) { pimul = 24-pimul; nsgn = -1; }
489 if ( pimul > 6 ) { pimul = 12-pimul; nsgn = -nsgn; }
492 mpfr_sqrt_ui(auxr3,3L,RND);
493 mpfr_sub_ui(auxr3,auxr3,2L,RND);
494 if ( nsgn > 0 ) mpfr_neg(auxr3,auxr3,RND);
495 mpfr_mul(auxr2,auxr2,auxr3,RND);
498 mpfr_sqrt_ui(auxr3,3L,RND);
499 mpfr_div_ui(auxr3,auxr3,3L,RND);
500 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
501 mpfr_mul(auxr2,auxr2,auxr3,RND);
506 mpfr_sqrt_ui(auxr3,3L,RND);
507 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
508 mpfr_mul(auxr2,auxr2,auxr3,RND);
511 mpfr_sqrt_ui(auxr3,3L,RND);
512 mpfr_add_ui(auxr3,auxr3,2L,RND);
513 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
514 mpfr_mul(auxr2,auxr2,auxr3,RND);
522 if ( *t == AGMFUNCTION || *t == ATAN2FUNCTION ) {
523 if ( GetFloatArgument(BHEAD auxr1,t,1) < 0 )
goto nextfun;
524 if ( GetFloatArgument(BHEAD auxr3,t,-2) < 0 )
goto nextfun;
526 else if ( GetFloatArgument(BHEAD auxr1,t,-1) < 0 )
goto nextfun;
527 nsgn = mpfr_sgn(auxr1);
531 if ( nsgn < 0 )
goto nextfun;
532 if ( nsgn == 0 )
goto getout;
533 else mpfr_sqrt(auxr3,auxr1,RND);
534 mpfr_mul(auxr2,auxr2,auxr3,RND);
537 if ( nsgn <= 0 )
goto nextfun;
538 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
539 else mpfr_log(auxr3,auxr1,RND);
540 mpfr_mul(auxr2,auxr2,auxr3,RND);
543 mpfr_exp(auxr3,auxr1,RND);
544 mpfr_mul(auxr2,auxr2,auxr3,RND);
547 if ( nsgn == 0 )
goto getout;
548 mpfr_abs(auxr3,auxr1,RND);
549 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
550 mpfr_li2(auxr3,auxr1,RND);
551 mpfr_mul(auxr2,auxr2,auxr3,RND);
557 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] <= 0 )
goto nextfun;
558 if ( t[FUNHEAD] == t[1]-FUNHEAD && ABS(t[t[1]-1]) ==
559 t[FUNHEAD]-ARGHEAD-1 && t[t[1]-1] < 0 ) {
560 nsize = (-t[t[1]-1]-1)/2;
561 if ( t[t[1]-1-nsize] == 1 ) {
562 for ( i = 1; i < nsize; i++ ) {
563 if ( t[t[1]-1-nsize+i] != 0 )
break;
565 if ( i >= nsize )
goto nextfun;
568 mpfr_gamma(auxr3,auxr1,RND);
569 mpfr_mul(auxr2,auxr2,auxr3,RND);
572 nsgn = mpfr_sgn(auxr1);
573 nsgn2 = mpfr_sgn(auxr3);
574 if ( nsgn == 0 || nsgn2 == 0)
goto getout;
575 if ( nsgn < 0 || nsgn2 < 0 )
goto nextfun;
576 mpfr_agm(auxr3,auxr1,auxr3,RND);
577 mpfr_mul(auxr2,auxr2,auxr3,RND);
580 if ( nsgn == 0 )
goto getout;
581 mpfr_sinh(auxr3,auxr1,RND);
582 mpfr_mul(auxr2,auxr2,auxr3,RND);
585 mpfr_cosh(auxr3,auxr1,RND);
586 mpfr_mul(auxr2,auxr2,auxr3,RND);
589 if ( nsgn == 0 )
goto getout;
590 mpfr_tanh(auxr3,auxr1,RND);
591 mpfr_mul(auxr2,auxr2,auxr3,RND);
594 if ( nsgn == 0 )
goto getout;
595 mpfr_asinh(auxr3,auxr1,RND);
596 mpfr_mul(auxr2,auxr2,auxr3,RND);
599 if ( mpfr_cmp_ui(auxr1,1L) < 0 )
goto nextfun;
600 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
601 mpfr_acosh(auxr3,auxr1,RND);
602 mpfr_mul(auxr2,auxr2,auxr3,RND);
605 if ( nsgn == 0 )
goto getout;
606 mpfr_abs(auxr3,auxr1,RND);
607 if ( mpfr_cmp_ui(auxr3,1L) >= 0 )
goto nextfun;
608 mpfr_atanh(auxr3,auxr1,RND);
609 mpfr_mul(auxr2,auxr2,auxr3,RND);
612 if ( nsgn == 0 )
goto getout;
613 mpfr_abs(auxr3,auxr1,RND);
614 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
615 mpfr_asin(auxr3,auxr1,RND);
616 mpfr_mul(auxr2,auxr2,auxr3,RND);
619 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
620 mpfr_abs(auxr3,auxr1,RND);
621 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
622 mpfr_acos(auxr3,auxr1,RND);
623 mpfr_mul(auxr2,auxr2,auxr3,RND);
626 if ( nsgn == 0 )
goto getout;
627 mpfr_atan(auxr3,auxr1,RND);
628 mpfr_mul(auxr2,auxr2,auxr3,RND);
631 nsgn = mpfr_sgn(auxr1);
632 nsgn2 = mpfr_sgn(auxr3);
634 if ( nsgn == 0 && nsgn2 >= 0)
goto getout;
635 mpfr_atan2(auxr3,auxr1,auxr3,RND);
636 mpfr_mul(auxr2,auxr2,auxr3,RND);
639 mpfr_sin(auxr3,auxr1,RND);
640 mpfr_mul(auxr2,auxr2,auxr3,RND);
643 mpfr_cos(auxr3,auxr1,RND);
644 mpfr_mul(auxr2,auxr2,auxr3,RND);
647 mpfr_tan(auxr3,auxr1,RND);
648 mpfr_mul(auxr2,auxr2,auxr3,RND);
658 else if ( pars[2] == ALLFUNCTIONS ) {
662 if ( t[1] == FUNHEAD )
goto nextfun;
696 if ( first == 1 )
return(
Generator(BHEAD term,level));
697 mpfr_get_f(aux4,auxr2,RND);
704 nsize = term[*term-1];
705 if ( nsize < 0 ) { nsize = -nsize; nsgn = -1; }
707 if ( aux4->_mp_size < 0 ) {
708 aux4->_mp_size = -aux4->_mp_size;
713 if ( tstop[0] != 1 ) {
714 mpf_mul_ui(aux4,aux4,(ULONG)((UWORD)tstop[0]));
716 if ( tstop[1] != 1 ) {
717 mpf_div_ui(aux4,aux4,(ULONG)((UWORD)tstop[1]));
721 RatToFloat(aux5,(UWORD *)tstop,nsize);
722 mpf_mul(aux4,aux4,aux5);
729 while ( t < tstop ) {
730 if ( *t == FLOATFUN ) {
732 mpf_mul(aux4,aux4,aux5);
740 newterm = AT.WorkPointer;
742 while ( t < tstop ) {
743 if ( *t == 0 || *t == FLOATFUN ) t += t[1];
745 i = t[1]; NCOPY(tt,t,i);
750 *tt++ = 1; *tt++ = 1; *tt++ = 3*nsgn;
751 *newterm = tt-newterm;
755 AT.WorkPointer = oldworkpointer;
int Generator(PHEAD WORD *, WORD)