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;
118 totnum = totnum + GetNumberOfSortBots(totnum - 1);
119 for (
id = 0;
id < totnum;
id++ ) {
120 AB[id]->T.auxr_ = (
void *)Malloc1(
sizeof(mpfr_t)*5,
"AB[id]->T.auxr_");
121 a = (mpfr_t *)AB[
id]->T.auxr_;
126 mpfr_inits2(fprec,a[0],a[1],a[2],a[3],a[4],(mpfr_ptr)0);
129 AT.auxr_ = (
void *)Malloc1(
sizeof(mpfr_t)*5,
"AT.auxr_");
130 mpfr_inits2(fprec,auxr1,auxr2,auxr3,auxr4,auxr5,(mpfr_ptr)0);
139void ClearfFloat(
void)
142 int totnum = AM.totalnumberofthreads, id;
144 totnum = totnum + GetNumberOfSortBots(totnum - 1);
145 if ( AB[0]->T.auxr_ ) {
146 for (
id = 0;
id < totnum;
id++ ) {
147 a = (mpfr_t *)AB[
id]->T.auxr_;
148 mpfr_clears(a[0],a[1],a[2],a[3],a[4],(mpfr_ptr)0);
149 M_free(AB[
id]->T.auxr_,
"AB[id]->T.auxr_");
155 mpfr_clears(auxr1,auxr2,auxr3,auxr4,auxr5,(mpfr_ptr)0);
156 M_free(AT.auxr_,
"AT.auxr_");
176int GetFloatArgument(PHEAD mpfr_t f_out,WORD *fun,
int par)
178 WORD *term, *tn, *t, *tstop, first, ncoef, *arg, *argp, abspar;
181 while ( arg < fun+fun[1] && abspar > 1 ) { abspar--; NEXTARG(arg) }
182 if ( arg >= fun+fun[1] || abspar!= 1 )
return(-1);
184 argp = arg; NEXTARG(argp);
if ( argp != fun+fun[1] )
return(-1);
187 if ( *arg == -SNUMBER ) {
188 mpfr_set_si(f_out,(LONG)(arg[1]),RND);
190 else if ( *arg == -SYMBOL && ( arg[1] == PISYMBOL ) ) {
191 mpfr_const_pi(f_out,RND);
193 else if ( *arg == -INDEX && arg[1] >= 0 && arg[1] < AM.OffsetIndex ) {
194 mpfr_set_ui(f_out,(ULONG)(arg[1]),RND);
199 else if ( arg[0] != arg[ARGHEAD]+ARGHEAD ) {
204 tstop = tn-ABS(tn[-1]);
207 while ( t <= tstop ) {
209 if ( first ) RatToFloatr(f_out,(UWORD *)tstop,tn[-1]);
211 RatToFloatr(auxr4,(UWORD *)tstop,tn[-1]);
212 mpfr_mul(f_out,f_out,auxr4,RND);
216 else if ( *t == FLOATFUN ) {
217 if ( t+t[1] != tstop )
return(-1);
218 if ( UnpackFloat(aux5,t) < 0 )
return(-1);
220 mpfr_set_f(f_out,aux5,RND);
224 mpfr_set_f(auxr4,aux5,RND);
225 mpfr_mul(f_out,f_out,auxr4,RND);
230 mpfr_neg(f_out,f_out,RND);
233 if ( ncoef == 3 && tn[-2] == 1 && tn[-3] == 1 )
return(0);
238 MLOCK(ErrorMessageLock);
239 MesPrint(
"!>Unnormalized argument in GetFloatArgument: %a",*term,term);
240 MUNLOCK(ErrorMessageLock);
244 else if ( t[0] == SYMBOL && t[1] == 4 && t[2] == PISYMBOL && t[3] == 1 ) {
246 mpfr_const_pi(f_out,RND);
250 mpfr_const_pi(auxr5,RND);
251 mpfr_mul(f_out,f_out,auxr5,RND);
273int GetPiArgument(PHEAD WORD *arg)
275 UWORD *coef, *co, *tco, twelve, *numer, *denom, *c, *d;
276 WORD i, ii, i2, iflip, nc, nd, *t, *tn, *tstop;
281 if ( *arg == -SNUMBER && arg[1] == 0 )
return(0);
282 if ( *arg == -SYMBOL && arg[1] == PISYMBOL )
return(12);
283 if ( *arg < 0 )
return(-1);
284 if ( arg[ARGHEAD] != *arg-ARGHEAD )
return(-1);
286 tn = arg+*arg; tstop = tn - ABS(tn[-1]);
287 if ( *t != SYMBOL || t[1] != 4 || t[2] != PISYMBOL || t[3] != 1
288 || t+t[1] != tstop )
return(-1);
293 co = coef = NumberMalloc(
"GetPiArgument");
294 tco = (UWORD *)tstop;
295 i = tn[-1];
if ( i < 0 ) { i = -i; iflip = 1; }
else iflip = 0;
300 Mully(BHEAD co,&ii,&twelve,1);
305 numer = co; denom = numer + i;
308 if ( denom[i2--] != 0 ) {
309 NumberFree(co,
"GetPiArgument");
315 NumberFree(co,
"GetPiArgument");
325 c = NumberMalloc(
"GetPiArgument");
326 d = NumberMalloc(
"GetPiArgument");
328 DivLong(numer,i,&twelve,1,c,&nc,d,&nd);
330 NumberFree(d,
"GetPiArgument");
331 NumberFree(c,
"GetPiArgument");
333 NumberFree(co,
"GetPiArgument");
334 if ( iflip && rem != 0 ) rem = 24-rem;
366int EvaluateFun(PHEAD WORD *term, WORD level, WORD *pars)
368 WORD *t, *tstop, *tt, *tnext, *newterm, i;
369 WORD *oldworkpointer = AT.WorkPointer, nsize, nsgn, nsgn2;
370 int retval = 0, first = 1, pimul;
372 tstop = term + *term; tstop -= ABS(tstop[-1]);
373 if ( AT.WorkPointer < term+*term ) AT.WorkPointer = term + *term;
375 mpfr_set_ui(auxr2,1L,RND);
376 while ( t < tstop ) {
377 if ( pars[2] == *t ) {
382 tnext = t+t[1]; tt = t+FUNHEAD; NEXTARG(tt);
384 for ( WORD* ti = t+2; ti < t+t[1]; ti+=2 ) {
385 if( ( *ti == PISYMBOL || *ti == EESYMBOL || *ti == EMSYMBOL )
386 && ( pars[2] == ALLFUNCTIONS || pars[3] == *ti ) ) {
387 if ( *ti == PISYMBOL )
388 mpfr_const_pi(auxr3,RND);
389 else if ( *ti == EESYMBOL ) {
390 mpfr_set_ui(auxr3,1,RND);
391 mpfr_exp(auxr3,auxr3,RND);
393 else if ( *ti == EMSYMBOL )
394 mpfr_const_euler(auxr3,RND);
396 mpfr_pow_si(auxr3,auxr3,ti[1],RND);
397 mpfr_mul(auxr2,auxr2,auxr3,RND);
404 if ( tt != tnext && *t != AGMFUNCTION && *t != ATAN2FUNCTION)
goto nextfun;
405 if ( *t == SINFUNCTION ) {
406 pimul = GetPiArgument(BHEAD t+FUNHEAD);
407 if ( pimul >= 0 && pimul < 24 ) {
408 if ( pimul == 0 || pimul == 12 )
goto getout;
409 if ( pimul > 12 ) { pimul = 24-pimul; nsgn = -1; }
411 if ( pimul > 6 ) pimul = 12-pimul;
415 mpfr_sqrt_ui(auxr3,3L,RND);
416 mpfr_sub_ui(auxr3,auxr3,1L,RND);
417 mpfr_sqrt_ui(auxr1,2L,RND);
418 mpfr_div_ui(auxr1,auxr1,4L,RND);
419 mpfr_mul(auxr3,auxr3,auxr1,RND);
420 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
421 mpfr_mul(auxr2,auxr2,auxr3,RND);
425 mpfr_div_ui(auxr2,auxr2,2L,RND);
426 if ( nsgn < 0 ) mpfr_neg(auxr2,auxr2,RND);
430 mpfr_sqrt_ui(auxr3,2L,RND);
431 mpfr_div_ui(auxr3,auxr3,2L,RND);
432 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
433 mpfr_mul(auxr2,auxr2,auxr3,RND);
437 mpfr_sqrt_ui(auxr3,3L,RND);
438 mpfr_div_ui(auxr3,auxr3,2L,RND);
439 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
440 mpfr_mul(auxr2,auxr2,auxr3,RND);
444 mpfr_sqrt_ui(auxr3,3L,RND);
445 mpfr_add_ui(auxr3,auxr3,1L,RND);
446 mpfr_sqrt_ui(auxr1,2L,RND);
447 mpfr_div_ui(auxr1,auxr1,4L,RND);
448 mpfr_mul(auxr3,auxr3,auxr1,RND);
449 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
450 mpfr_mul(auxr2,auxr2,auxr3,RND);
454 if ( nsgn < 0 ) mpfr_neg(auxr2,auxr2,RND);
461 else if ( *t == COSFUNCTION ) {
462 pimul = GetPiArgument(BHEAD t+FUNHEAD);
463 if ( pimul >= 0 && pimul < 24 ) {
464 if ( pimul > 12 ) pimul = 24-pimul;
465 if ( pimul > 6 ) { pimul = 12-pimul; nsgn = -1; }
467 if ( pimul == 6 )
goto getout;
478 else if ( *t == TANFUNCTION ) {
479 pimul = GetPiArgument(BHEAD t+FUNHEAD);
480 if ( pimul >= 0 && pimul < 24 ) {
481 if ( pimul == 6 || pimul == 18 )
goto nextfun;
482 if ( pimul == 0 || pimul == 12 )
goto getout;
483 if ( pimul > 12 ) { pimul = 24-pimul; nsgn = -1; }
485 if ( pimul > 6 ) { pimul = 12-pimul; nsgn = -nsgn; }
488 mpfr_sqrt_ui(auxr3,3L,RND);
489 mpfr_sub_ui(auxr3,auxr3,2L,RND);
490 if ( nsgn > 0 ) mpfr_neg(auxr3,auxr3,RND);
491 mpfr_mul(auxr2,auxr2,auxr3,RND);
494 mpfr_sqrt_ui(auxr3,3L,RND);
495 mpfr_div_ui(auxr3,auxr3,3L,RND);
496 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
497 mpfr_mul(auxr2,auxr2,auxr3,RND);
502 mpfr_sqrt_ui(auxr3,3L,RND);
503 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
504 mpfr_mul(auxr2,auxr2,auxr3,RND);
507 mpfr_sqrt_ui(auxr3,3L,RND);
508 mpfr_add_ui(auxr3,auxr3,2L,RND);
509 if ( nsgn < 0 ) mpfr_neg(auxr3,auxr3,RND);
510 mpfr_mul(auxr2,auxr2,auxr3,RND);
518 if ( *t == AGMFUNCTION || *t == ATAN2FUNCTION ) {
519 if ( GetFloatArgument(BHEAD auxr1,t,1) < 0 )
goto nextfun;
520 if ( GetFloatArgument(BHEAD auxr3,t,-2) < 0 )
goto nextfun;
522 else if ( GetFloatArgument(BHEAD auxr1,t,-1) < 0 )
goto nextfun;
523 nsgn = mpfr_sgn(auxr1);
527 if ( nsgn < 0 )
goto nextfun;
528 if ( nsgn == 0 )
goto getout;
529 else mpfr_sqrt(auxr3,auxr1,RND);
530 mpfr_mul(auxr2,auxr2,auxr3,RND);
533 if ( nsgn <= 0 )
goto nextfun;
534 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
535 else mpfr_log(auxr3,auxr1,RND);
536 mpfr_mul(auxr2,auxr2,auxr3,RND);
539 mpfr_exp(auxr3,auxr1,RND);
540 mpfr_mul(auxr2,auxr2,auxr3,RND);
543 if ( nsgn == 0 )
goto getout;
544 mpfr_abs(auxr3,auxr1,RND);
545 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
546 mpfr_li2(auxr3,auxr1,RND);
547 mpfr_mul(auxr2,auxr2,auxr3,RND);
553 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] <= 0 )
goto nextfun;
554 if ( t[FUNHEAD] == t[1]-FUNHEAD && ABS(t[t[1]-1]) ==
555 t[FUNHEAD]-ARGHEAD-1 && t[t[1]-1] < 0 ) {
556 nsize = (-t[t[1]-1]-1)/2;
557 if ( t[t[1]-1-nsize] == 1 ) {
558 for ( i = 1; i < nsize; i++ ) {
559 if ( t[t[1]-1-nsize+i] != 0 )
break;
561 if ( i >= nsize )
goto nextfun;
564 mpfr_gamma(auxr3,auxr1,RND);
565 mpfr_mul(auxr2,auxr2,auxr3,RND);
568 nsgn = mpfr_sgn(auxr1);
569 nsgn2 = mpfr_sgn(auxr3);
570 if ( nsgn == 0 || nsgn2 == 0)
goto getout;
571 if ( nsgn < 0 || nsgn2 < 0 )
goto nextfun;
572 mpfr_agm(auxr3,auxr1,auxr3,RND);
573 mpfr_mul(auxr2,auxr2,auxr3,RND);
576 if ( nsgn == 0 )
goto getout;
577 mpfr_sinh(auxr3,auxr1,RND);
578 mpfr_mul(auxr2,auxr2,auxr3,RND);
581 mpfr_cosh(auxr3,auxr1,RND);
582 mpfr_mul(auxr2,auxr2,auxr3,RND);
585 if ( nsgn == 0 )
goto getout;
586 mpfr_tanh(auxr3,auxr1,RND);
587 mpfr_mul(auxr2,auxr2,auxr3,RND);
590 if ( nsgn == 0 )
goto getout;
591 mpfr_asinh(auxr3,auxr1,RND);
592 mpfr_mul(auxr2,auxr2,auxr3,RND);
595 if ( mpfr_cmp_ui(auxr1,1L) < 0 )
goto nextfun;
596 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
597 mpfr_acosh(auxr3,auxr1,RND);
598 mpfr_mul(auxr2,auxr2,auxr3,RND);
601 if ( nsgn == 0 )
goto getout;
602 mpfr_abs(auxr3,auxr1,RND);
603 if ( mpfr_cmp_ui(auxr3,1L) >= 0 )
goto nextfun;
604 mpfr_atanh(auxr3,auxr1,RND);
605 mpfr_mul(auxr2,auxr2,auxr3,RND);
608 if ( nsgn == 0 )
goto getout;
609 mpfr_abs(auxr3,auxr1,RND);
610 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
611 mpfr_asin(auxr3,auxr1,RND);
612 mpfr_mul(auxr2,auxr2,auxr3,RND);
615 if ( mpfr_cmp_ui(auxr1,1L) == 0 )
goto getout;
616 mpfr_abs(auxr3,auxr1,RND);
617 if ( mpfr_cmp_ui(auxr3,1L) > 0 )
goto nextfun;
618 mpfr_acos(auxr3,auxr1,RND);
619 mpfr_mul(auxr2,auxr2,auxr3,RND);
622 if ( nsgn == 0 )
goto getout;
623 mpfr_atan(auxr3,auxr1,RND);
624 mpfr_mul(auxr2,auxr2,auxr3,RND);
627 nsgn = mpfr_sgn(auxr1);
628 nsgn2 = mpfr_sgn(auxr3);
630 if ( nsgn == 0 && nsgn2 >= 0)
goto getout;
631 mpfr_atan2(auxr3,auxr1,auxr3,RND);
632 mpfr_mul(auxr2,auxr2,auxr3,RND);
635 mpfr_sin(auxr3,auxr1,RND);
636 mpfr_mul(auxr2,auxr2,auxr3,RND);
639 mpfr_cos(auxr3,auxr1,RND);
640 mpfr_mul(auxr2,auxr2,auxr3,RND);
643 mpfr_tan(auxr3,auxr1,RND);
644 mpfr_mul(auxr2,auxr2,auxr3,RND);
654 else if ( pars[2] == ALLFUNCTIONS ) {
658 if ( t[1] == FUNHEAD )
goto nextfun;
692 if ( first == 1 )
return(
Generator(BHEAD term,level));
693 mpfr_get_f(aux4,auxr2,RND);
700 nsize = term[*term-1];
701 if ( nsize < 0 ) { nsize = -nsize; nsgn = -1; }
703 if ( aux4->_mp_size < 0 ) {
704 aux4->_mp_size = -aux4->_mp_size;
709 if ( tstop[0] != 1 ) {
710 mpf_mul_ui(aux4,aux4,(ULONG)((UWORD)tstop[0]));
712 if ( tstop[1] != 1 ) {
713 mpf_div_ui(aux4,aux4,(ULONG)((UWORD)tstop[1]));
717 RatToFloat(aux5,(UWORD *)tstop,nsize);
718 mpf_mul(aux4,aux4,aux5);
725 while ( t < tstop ) {
726 if ( *t == FLOATFUN ) {
728 mpf_mul(aux4,aux4,aux5);
736 newterm = AT.WorkPointer;
738 while ( t < tstop ) {
739 if ( *t == 0 || *t == FLOATFUN ) t += t[1];
741 i = t[1]; NCOPY(tt,t,i);
746 *tt++ = 1; *tt++ = 1; *tt++ = 3*nsgn;
747 *newterm = tt-newterm;
751 AT.WorkPointer = oldworkpointer;
int Generator(PHEAD WORD *, WORD)