47#define GMPSPREAD (GMP_LIMB_BITS/BITSINWORD)
50void Form_mpf_init(mpf_t t);
51void Form_mpf_clear(mpf_t t);
52void Form_mpf_set_prec_raw(mpf_t t,ULONG newprec);
53void FormtoZ(mpz_t z,UWORD *a,WORD na);
54void ZtoForm(UWORD *a,WORD *na,mpz_t z);
55long FloatToInteger(UWORD *out, mpf_t floatin,
long *bitsused);
56void IntegerToFloat(mpf_t result, UWORD *formlong,
int longsize);
57int FloatToRat(UWORD *ratout, WORD *nratout, mpf_t floatin);
58int AddFloats(PHEAD WORD *fun3, WORD *fun1, WORD *fun2);
59int MulFloats(PHEAD WORD *fun3, WORD *fun1, WORD *fun2);
60int DivFloats(PHEAD WORD *fun3, WORD *fun1, WORD *fun2);
61int AddRatToFloat(PHEAD WORD *outfun, WORD *infun, UWORD *formrat, WORD nrat);
62int MulRatToFloat(PHEAD WORD *outfun, WORD *infun, UWORD *formrat, WORD nrat);
63void SimpleDelta(mpf_t sum,
int m);
64void SimpleDeltaC(mpf_t sum,
int m);
65void SingleTable(mpf_t *tabl,
int N,
int m,
int pow);
66void DoubleTable(mpf_t *tabout, mpf_t *tabin,
int N,
int m,
int pow);
67void EndTable(mpf_t sum, mpf_t *tabin,
int N,
int m,
int pow);
68void deltaMZV(mpf_t, WORD *,
int);
69void deltaEuler(mpf_t, WORD *,
int);
70void deltaEulerC(mpf_t, WORD *,
int);
71void CalculateMZVhalf(mpf_t, WORD *,
int);
72void CalculateMZV(mpf_t, WORD *,
int);
73void CalculateEuler(mpf_t, WORD *,
int);
74int ExpandMZV(WORD *term, WORD level);
75int ExpandEuler(WORD *term, WORD level);
76int PackFloat(WORD *,mpf_t);
77int UnpackFloat(mpf_t, WORD *);
78void RatToFloat(mpf_t result, UWORD *formrat,
int ratsize);
177void Form_mpf_init(mpf_t t)
181 if ( t->_mp_d ) { M_free(t->_mp_d,
"Form_mpf_init"); t->_mp_d = 0; }
182 prec = (AC.DefaultPrecision + 8*
sizeof(mp_limb_t)-1)/(8*
sizeof(mp_limb_t)) + 1;
186 d = (mp_limb_t *)Malloc1(prec*
sizeof(mp_limb_t),
"Form_mpf_init");
188 MesPrint(
"Fatal error in Malloc1 call in Form_mpf_init. Trying to allocate %ld bytes.",
189 prec*
sizeof(mp_limb_t));
193 for ( i = 0; i < prec; i++ ) d[i] = 0;
201void Form_mpf_clear(mpf_t t)
203 if ( t->_mp_d ) { M_free(t->_mp_d,
"Form_mpf_init"); t->_mp_d = 0; }
214void Form_mpf_empty(mpf_t t)
217 for ( i = 0; i < t->_mp_prec; i++ ) t->_mp_d[i] = 0;
227void Form_mpf_set_prec_raw(mpf_t t,ULONG newprec)
229 ULONG newpr = (newprec + 8*
sizeof(mp_limb_t)-1)/(8*
sizeof(mp_limb_t)) + 1;
230 if ( newpr <= (ULONG)(t->_mp_prec) ) {
231 int i, used = ABS(t->_mp_size) ;
232 if ( newpr > (ULONG)used ) {
233 for ( i = used; i < (int)newpr; i++ ) t->_mp_d[i] = 0;
235 if ( t->_mp_size < 0 ) newpr = -newpr;
244 MesPrint(
"Trying too big a precision %ld in Form_mpf_set_prec_raw.",newprec);
245 MesPrint(
"Old maximal precision is %ld.",
246 (
size_t)(t->_mp_prec-1)*
sizeof(mp_limb_t)*8);
271int PackFloat(WORD *fun,mpf_t infloat)
273 WORD *t, nlimbs, num, nnum;
274 mp_limb_t *d = infloat->_mp_d;
276 long e = infloat->_mp_exp;
282 *t++ = infloat->_mp_prec;
284 *t++ = infloat->_mp_size;
290 if ( ( e >> (BITSINWORD-1) ) == 0 ) {
291 *t++ = -SNUMBER; *t++ = -e;
294 *t++ = ARGHEAD+6; *t++ = 0; FILLARG(t);
297 *t++ = (UWORD)(e >> BITSINWORD);
298 *t++ = 1; *t++ = 0; *t++ = -5;
302 if ( ( e >> (BITSINWORD-1) ) == 0 ) {
303 *t++ = -SNUMBER; *t++ = e;
306 *t++ = ARGHEAD+6; *t++ = 0; FILLARG(t);
309 *t++ = (UWORD)(e >> BITSINWORD);
310 *t++ = 1; *t++ = 0; *t++ = 5;
317 nlimbs = infloat->_mp_size < 0 ? -infloat->_mp_size: infloat->_mp_size;
322 else if ( nlimbs == 1 && (ULONG)(*d) < ((ULONG)1)<<(BITSINWORD-1) ) {
327 if ( d[nlimbs-1] < ((ULONG)1)<<BITSINWORD ) {
334 *t++ = 2*num+2+ARGHEAD;
339 *t++ = (UWORD)(*d); *t++ = (UWORD)(((ULONG)(*d))>>BITSINWORD); d++;
342 if ( num == 1 ) { *t++ = (UWORD)(*d); }
344 for ( i = 1; i < nnum; i++ ) *t++ = 0;
366int UnpackFloat(mpf_t outfloat,WORD *fun)
376 if ( AT.aux_ == 0 ) {
377 MLOCK(ErrorMessageLock);
378 MesPrint(
"Illegal attempt at using a float_ function without proper startup.");
379 MesPrint(
"Please use %#StartFloat <options> first.");
380 MUNLOCK(ErrorMessageLock);
388 if ( TestFloat(fun) == 0 )
goto Incorrect;
389 f = fun + FUNHEAD + 2;
390 if ( ABS(f[1]) > f[-1]+1 )
goto Incorrect;
391 if ( f[1] > outfloat->_mp_prec+1
392 || outfloat->_mp_d == 0 ) {
400 if ( outfloat->_mp_d != 0 ) free(outfloat->_mp_d);
401 outfloat->_mp_d = (mp_limb_t *)malloc((f[1]+1)*
sizeof(mp_limb_t));
404 outfloat->_mp_size = num;
405 if ( num < 0 ) { num = -num; }
407 if ( *f == -SNUMBER ) {
408 outfloat->_mp_exp = (mp_exp_t)(f[1]);
415 -(mp_exp_t)((((ULONG)(f[-4]))<<BITSINWORD)+(UWORD)f[-5]);
417 else if ( f[-1] == 5 ) {
419 (mp_exp_t)((((ULONG)(f[-4]))<<BITSINWORD)+(UWORD)f[-5]);
426 if ( outfloat->_mp_size == 0 ) {
427 for ( i = 0; i < outfloat->_mp_prec; i++ ) *d++ = 0;
430 else if ( *f == -SNUMBER ) {
431 *d++ = (mp_limb_t)f[1];
432 for ( i = 0; i < outfloat->_mp_prec; i++ ) *d++ = 0;
435 num = (*f-ARGHEAD-2)/2;
436 t = (UWORD *)(f+ARGHEAD+1);
438 *d++ = (mp_limb_t)((((ULONG)(t[1]))<<BITSINWORD)+t[0]);
441 if ( num == 1 ) *d++ = (mp_limb_t)((UWORD)(*t));
442 for ( i = d-outfloat->_mp_d; i <= outfloat->_mp_prec; i++ ) *d++ = 0;
456int TestFloat(WORD *fun)
458 WORD *fstop, *f, num, nnum, i;
465 while ( f < fstop ) { num++; NEXTARG(f); }
466 if ( num != 4 )
return(0);
468 if ( *f != -SNUMBER )
return(0);
469 if ( f[1] < 0 )
return(0);
471 if ( *f != -SNUMBER )
return(0);
474 if ( *f == -SNUMBER ) { f += 2; }
476 if ( *f != ARGHEAD+6 )
return(0);
477 if ( ABS(f[ARGHEAD+5]) != 5 )
return(0);
478 if ( f[ARGHEAD+3] != 1 )
return(0);
479 if ( f[ARGHEAD+4] != 0 )
return(0);
482 if ( num == 0 )
return(1);
483 if ( *f == -SNUMBER ) {
if ( num != 1 )
return(0); }
485 nnum = (ABS(f[*f-1])-1)/2;
486 if ( ( *f != 4*num+2+ARGHEAD ) && ( *f != 4*num+ARGHEAD ) )
return(0);
487 if ( ( nnum != 2*num ) && ( nnum != 2*num-1 ) )
return(0);
489 if ( f[0] != 1 )
return(0);
490 for ( i = 1; i < nnum; i++ ) {
491 if ( f[i] != 0 )
return(0);
515void FormtoZ(mpz_t z,UWORD *a,WORD na)
527 if ( nb < 0 ) { sgn = -1; nb = -nb; }
529 if ( mpz_cmp_si(z,0L) <= 1 ) {
530 mpz_set_ui(z,10000000);
532 if ( z->_mp_alloc <= nlimbs ) {
535 while ( z->_mp_alloc <= nlimbs ) {
541 z->_mp_size = sgn*nlimbs;
544 *d++ = (((mp_limb_t)(b[1]))<<BITSINWORD)+(mp_limb_t)(b[0]);
547 if ( nb == 1 ) { *d = (mp_limb_t)(*b); }
559void ZtoForm(UWORD *a,WORD *na,mpz_t z)
561 mp_limb_t *d = z->_mp_d;
562 int nlimbs = ABS(z->_mp_size), i;
564 if ( nlimbs == 0 ) { *na = 0;
return; }
566 for ( i = 0; i < nlimbs-1; i++ ) {
568 *a++ = (UWORD)((*d++)>>BITSINWORD);
573 j = (UWORD)((*d)>>BITSINWORD);
574 if ( j != 0 ) { *a = j; *na += 1; }
575 if ( z->_mp_size < 0 ) *na = -*na;
585long FloatToInteger(UWORD *out, mpf_t floatin,
long *bitsused)
591 mpz_set_f(z,floatin);
592 ZtoForm(out,&nout,z);
594 x = out[nout-1]; nx = 0;
595 while ( x ) { nx++; x >>= 1; }
596 *bitsused = (nout-1)*BITSINWORD + nx;
608void IntegerToFloat(mpf_t result, UWORD *formlong,
int longsize)
612 FormtoZ(z,formlong,longsize);
624void RatToFloat(mpf_t result, UWORD *formrat,
int ratsize)
630 if ( ratsize < 0 ) { ratsize = -ratsize; sgn = 1; }
631 nnum = nden = (ratsize-1)/2;
632 num = formrat; den = formrat+nnum;
633 while ( num[nnum-1] == 0 ) { nnum--; }
634 while ( den[nden-1] == 0 ) { nden--; }
635 IntegerToFloat(aux2,num,nnum);
636 IntegerToFloat(aux3,den,nden);
637 mpf_div(result,aux2,aux3);
638 if ( sgn > 0 ) mpf_neg(result,result);
646WORD FloatFunToRat(PHEAD UWORD *ratout,WORD *in)
648 WORD oldin = in[0], nratout;
650 UnpackFloat(aux4,in);
651 FloatToRat(ratout,&nratout,aux4);
672int FloatToRat(UWORD *ratout, WORD *nratout, mpf_t floatin)
675 WORD *out = AT.WorkPointer;
677 UWORD *a, *b, *c, *d, *mc;
678 WORD na, nb, nc, nd, i;
680 LONG oldpWorkPointer = AT.pWorkPointer;
681 long bitsused = 0, totalbitsused = 0, totalbits = AC.DefaultPrecision-AC.MaxWeight-1;
682 int retval = 0, startnul;
683 WantAddPointers(AC.DefaultPrecision);
684 AT.pWorkSpace[AT.pWorkPointer++] = out;
685 a = NumberMalloc(
"FloatToRat");
686 b = NumberMalloc(
"FloatToRat");
688 s = mpf_sgn(floatin);
689 if ( s < 0 ) mpf_neg(floatin,floatin);
691 Form_mpf_empty(aux1);
692 Form_mpf_empty(aux2);
693 Form_mpf_empty(aux3);
695 mpf_trunc(aux1,floatin);
696 mpf_sub(aux2,floatin,aux1);
697 if ( mpf_sgn(aux1) == 0 ) { *out++ = 0; startnul = 1; }
699 nout = FloatToInteger((UWORD *)out,aux1,&totalbitsused);
703 AT.pWorkSpace[AT.pWorkPointer++] = out;
704 if ( mpf_sgn(aux2) ) {
706 mpf_ui_div(aux3,1,aux2);
707 mpf_trunc(aux1,aux3);
708 mpf_sub(aux2,aux3,aux1);
709 if ( mpf_sgn(aux1) == 0 ) { *out++ = 0; }
711 nout = FloatToInteger((UWORD *)out,aux1,&bitsused);
714 if ( bitsused > (totalbits-totalbitsused)/2 ) {
break; }
715 if ( mpf_sgn(aux2) == 0 ) {
716 AT.pWorkSpace[AT.pWorkPointer++] = out;
719 totalbitsused += bitsused;
720 AT.pWorkSpace[AT.pWorkPointer++] = out;
727 if ( startnul == 1 && AT.pWorkPointer == oldpWorkPointer + 2 ) {
728 *ratout++ = 0; *ratout++ = 1; *ratout = *nratout = 3;
742 out = (WORD *)(AT.pWorkSpace[--AT.pWorkPointer]);
744 c = (UWORD *)(AT.pWorkSpace[--AT.pWorkPointer]);
745 nc = nb = ((UWORD *)out)-c;
746 for ( i = 0; i < nb; i++ ) b[i] = c[i];
747 mc = c = NumberMalloc(
"FloatToRat");
748 while ( AT.pWorkPointer > oldpWorkPointer ) {
749 d = (UWORD *)(AT.pWorkSpace[--AT.pWorkPointer]);
750 nd = (UWORD *)(AT.pWorkSpace[AT.pWorkPointer+1])-d;
751 if ( nd == 1 && *d == 0 )
break;
752 c = a; a = b; b = c; nc = na; na = nb; nb = nc;
753 MulLong(d,nd,a,na,mc,&nc);
754 AddLong(mc,nc,b,nb,b,&nb);
756 NumberFree(mc,
"FloatToRat");
757 if ( startnul == 0 ) {
758 c = a; a = b; b = c; nc = na; na = nb; nb = nc;
762 c = (UWORD *)(AT.pWorkSpace[oldpWorkPointer]);
763 na = (UWORD *)out - c;
764 for ( i = 0; i < na; i++ ) a[i] = c[i];
772 *nratout = (2*na+1)*s;
773 for ( i = 0; i < na; i++ ) *d++ = a[i];
774 for ( i = 0; i < nb; i++ ) *d++ = b[i];
776 else if ( na < nb ) {
777 *nratout = (2*nb+1)*s;
778 for ( i = 0; i < na; i++ ) *d++ = a[i];
779 for ( ; i < nb; i++ ) *d++ = 0;
780 for ( i = 0; i < nb; i++ ) *d++ = b[i];
783 *nratout = (2*na+1)*s;
784 for ( i = 0; i < na; i++ ) *d++ = a[i];
785 for ( i = 0; i < nb; i++ ) *d++ = b[i];
786 for ( ; i < na; i++ ) *d++ = 0;
788 *d = (UWORD)(*nratout);
789 NumberFree(b,
"FloatToRat");
790 NumberFree(a,
"FloatToRat");
791 AT.pWorkPointer = oldpWorkPointer;
795 if ( s < 0 ) mpf_neg(floatin,floatin);
813void ZeroTable(mpf_t *tab,
int N)
816 for ( i = 0; i < N; i++ ) {
817 for ( j = 0; j < tab[i]->_mp_prec; j++ ) tab[i]->_mp_d[j] = 0;
831SBYTE *ReadFloat(SBYTE *s)
836 while ( *ss > 0 ) ss++;
838 gmp_sscanf((
char *)s,
"%Ff",aux1);
839 if ( AT.WorkPointer > AT.WorkTop ) {
840 MLOCK(ErrorMessageLock);
842 MUNLOCK(ErrorMessageLock);
845 PackFloat(AT.WorkPointer,aux1);
857UBYTE *CheckFloat(UBYTE *ss,
int *spec)
863 if ( *s ==
'.' && FG.cTable[s[-1]] != 1 && FG.cTable[s[1]] != 1 )
return(ss);
864 while ( FG.cTable[s[-1]] == 1 ) s--;
866 if ( *s !=
'.' && FG.cTable[*s] != 1 )
return(ss);
868 while ( FG.cTable[*s] == 1 ) s++;
872 while ( FG.cTable[*s] == 1 ) s++;
878 if ( *s ==
'e' || *s ==
'E' ) {
880 if ( *s ==
'-' || *s ==
'+' ) s++;
881 if ( FG.cTable[*s] == 1 ) {
883 while ( FG.cTable[*s] == 1 ) s++;
887 else if ( gotdot == 0 )
return(ss);
888 if ( AT.aux_ == 0 ) {
910int SetFloatPrecision(WORD prec)
913 MesPrint(
"&Illegal value for number of bits for floating point constants: %d",prec);
917 AC.DefaultPrecision = prec;
918 if ( AO.floatspace != 0 ) M_free(AO.floatspace,
"floatspace");
919 AO.floatsize = (prec+20)*
sizeof(
char);
920 AO.floatspace = (UBYTE *)Malloc1(AO.floatsize,
"floatspace");
921 mpf_set_default_prec(prec);
939int PrintFloat(WORD *fun,
int numdigits)
944 int prec = (AC.DefaultPrecision-AC.MaxWeight-1)*log10(2.0);
945 if ( numdigits > prec || numdigits == 0 ) {
952 if ( UnpackFloat(aux4,fun) == 0 )
953 n = gmp_snprintf((
char *)(AO.floatspace),AO.floatsize,
"%.*Fe",numdigits-1,aux4);
956 s1 = AO.floatspace+n;
957 while ( s1 > AO.floatspace && s1[-1] !=
'e'
958 && s1[-1] !=
'E' && s1[-1] !=
'.' ) { s1--; n2--; }
959 if ( s1 > AO.floatspace && s1[-1] !=
'.' ) {
962 while ( s1[-1] ==
'0' ) { s1--; n1--; }
963 if ( s1[-1] ==
'.' ) { s1++; n1++; }
965 while ( n1 < n ) { *s1++ = *s2++; n1++; }
968 if ( AC.OutputMode == FORTRANMODE ) {
969 s1 = AO.floatspace+n;
970 while ( s1 > AO.floatspace && *s1 !=
'e' && *s1 !=
'E' ) {
973 if ( ( AO.DoubleFlag & 2 ) == 2 ) { *s1 =
'Q'; }
974 else if ( ( AO.DoubleFlag & 1 ) == 1 ) { *s1 =
'D'; }
977 if ( AC.OutputMode == MATHEMATICAMODE ) {
978 s1 = AO.floatspace+n;
979 s2 = s1+2; *s2-- = 0;
980 while ( s1 > AO.floatspace && *s1 !=
'e' && *s1 !=
'E' ) {
983 *s2-- =
'^'; *s2 =
'*';
995int AddFloats(PHEAD WORD *fun3, WORD *fun1, WORD *fun2)
998 if ( UnpackFloat(aux1,fun1) == 0 && UnpackFloat(aux2,fun2) == 0 ) {
999 mpf_add(aux1,aux1,aux2);
1000 PackFloat(fun3,aux1);
1002 else { retval = -1; }
1011int MulFloats(PHEAD WORD *fun3, WORD *fun1, WORD *fun2)
1014 if ( UnpackFloat(aux1,fun1) == 0 && UnpackFloat(aux2,fun2) == 0 ) {
1015 mpf_mul(aux1,aux1,aux2);
1016 PackFloat(fun3,aux1);
1018 else { retval = -1; }
1027int DivFloats(PHEAD WORD *fun3, WORD *fun1, WORD *fun2)
1030 if ( UnpackFloat(aux1,fun1) == 0 && UnpackFloat(aux2,fun2) == 0 ) {
1031 mpf_div(aux1,aux1,aux2);
1032 PackFloat(fun3,aux1);
1034 else { retval = -1; }
1045int AddRatToFloat(PHEAD WORD *outfun, WORD *infun, UWORD *formrat, WORD nrat)
1048 if ( UnpackFloat(aux2,infun) == 0 ) {
1049 RatToFloat(aux1,formrat,nrat);
1050 mpf_add(aux2,aux2,aux1);
1051 PackFloat(outfun,aux2);
1064int MulRatToFloat(PHEAD WORD *outfun, WORD *infun, UWORD *formrat, WORD nrat)
1067 if ( UnpackFloat(aux2,infun) == 0 ) {
1068 RatToFloat(aux1,formrat,nrat);
1069 mpf_mul(aux2,aux2,aux1);
1070 PackFloat(outfun,aux2);
1081void SetupMZVTables(
void)
1093 int i, Nw, id, totnum;
1096 Nw = AC.DefaultPrecision;
1098 totnum = AM.totalnumberofthreads;
1099 for (
id = 0;
id < totnum;
id++ ) {
1100 AB[id]->T.mpf_tab1 = (
void *)Malloc1((N+2)*
sizeof(mpf_t),
"mpftab1");
1101 a = (mpf_t *)AB[
id]->T.mpf_tab1;
1102 for ( i = 0; i <=Nw; i++ ) {
1109 AB[id]->T.mpf_tab2 = (
void *)Malloc1((N+2)*
sizeof(mpf_t),
"mpftab2");
1110 a = (mpf_t *)AB[
id]->T.mpf_tab2;
1111 for ( i = 0; i <=Nw; i++ ) {
1118 Nw = AC.DefaultPrecision;
1120 AT.mpf_tab1 = (
void *)Malloc1((N+2)*
sizeof(mpf_t),
"mpftab1");
1121 for ( i = 0; i <= Nw; i++ ) {
1126 mpf_init(mpftab1[i]);
1128 AT.mpf_tab2 = (
void *)Malloc1((N+2)*
sizeof(mpf_t),
"mpftab2");
1129 for ( i = 0; i <= Nw; i++ ) {
1130 mpf_init(mpftab2[i]);
1133 AS.delta_1 = (
void *)Malloc1(
sizeof(mpf_t),
"delta1");
1134 mpf_init(mpfdelta1);
1135 SimpleDelta(mpfdelta1,1);
1145void SetupMPFTables(
void)
1151 totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
1153 for (
id = 0;
id < totnum;
id++ ) {
1158 AB[id]->T.aux_ = (
void *)Malloc1(
sizeof(mpf_t)*8,
"AB[id]->T.aux_");
1159 a = (mpf_t *)AB[
id]->T.aux_;
1160 mpf_inits(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],(mpf_ptr)0);
1161 if ( AB[
id]->T.indi1 ) M_free(AB[
id]->T.indi1,
"indi1");
1162 AB[id]->T.indi1 = (WORD *)Malloc1(
sizeof(WORD)*AC.MaxWeight*2,
"indi1");
1163 AB[id]->T.indi2 = AB[id]->T.indi1 + AC.MaxWeight;
1166 AT.aux_ = (
void *)Malloc1(
sizeof(mpf_t)*8,
"AT.aux_");
1167 mpf_inits(aux1,aux2,aux3,aux4,aux5,auxjm,auxjjm,auxsum,(mpf_ptr)0);
1168 if ( AT.indi1 ) M_free(AT.indi1,
"indi1");
1169 AT.indi1 = (WORD *)Malloc1(
sizeof(WORD)*AC.MaxWeight*2,
"indi1");
1170 AT.indi2 = AT.indi1 + AC.MaxWeight;
1179void ClearMZVTables(
void)
1184 totnum = AM.totalnumberofthreads;
1185 for (
id = 0;
id < totnum;
id++ ) {
1186 if ( AB[
id]->T.mpf_tab1 ) {
1191 a = (mpf_t *)AB[
id]->T.mpf_tab1;
1192 for ( i = 0; i <=AC.DefaultPrecision; i++ ) {
1195 M_free(AB[
id]->T.mpf_tab1,
"mpftab1");
1196 AB[id]->T.mpf_tab1 = 0;
1198 if ( AB[
id]->T.mpf_tab2 ) {
1199 a = (mpf_t *)AB[
id]->T.mpf_tab2;
1200 for ( i = 0; i <=AC.DefaultPrecision; i++ ) {
1203 M_free(AB[
id]->T.mpf_tab2,
"mpftab2");
1204 AB[id]->T.mpf_tab2 = 0;
1208 totnum = MaX(2*AM.totalnumberofthreads-3,AM.totalnumberofthreads);
1210 for (
id = 0;
id < totnum;
id++ ) {
1211 if ( AB[
id]->T.aux_ ) {
1212 a = (mpf_t *)AB[
id]->T.aux_;
1213 mpf_clears(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],(mpf_ptr)0);
1214 M_free(AB[
id]->T.aux_,
"AB[id]->T.aux_");
1217 if ( AB[
id]->T.indi1 ) { M_free(AB[
id]->T.indi1,
"indi1"); AB[id]->T.indi1 = 0; }
1221 if ( AT.mpf_tab1 ) {
1222 for ( i = 0; i <= AC.DefaultPrecision; i++ ) {
1223 mpf_clear(mpftab1[i]);
1225 M_free(AT.mpf_tab1,
"mpftab1");
1228 if ( AT.mpf_tab2 ) {
1229 for ( i = 0; i <= AC.DefaultPrecision; i++ ) {
1230 mpf_clear(mpftab2[i]);
1232 M_free(AT.mpf_tab2,
"mpftab2");
1236 mpf_clears(aux1,aux2,aux3,aux4,aux5,auxjm,auxjjm,auxsum,(mpf_ptr)0);
1237 M_free(AT.aux_,
"AT.aux_");
1240 if ( AT.indi1 ) { M_free(AT.indi1,
"indi1"); AT.indi1 = 0; }
1242 if ( AO.floatspace ) { M_free(AO.floatspace,
"floatspace"); AO.floatspace = 0;
1245 mpf_clear(mpfdelta1);
1246 M_free(AS.delta_1,
"delta1");
1256int CoToFloat(UBYTE *s)
1259 if ( AT.aux_ == 0 ) {
1260 MesPrint(
"&Illegal attempt to convert to float_ without activating floating point numbers.");
1261 MesPrint(
"&Forgotten %#startfloat instruction?");
1264 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1266 MesPrint(
"&Illegal argument(s) in ToFloat statement: '%s'",s);
1269 Add2Com(TYPETOFLOAT);
1278int CoToRat(UBYTE *s)
1281 if ( AT.aux_ == 0 ) {
1282 MesPrint(
"&Illegal attempt to convert from float_ without activating floating point numbers.");
1283 MesPrint(
"&Forgotten %#startfloat instruction?");
1286 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1288 MesPrint(
"&Illegal argument(s) in ToRat statement: '%s'",s);
1305int CoStrictRounding(UBYTE *s)
1310 if ( AT.aux_ == 0 ) {
1311 MesPrint(
"&Illegal attempt for strict rounding without activating floating point numbers.");
1312 MesPrint(
"&Forgotten %#startfloat instruction?");
1315 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1318 x = AC.DefaultPrecision - AC.MaxWeight - 1;
1321 else if ( FG.cTable[*s] == 1 ) {
1323 if ( tolower(*s) ==
'd' ) { base = 10; s++; }
1324 else if ( tolower(*s) ==
'b' ){ base = 2; s++; }
1330 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1335 MesPrint(
"&Illegal argument(s) in StrictRounding statement: '%s'",s);
1338 Add4Com(TYPESTRICTROUNDING,x,base);
1359 if ( AT.aux_ == 0 ) {
1360 MesPrint(
"&Illegal attempt to chop a float_ without activating floating point numbers.");
1361 MesPrint(
"&Forgotten %#startfloat instruction?");
1365 MesPrint(
"&Chop needs a number (float, rational or power) as an argument.");
1369 w = OldWork = AT.WorkPointer;
1373 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1380 if ( FG.cTable[*s] == 1 || *s ==
'.' ) {
1382 ss = CheckFloat(s, &spec);
1390 ReadFloat((SBYTE *)s);
1397 if ( FG.cTable[*s] == 1 ) {
1401 while ( *s ==
' ' || *s ==
'\t' ) s++;
1403 if ( *s ==
'/' || *s ==
'^' ) {
1405 while ( *s ==
' ' || *s ==
'\t' ) s++;
1406 if ( *s ==
'-' ) { s++; pow = -1; }
1408 if ( FG.cTable[*s] == 1 ) {
1412 MesPrint(
"&Division by zero in chop statement.");
1416 mpf_div_ui(aux1, aux1,x);
1419 mpf_pow_ui(aux1,aux1,x);
1421 mpf_ui_div(aux1,(
unsigned long) 1, aux1);
1432 MesPrint(
"&Illegal argument(s) in Chop statement: '%s'.",s);
1435 AT.WorkPointer = OldWork;
1436 AT.WorkPointer[1] = w - AT.WorkPointer;
1437 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
1448int ToFloat(PHEAD WORD *term, WORD level)
1450 WORD *t, *tstop, nsize, nsign = 3;
1454 if ( t[-1] < 0 ) { nsign = -nsign; }
1455 if ( nsize == 3 && t[-2] == 1 && t[-3] == 1 ) {
1457 while ( t < tstop ) {
1458 if ( ( *t == FLOATFUN ) && ( t+t[1] == tstop ) ) {
1464 RatToFloat(aux4,(UWORD *)tstop,nsize);
1465 PackFloat(tstop,aux4);
1467 *tstop++ = 1; *tstop++ = 1; *tstop++ = nsign;
1468 *term = tstop - term;
1469 AT.WorkPointer = tstop;
1480int ToRat(PHEAD WORD *term, WORD level)
1482 WORD *tstop, *t, nsize, nsign, ncoef;
1486 tstop = term + *term; nsize = ABS(tstop[-1]);
1487 nsign = tstop[-1] < 0 ? -1: 1; tstop -= nsize;
1489 while ( t < tstop ) {
1490 if ( *t == FLOATFUN && t + t[1] == tstop && TestFloat(t) &&
1491 nsize == 3 && tstop[0] == 1 && tstop[1] == 1 )
break;
1499 UnpackFloat(aux4,t);
1501 if ( mpf_sgn(aux4) == 0 )
return(0);
1502 if ( FloatToRat((UWORD *)t,&ncoef,aux4) == 0 ) {
1504 if ( t[0] == 0 && t[1] == 1 && ncoef == 3 )
return(0);
1506 t[-1] = ncoef*nsign;
1520int StrictRounding(PHEAD WORD *term, WORD level, WORD prec, WORD base) {
1522 int sign,size,maxprec = AC.DefaultPrecision-AC.MaxWeight-1;
1524 if ( base == 2 && prec > maxprec ) {
1527 if ( base == 10 && prec > (
int)(maxprec*log10(2.0)) ) {
1528 prec = maxprec*log10(2.0);
1531 tstop = term + *term; size = ABS(tstop[-1]);
1532 sign = tstop[-1] < 0 ? -1: 1; tstop -= size;
1534 while ( t < tstop ) {
1535 if ( *t == FLOATFUN && t + t[1] == tstop && TestFloat(t) &&
1536 size == 3 && tstop[0] == 1 && tstop[1] == 1) {
1549 UnpackFloat(aux4,t);
1555 s = (
char *)AO.floatspace;
1557 mpf_get_str(s,&exp, base, prec, aux4);
1558 while ( *s != 0 ) s++;
1560 snprintf(s,AO.floatsize-(s-(
char *)AO.floatspace),
"%ld",exp);
1562 mpf_set_str(aux4,(
char *)AO.floatspace,-base);
1566 *t++ = 1; *t++ = 1; *t++ = 3*sign;
1582int Chop(PHEAD WORD *term, WORD level)
1584 WORD *tstop, *t, nsize, *threshold;
1585 CBUF *C = cbuf+AM.rbufnum;
1587 tstop = term + *term;
1588 nsize = ABS(tstop[-1]); tstop -= nsize;
1590 while ( t < tstop ) {
1591 if ( *t == FLOATFUN && t + t[1] == tstop && TestFloat(t) &&
1592 nsize == 3 && tstop[0] == 1 && tstop[1] == 1 )
break;
1597 threshold = C->
lhs[level];
1599 UnpackFloat(aux5, threshold);
1602 UnpackFloat(aux4, t);
1603 mpf_abs(aux4, aux4);
1606 if ( mpf_cmp(aux4, aux5) < 0 )
return(0);
1651int AddWithFloat(PHEAD WORD **ps1, WORD **ps2)
1655 WORD *coef1, *coef2, size1, size2, *fun1, *fun2, *fun3;
1656 WORD *s1,*s2,sign3,j,jj, *t1, *t2, i;
1659 coef1 = s1+*s1; size1 = coef1[-1]; coef1 -= ABS(coef1[-1]);
1660 coef2 = s2+*s2; size2 = coef2[-1]; coef2 -= ABS(coef2[-1]);
1661 if ( AT.SortFloatMode == 3 ) {
1662 fun1 = s1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1663 fun2 = s2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1664 UnpackFloat(aux1,fun1);
1665 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1666 UnpackFloat(aux2,fun2);
1667 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1669 else if ( AT.SortFloatMode == 1 ) {
1670 fun1 = s1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1671 UnpackFloat(aux1,fun1);
1672 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1674 RatToFloat(aux2,(UWORD *)coef2,size2);
1676 else if ( AT.SortFloatMode == 2 ) {
1677 fun2 = s2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1679 RatToFloat(aux1,(UWORD *)coef1,size1);
1680 UnpackFloat(aux2,fun2);
1681 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1685 MLOCK(ErrorMessageLock);
1686 MesPrint(
"!>Illegal value %d for AT.SortFloatMode in AddWithFloat.",AT.SortFloatMode);
1687 MUNLOCK(ErrorMessageLock);
1692 mpf_add(aux3,aux1,aux2);
1693 sign3 = mpf_sgn(aux3);
1694 if ( sign3 < 0 ) mpf_neg(aux3,aux3);
1695 fun3 = TermMalloc(
"AddWithFloat");
1696 PackFloat(fun3,aux3);
1707 if ( AT.SortFloatMode == 3 ) {
1708 if ( fun1[1] == fun3[1] ) {
1710 i = fun3[1]; t1 = fun1; t2 = fun3; NCOPY(t1,t2,i);
1711 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1712 *s1 = t1-s1;
goto Finished;
1714 else if ( fun2[1] == fun3[1] ) {
1716 i = fun3[1]; t1 = fun2; t2 = fun3; NCOPY(t1,t2,i);
1717 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1718 *s2 = t1-s2; *ps1 = s2;
goto Finished;
1720 else if ( fun1[1] >= fun3[1] )
goto Over1;
1721 else if ( fun2[1] >= fun3[1] )
goto Over2;
1723 else if ( AT.SortFloatMode == 1 ) {
1724 if ( fun1[1] >= fun3[1] )
goto Over1;
1725 else if ( fun3[1]+3 <= ABS(size2) )
goto Over2;
1727 else if ( AT.SortFloatMode == 2 ) {
1728 if ( fun2[1] >= fun3[1] )
goto Over2;
1729 else if ( fun3[1]+3 <= ABS(size1) )
goto Over1;
1736 if ( (S->sFill + j) >= S->sTop2 ) {
1742 for ( i = 0; i < jj; i++ ) *t1++ = s1[i];
1743 i = fun3[1]; s1 = fun3; NCOPY(t1,s1,i);
1744 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1750 TermFree(fun3,
"AddWithFloat");
1751 AT.SortFloatMode = 0;
1752 if ( **ps1 > AM.MaxTer/((LONG)(
sizeof(WORD))) ) {
1753 MLOCK(ErrorMessageLock);
1754 MesPrint(
"Term too complex after addition in sort. MaxTermSize = %10l",
1755 AM.MaxTer/
sizeof(WORD));
1756 MUNLOCK(ErrorMessageLock);
1759 if ( **ps1 > S->verbMaxTermSize ) S->verbMaxTermSize = **ps1;
1772int MergeWithFloat(PHEAD WORD **interm1, WORD **interm2)
1775 WORD *coef1, *coef2, size1, size2, *fun1, *fun2, *fun3, *tt;
1776 WORD sign3,jj, *t1, *t2, i, *term1 = *interm1, *term2 = *interm2;
1778 coef1 = term1+*term1; size1 = coef1[-1]; coef1 -= ABS(size1);
1779 coef2 = term2+*term2; size2 = coef2[-1]; coef2 -= ABS(size2);
1780 if ( AT.SortFloatMode == 3 ) {
1781 fun1 = term1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1782 fun2 = term2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1783 UnpackFloat(aux1,fun1);
1784 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1785 UnpackFloat(aux2,fun2);
1786 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1788 else if ( AT.SortFloatMode == 1 ) {
1789 fun1 = term1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1790 UnpackFloat(aux1,fun1);
1791 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1793 RatToFloat(aux2,(UWORD *)coef2,size2);
1795 else if ( AT.SortFloatMode == 2 ) {
1796 fun2 = term2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1798 RatToFloat(aux1,(UWORD *)coef1,size1);
1799 UnpackFloat(aux2,fun2);
1800 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1804 MLOCK(ErrorMessageLock);
1805 MesPrint(
"!>Illegal value %d for AT.SortFloatMode in MergeWithFloat.",AT.SortFloatMode);
1806 MUNLOCK(ErrorMessageLock);
1811 mpf_add(aux3,aux1,aux2);
1812 sign3 = mpf_sgn(aux3);
1816 if ( sign3 < 0 ) mpf_neg(aux3,aux3);
1817 fun3 = TermMalloc(
"MergeWithFloat");
1818 PackFloat(fun3,aux3);
1819 if ( AT.SortFloatMode == 3 ) {
1820 if ( fun1[1] + ABS(size1) == fun3[1] + 3 ) {
1821OnTopOf1: t1 = fun3; t2 = fun1;
1822 for ( i = 0; i < fun3[1]; i++ ) *t2++ = *t1++;
1823 *t2++ = 1; *t2++ = 1; *t2++ = sign3 < 0 ? -3: 3;
1826 else if ( fun1[1] + ABS(size1) > fun3[1] + 3 ) {
1827Shift1: t2 = term1 + *term1; tt = t2;
1828 *--t2 = sign3 < 0 ? -3: 3; *--t2 = 1; *--t2 = 1;
1829 t1 = fun3 + fun3[1];
for ( i = 0; i < fun3[1]; i++ ) *--t2 = *--t1;
1831 while ( t1 > term1 ) *--t2 = *--t1;
1832 *t2 = tt-t2; term1 = t2;
1836 jj = fun3[1]-fun1[1]+3-ABS(size1);
1837Over1: t2 = term1-jj; t1 = term1;
1838 while ( t1 < fun1 ) *t2++ = *t1++;
1841 for ( i = 0; i < fun3[1]; i++ ) *t2++ = fun3[i];
1842 *t2++ = 1; *t2++ = 1; *t2++ = sign3 < 0 ? -3: 3;
1846 else if ( AT.SortFloatMode == 1 ) {
1847 if ( fun1[1] + ABS(size1) == fun3[1] + 3 )
goto OnTopOf1;
1848 else if ( fun1[1] + ABS(size1) > fun3[1] + 3 )
goto Shift1;
1850 jj = fun3[1]-fun1[1]+3-ABS(size1);
1855 if ( fun3[1] + 3 == ABS(size1) )
goto OnTopOf1;
1856 else if ( fun3[1] + 3 < ABS(size1) )
goto Shift1;
1858 jj = fun3[1]+3-ABS(size1);
1863 TermFree(fun3,
"MergeWithFloat");
1864 AT.SortFloatMode = 0;
1885void SimpleDelta(mpf_t sum,
int m)
1888 long prec = AC.DefaultPrecision;
1889 unsigned long xprec = (
unsigned long)prec, x;
1892 mpf_init(jm); mpf_init(jjm);
1893 if ( m < 0 ) { s = -1; m = -m; }
1904 while ( x ) { x >>= 1; n++; }
1909 jmax = (int)((
int)xprec - (n-1)*m);
1914 if ( jmax < 0 ) jmax = 1;
1917 x = (
unsigned long)jmax;
1918 while (x) { x >>= 1; n++; }
1921 }
while ( jmax + m * n <= prec );
1923 for ( j = 1; j <= jmax; j++ ) {
1926 mpf_set_prec_raw(jm,xprec);
1927 mpf_set_prec_raw(jjm,xprec);
1930 mpf_div_ui(jjm,jm,(
unsigned long)j);
1931 mpf_pow_ui(jm,jjm,(
unsigned long)m);
1932 mpf_div_2exp(jjm,jm,(
unsigned long)j);
1933 if ( s == -1 && j%2 == 1 ) mpf_sub(sum,sum,jjm);
1934 else mpf_add(sum,sum,jjm);
1936 mpf_clear(jjm); mpf_clear(jm);
1944void SimpleDeltaC(mpf_t sum,
int m)
1947 long prec = AC.DefaultPrecision;
1948 unsigned long xprec = (
unsigned long)prec, x;
1951 mpf_init(jm); mpf_init(jjm);
1952 if ( m < 0 ) { s = -1; m = -m; }
1962 while ( x ) { x >>= 1; n++; }
1967 jmax = (int)((
int)xprec - (n-1)*m);
1972 if ( jmax < 0 ) jmax = 1;
1975 x = (
unsigned long)jmax;
1976 while (x) { x >>= 1; n++; }
1979 }
while ( jmax + m * n <= prec );
1980 if ( s < 0 ) jmax /= 2;
1982 for ( j = 1; j <= jmax; j++ ) {
1985 mpf_set_prec_raw(jm,xprec);
1986 mpf_set_prec_raw(jjm,xprec);
1989 mpf_div_ui(jjm,jm,(
unsigned long)j);
1990 mpf_pow_ui(jm,jjm,(
unsigned long)m);
1991 if ( s == -1 ) mpf_div_2exp(jjm,jm,2*(
unsigned long)j);
1992 else mpf_div_2exp(jjm,jm,(
unsigned long)j);
1993 mpf_add(sum,sum,jjm);
1995 mpf_clear(jjm); mpf_clear(jm);
2003void SingleTable(mpf_t *tabl,
int N,
int m,
int pow)
2020 long prec = mpf_get_default_prec();
2023 mpf_init(jm); mpf_init(jjm);
2024 if ( pow < 1 || pow > 2 ) {
2026 MLOCK(ErrorMessageLock);
2027 MesPrint(
"!>Wrong parameter pow in SingleTable: %d\n",pow);
2028 MUNLOCK(ErrorMessageLock);
2032 if ( m < 0 ) { m = -m; s = -1; }
2033 mpf_set_si(auxsum,0L);
2034 for ( j = N; j > 0; j-- ) {
2036 mpf_set_prec_raw(jm,prec-j);
2037 mpf_set_prec_raw(jjm,prec-j);
2040 mpf_div_ui(jjm,jm,(
unsigned long)j);
2041 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2042 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2043 if ( pow == 2 ) mpf_add(auxsum,auxsum,jjm);
2044 else if ( s == -1 && j%2 == 1 ) mpf_sub(auxsum,auxsum,jjm);
2045 else mpf_add(auxsum,auxsum,jjm);
2049 mpf_set(tabl[j],auxsum);
2051 mpf_clear(jjm); mpf_clear(jm);
2059void DoubleTable(mpf_t *tabout, mpf_t *tabin,
int N,
int m,
int pow)
2064 long prec = mpf_get_default_prec();
2068 mpf_init(jm); mpf_init(jjm);
2069 if ( pow < -1 || pow > 2 ) {
2071 MLOCK(ErrorMessageLock);
2072 MesPrint(
"!>Wrong parameter pow in DoubleTable: %d\n",pow);
2073 MUNLOCK(ErrorMessageLock);
2077 if ( m < 0 ) { m = -m; s = -1; }
2078 mpf_set_ui(auxsum,0L);
2079 for ( j = N; j > 0; j-- ) {
2081 mpf_set_prec_raw(jm,prec-j);
2082 mpf_set_prec_raw(jjm,prec-j);
2085 mpf_div_ui(jjm,jm,(
unsigned long)j);
2086 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2088 mpf_mul_2exp(jjm,jm,(
unsigned long)j);
2089 mpf_mul(jm,jjm,tabin[j+1]);
2091 else if ( pow > 0 ) {
2092 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2093 mpf_mul(jm,jjm,tabin[j+1]);
2096 mpf_mul(jm,jm,tabin[j+1]);
2098 if ( pow == 2 ) mpf_add(auxsum,auxsum,jm);
2099 else if ( s == -1 && j%2 == 1 ) mpf_sub(auxsum,auxsum,jm);
2100 else mpf_add(auxsum,auxsum,jm);
2104 mpf_set(tabout[j],auxsum);
2106 mpf_clear(jjm); mpf_clear(jm);
2114void EndTable(mpf_t sum, mpf_t *tabin,
int N,
int m,
int pow)
2118 long prec = mpf_get_default_prec();
2122 mpf_init(jm); mpf_init(jjm);
2123 if ( pow < -1 || pow > 2 ) {
2125 MLOCK(ErrorMessageLock);
2126 MesPrint(
"!>Wrong parameter pow in EndTable: %d\n",pow);
2127 MUNLOCK(ErrorMessageLock);
2131 if ( m < 0 ) { m = -m; s = -1; }
2133 for ( j = N; j > 0; j-- ) {
2135 mpf_set_prec_raw(jm,prec-j);
2136 mpf_set_prec_raw(jjm,prec-j);
2139 mpf_div_ui(jjm,jm,(
unsigned long)j);
2140 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2142 mpf_mul_2exp(jjm,jm,(
unsigned long)j);
2143 mpf_mul(jm,jjm,tabin[j+1]);
2145 else if ( pow > 0 ) {
2146 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2147 mpf_mul(jm,jjm,tabin[j+1]);
2150 mpf_mul(jm,jm,tabin[j+1]);
2152 if ( s == -1 && j%2 == 1 ) mpf_sub(sum,sum,jm);
2153 else mpf_add(sum,sum,jm);
2155 mpf_clear(jjm); mpf_clear(jm);
2163void deltaMZV(mpf_t result, WORD *indexes,
int depth)
2171 if ( indexes[0] == 1 ) {
2172 mpf_set(result,mpfdelta1);
2175 SimpleDelta(result,indexes[0]);
2177 else if ( depth == 2 ) {
2178 if ( indexes[0] == 1 && indexes[1] == 1 ) {
2179 mpf_pow_ui(result,mpfdelta1,2);
2180 mpf_div_2exp(result,result,1);
2183 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+1,indexes[0],1);
2184 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,indexes[1],0);
2187 else if ( depth > 2 ) {
2193 for ( d = 0; d < depth; d++ ) {
2194 if ( indexes[d] != 1 )
break;
2197 mpf_pow_ui(result,mpfdelta1,depth);
2198 for ( d = 2; d <= depth; d++ ) {
2199 mpf_div_ui(result,result,(
unsigned long)d);
2204 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,1);
2207 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,0);
2210 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,*indexes,0);
2213 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2214 AT.mpf_tab2 = (
void *)mpftab3;
2218 else if ( depth == 0 ) {
2219 mpf_set_ui(result,1L);
2230void deltaEuler(mpf_t result, WORD *indexes,
int depth)
2236 printf(
" deltaEuler(");
2237 for ( i = 0; i < depth; i++ ) {
2238 if ( i != 0 ) printf(
",");
2239 printf(
"%d",indexes[i]);
2244 SimpleDelta(result,indexes[0]);
2246 else if ( depth == 2 ) {
2247 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+1,indexes[0],1);
2248 m = indexes[1];
if ( indexes[0] < 0 ) m = -m;
2249 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,m,0);
2251 else if ( depth > 2 ) {
2255 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,1);
2257 m = *indexes;
if ( indexes[-1] < 0 ) m = -m;
2259 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,m,0);
2261 m = *indexes;
if ( indexes[-1] < 0 ) m = -m;
2263 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,m,0);
2266 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2267 AT.mpf_tab2 = (
void *)mpftab3;
2270 else if ( depth == 0 ) {
2271 mpf_set_ui(result,1L);
2274 gmp_printf(
"%.*Fe\n",40,result);
2286void deltaEulerC(mpf_t result, WORD *indexes,
int depth)
2292 printf(
" deltaEulerC(");
2293 for ( i = 0; i < depth; i++ ) {
2294 if ( i != 0 ) printf(
",");
2295 printf(
"%d",indexes[i]);
2299 mpf_set_ui(result,0);
2301 if ( indexes[0] == 0 ) {
2302 MLOCK(ErrorMessageLock);
2303 MesPrint(
"Illegal index in depth=1 deltaEulerC: %d\n",indexes[0]);
2304 MUNLOCK(ErrorMessageLock);
2307 if ( indexes[0] < 0 ) SimpleDeltaC(result,indexes[0]);
2308 else SimpleDelta(result,indexes[0]);
2310 else if ( depth == 2 ) {
2313 if ( m < 0 ) SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+depth,-m,2);
2314 else SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+depth, m,1);
2316 if ( m < 0 ) { m = -m; par = indexes[0] < 0 ? 0: 1; }
2317 else { par = indexes[0] < 0 ? -1: 0; }
2318 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,m,par);
2320 else if ( depth > 2 ) {
2325 ZeroTable(mpftab1,AC.DefaultPrecision+1);
2326 if ( m < 0 ) SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d+1,-m,2);
2327 else SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d+1, m,1);
2328 d--; indexes++; m = indexes[0];
2329 if ( m < 0 ) { m = -m; par = indexes[-1] < 0 ? 0: 1; }
2330 else { par = indexes[-1] < 0 ? -1: 0; }
2332 ZeroTable(mpftab2,AC.DefaultPrecision-AC.MaxWeight+d);
2333 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,m,par);
2334 d--; indexes++; m = indexes[0];
2335 if ( m < 0 ) { m = -m; par = indexes[-1] < 0 ? 0: 1; }
2336 else { par = indexes[-1] < 0 ? -1: 0; }
2338 mpf_set_ui(result,0);
2339 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,m,par);
2342 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2343 AT.mpf_tab2 = (
void *)mpftab3;
2346 else if ( depth == 0 ) {
2347 mpf_set_ui(result,1L);
2350 gmp_printf(
"%.*Fe\n",40,result);
2362void CalculateMZVhalf(mpf_t result, WORD *indexes,
int depth)
2366 MLOCK(ErrorMessageLock);
2367 MesPrint(
"Illegal depth in CalculateMZVhalf: %d",depth);
2368 MUNLOCK(ErrorMessageLock);
2371 for ( i = 0; i < depth; i++ ) {
2372 if ( indexes[i] <= 0 ) {
2373 MLOCK(ErrorMessageLock);
2374 MesPrint(
"Illegal index[%d] in CalculateMZVhalf: %d",i,indexes[i]);
2375 MUNLOCK(ErrorMessageLock);
2379 deltaMZV(result,indexes,depth);
2387void CalculateMZV(mpf_t result, WORD *indexes,
int depth)
2390 int num1, num2 = 0, i, j = 0;
2392 MLOCK(ErrorMessageLock);
2393 MesPrint(
"Illegal depth in CalculateMZV: %d",depth);
2394 MUNLOCK(ErrorMessageLock);
2397 if ( indexes[0] == 1 ) {
2398 MLOCK(ErrorMessageLock);
2399 MesPrint(
"Divergent MZV in CalculateMZV");
2400 MUNLOCK(ErrorMessageLock);
2404 for ( i = 0; i < depth; i++ ) {
2405 if ( indexes[i] <= 0 ) {
2406 MLOCK(ErrorMessageLock);
2407 MesPrint(
"Illegal index[%d] in CalculateMZV: %d",i,indexes[i]);
2408 MUNLOCK(ErrorMessageLock);
2411 AT.indi1[i] = indexes[i];
2413 num1 = depth; i = 0;
2414 deltaMZV(result,indexes,depth);
2416 if ( AT.indi1[0] > 1 ) {
2418 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2419 AT.indi2[0] = 1; num2++;
2423 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2425 if ( num1 == 0 )
break;
2427 deltaMZV(aux1,AT.indi1,num1);
2428 deltaMZV(aux2,AT.indi2,num2);
2429 mpf_mul(aux3,aux1,aux2);
2430 mpf_add(result,result,aux3);
2432 deltaMZV(aux3,AT.indi2,num2);
2433 mpf_add(result,result,aux3);
2458void CalculateEuler(mpf_t result, WORD *Zindexes,
int depth)
2461 int s1, num1, num2, i, j;
2463 WORD *indexes = AT.WorkPointer;
2464 for ( i = 0; i < depth; i++ ) indexes[i] = Zindexes[i];
2465 for ( i = 0; i < depth-1; i++ ) {
2466 if ( Zindexes[i] < 0 ) {
2467 for ( j = i+1; j < depth; j++ ) indexes[j] = -indexes[j];
2472 MLOCK(ErrorMessageLock);
2473 MesPrint(
"Illegal depth in CalculateEuler: %d\n",depth);
2474 MUNLOCK(ErrorMessageLock);
2477 if ( indexes[0] == 1 ) {
2478 MLOCK(ErrorMessageLock);
2479 MesPrint(
"Divergent Euler sum in CalculateEuler\n");
2480 MUNLOCK(ErrorMessageLock);
2483 for ( i = 0, j = 0; i < depth; i++ ) {
2484 if ( indexes[i] == 0 ) {
2485 MLOCK(ErrorMessageLock);
2486 MesPrint(
"Illegal index[%d] in CalculateEuler: %d\n",i,indexes[i]);
2487 MUNLOCK(ErrorMessageLock);
2490 if ( indexes[i] < 0 ) j = 1;
2491 AT.indi1[i] = indexes[i];
2494 CalculateMZV(result,indexes,depth);
2497 num1 = depth; AT.indi2[0] = 0; num2 = 0;
2498 deltaEuler(result,AT.indi1,depth);
2502 if ( AT.indi1[0] > 1 ) {
2504 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2505 AT.indi2[0] = 1; num2++;
2507 else if ( AT.indi1[0] < -1 ) {
2509 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2510 AT.indi2[0] = 1; num2++;
2512 else if ( AT.indi1[0] == -1 ) {
2513 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2514 AT.indi2[0] = -1; num2++;
2515 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2519 AT.indi2[0] = AT.indi2[0] < 0 ? AT.indi2[0]-1: AT.indi2[0]+1;
2520 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2523 if ( num1 == 0 )
break;
2524 deltaEuler(aux1,AT.indi1,num1);
2525 deltaEulerC(aux2,AT.indi2,num2);
2526 mpf_mul(aux3,aux1,aux2);
2527 if ( (depth+num1+num2+s1)%2 == 0 ) mpf_add(result,result,aux3);
2528 else mpf_sub(result,result,aux3);
2530 deltaEulerC(aux3,AT.indi2,num2);
2531 if ( (depth+num2+s1)%2 == 0 ) mpf_add(result,result,aux3);
2532 else mpf_sub(result,result,aux3);
2540int ExpandMZV(WORD *term, WORD level)
2552int ExpandEuler(WORD *term, WORD level)
2580int EvaluateEuler(PHEAD WORD *term, WORD level, WORD par)
2582 WORD *t, *tstop, *tt, *tnext, sumweight, depth, first = 1, *newterm, i;
2583 WORD *oldworkpointer = AT.WorkPointer, nsize, *indexes;
2585 tstop = term + *term; tstop -= ABS(tstop[-1]);
2586 if ( AT.WorkPointer < term+*term ) AT.WorkPointer = term + *term;
2591 while ( t < tstop ) {
2592 if ( ( *t == par ) || ( ( par == ALLMZVFUNCTIONS ) && (
2593 *t == MZV || *t == EULER || *t == MZVHALF ) ) ) {
2595 indexes = AT.WorkPointer;
2596 sumweight = 0; depth = 0;
2597 tnext = t + t[1]; tt = t + FUNHEAD;
2598 while ( tt < tnext ) {
2599 if ( *tt != -SNUMBER )
goto nextfun;
2600 if ( tt[1] == 0 )
goto nextfun;
2601 indexes[depth] = tt[1];
2602 sumweight += ABS(tt[1]); depth++;
2606 if ( depth == 0)
goto nextfun;
2607 if ( sumweight > AC.MaxWeight ) {
2608 MLOCK(ErrorMessageLock);
2609 MesPrint(
"Error: Weight of Euler/MZV sum greater than %d.",AC.MaxWeight);
2610 MesPrint(
"Please increase the maximum weight in %#startfloat.");
2611 MUNLOCK(ErrorMessageLock);
2617 AT.WorkPointer += depth;
2619 if ( *t == MZV ) CalculateMZV(aux4,indexes,depth);
2620 else if ( *t == EULER ) CalculateEuler(aux4,indexes,depth);
2621 else if ( *t == MZVHALF ) CalculateMZVhalf(aux4,indexes,depth);
2625 if ( *t == MZV ) CalculateMZV(aux5,indexes,depth);
2626 else if ( *t == EULER ) CalculateEuler(aux5,indexes,depth);
2627 else if ( *t == MZVHALF ) CalculateMZVhalf(aux5,indexes,depth);
2628 mpf_mul(aux4,aux4,aux5);
2635 if ( first == 1 )
return(
Generator(BHEAD term,level));
2641 nsize = term[*term-1];
2647 if ( tstop[0] != 1 ) {
2648 mpf_mul_ui(aux4,aux4,(ULONG)((UWORD)tstop[0]));
2650 if ( tstop[1] != 1 ) {
2651 mpf_div_ui(aux4,aux4,(ULONG)((UWORD)tstop[1]));
2655 RatToFloat(aux5,(UWORD *)tstop,nsize);
2656 mpf_mul(aux4,aux4,aux5);
2662 while ( t < tstop ) {
2663 if ( *t == FLOATFUN ) {
2664 UnpackFloat(aux5,t);
2665 mpf_mul(aux4,aux4,aux5);
2673 newterm = AT.WorkPointer;
2675 while ( t < tstop ) {
2676 if ( *t == 0 || *t == FLOATFUN ) t += t[1];
2678 i = t[1]; NCOPY(tt,t,i);
2683 *tt++ = 1; *tt++ = 1; *tt++ = 3;
2684 *newterm = tt-newterm;
2685 AT.WorkPointer = tt;
2686 retval =
Generator(BHEAD newterm,level);
2687 AT.WorkPointer = oldworkpointer;
2700int CoEvaluate(UBYTE *s)
2706 if ( AT.aux_ == 0 ) {
2707 MesPrint(
"&Illegal attempt to evaluate a function without activating floating point numbers.");
2708 MesPrint(
"&Forgotten %#startfloat instruction?");
2711 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2716 Add3Com(TYPEEVALUATE,ALLFUNCTIONS);
2720 Add3Com(TYPEEVALUATE,ALLMZVFUNCTIONS);
2725 while ( FG.cTable[*s] == 0 ) s++;
2726 if ( *s ==
'2' ) s++;
2727 if ( *s ==
'_' ) s++;
2732 if ( ( ( type = GetName(AC.varnames,subkey,&numfun,NOAUTO) ) != CFUNCTION )
2733 || ( functions[numfun].spec != 0 ) ) {
2735 if ( type == CSYMBOL ) {
2736 Add4Com(TYPEEVALUATE,SYMBOL,numfun);
2742 MesPrint(
"&%s should be a built in function that can be evaluated numerically.",s);
2746 switch ( numfun+FUNCTION ) {
2777 Add3Com(TYPEEVALUATE,numfun+FUNCTION);
2780 MesPrint(
"&%s should be a built in function that can be evaluated numerically.",s);
2786 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
int Generator(PHEAD WORD *, WORD)