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);
1684 MLOCK(ErrorMessageLock);
1685 MesPrint(
"Illegal value %d for AT.SortFloatMode in AddWithFloat.",AT.SortFloatMode);
1686 MUNLOCK(ErrorMessageLock);
1690 mpf_add(aux3,aux1,aux2);
1691 sign3 = mpf_sgn(aux3);
1692 if ( sign3 < 0 ) mpf_neg(aux3,aux3);
1693 fun3 = TermMalloc(
"AddWithFloat");
1694 PackFloat(fun3,aux3);
1705 if ( AT.SortFloatMode == 3 ) {
1706 if ( fun1[1] == fun3[1] ) {
1708 i = fun3[1]; t1 = fun1; t2 = fun3; NCOPY(t1,t2,i);
1709 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1710 *s1 = t1-s1;
goto Finished;
1712 else if ( fun2[1] == fun3[1] ) {
1714 i = fun3[1]; t1 = fun2; t2 = fun3; NCOPY(t1,t2,i);
1715 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1716 *s2 = t1-s2; *ps1 = s2;
goto Finished;
1718 else if ( fun1[1] >= fun3[1] )
goto Over1;
1719 else if ( fun2[1] >= fun3[1] )
goto Over2;
1721 else if ( AT.SortFloatMode == 1 ) {
1722 if ( fun1[1] >= fun3[1] )
goto Over1;
1723 else if ( fun3[1]+3 <= ABS(size2) )
goto Over2;
1725 else if ( AT.SortFloatMode == 2 ) {
1726 if ( fun2[1] >= fun3[1] )
goto Over2;
1727 else if ( fun3[1]+3 <= ABS(size1) )
goto Over1;
1734 if ( (S->sFill + j) >= S->sTop2 ) {
1740 for ( i = 0; i < jj; i++ ) *t1++ = s1[i];
1741 i = fun3[1]; s1 = fun3; NCOPY(t1,s1,i);
1742 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1748 TermFree(fun3,
"AddWithFloat");
1749 AT.SortFloatMode = 0;
1750 if ( **ps1 > AM.MaxTer/((LONG)(
sizeof(WORD))) ) {
1751 MLOCK(ErrorMessageLock);
1752 MesPrint(
"Term too complex after addition in sort. MaxTermSize = %10l",
1753 AM.MaxTer/
sizeof(WORD));
1754 MUNLOCK(ErrorMessageLock);
1769int MergeWithFloat(PHEAD WORD **interm1, WORD **interm2)
1772 WORD *coef1, *coef2, size1, size2, *fun1, *fun2, *fun3, *tt;
1773 WORD sign3,jj, *t1, *t2, i, *term1 = *interm1, *term2 = *interm2;
1775 coef1 = term1+*term1; size1 = coef1[-1]; coef1 -= ABS(size1);
1776 coef2 = term2+*term2; size2 = coef2[-1]; coef2 -= ABS(size2);
1777 if ( AT.SortFloatMode == 3 ) {
1778 fun1 = term1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1779 fun2 = term2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1780 UnpackFloat(aux1,fun1);
1781 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1782 UnpackFloat(aux2,fun2);
1783 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1785 else if ( AT.SortFloatMode == 1 ) {
1786 fun1 = term1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1787 UnpackFloat(aux1,fun1);
1788 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1790 RatToFloat(aux2,(UWORD *)coef2,size2);
1792 else if ( AT.SortFloatMode == 2 ) {
1793 fun2 = term2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1795 RatToFloat(aux1,(UWORD *)coef1,size1);
1796 UnpackFloat(aux2,fun2);
1797 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1800 MLOCK(ErrorMessageLock);
1801 MesPrint(
"Illegal value %d for AT.SortFloatMode in MergeWithFloat.",AT.SortFloatMode);
1802 MUNLOCK(ErrorMessageLock);
1806 mpf_add(aux3,aux1,aux2);
1807 sign3 = mpf_sgn(aux3);
1811 if ( sign3 < 0 ) mpf_neg(aux3,aux3);
1812 fun3 = TermMalloc(
"MergeWithFloat");
1813 PackFloat(fun3,aux3);
1814 if ( AT.SortFloatMode == 3 ) {
1815 if ( fun1[1] + ABS(size1) == fun3[1] + 3 ) {
1816OnTopOf1: t1 = fun3; t2 = fun1;
1817 for ( i = 0; i < fun3[1]; i++ ) *t2++ = *t1++;
1818 *t2++ = 1; *t2++ = 1; *t2++ = sign3 < 0 ? -3: 3;
1821 else if ( fun1[1] + ABS(size1) > fun3[1] + 3 ) {
1822Shift1: t2 = term1 + *term1; tt = t2;
1823 *--t2 = sign3 < 0 ? -3: 3; *--t2 = 1; *--t2 = 1;
1824 t1 = fun3 + fun3[1];
for ( i = 0; i < fun3[1]; i++ ) *--t2 = *--t1;
1826 while ( t1 > term1 ) *--t2 = *--t1;
1827 *t2 = tt-t2; term1 = t2;
1831 jj = fun3[1]-fun1[1]+3-ABS(size1);
1832Over1: t2 = term1-jj; t1 = term1;
1833 while ( t1 < fun1 ) *t2++ = *t1++;
1836 for ( i = 0; i < fun3[1]; i++ ) *t2++ = fun3[i];
1837 *t2++ = 1; *t2++ = 1; *t2++ = sign3 < 0 ? -3: 3;
1841 else if ( AT.SortFloatMode == 1 ) {
1842 if ( fun1[1] + ABS(size1) == fun3[1] + 3 )
goto OnTopOf1;
1843 else if ( fun1[1] + ABS(size1) > fun3[1] + 3 )
goto Shift1;
1845 jj = fun3[1]-fun1[1]+3-ABS(size1);
1850 if ( fun3[1] + 3 == ABS(size1) )
goto OnTopOf1;
1851 else if ( fun3[1] + 3 < ABS(size1) )
goto Shift1;
1853 jj = fun3[1]+3-ABS(size1);
1858 TermFree(fun3,
"MergeWithFloat");
1859 AT.SortFloatMode = 0;
1880void SimpleDelta(mpf_t sum,
int m)
1883 long prec = AC.DefaultPrecision;
1884 unsigned long xprec = (
unsigned long)prec, x;
1887 mpf_init(jm); mpf_init(jjm);
1888 if ( m < 0 ) { s = -1; m = -m; }
1899 while ( x ) { x >>= 1; n++; }
1904 jmax = (int)((
int)xprec - (n-1)*m);
1909 if ( jmax < 0 ) jmax = 1;
1912 x = (
unsigned long)jmax;
1913 while (x) { x >>= 1; n++; }
1916 }
while ( jmax + m * n <= prec );
1918 for ( j = 1; j <= jmax; j++ ) {
1921 mpf_set_prec_raw(jm,xprec);
1922 mpf_set_prec_raw(jjm,xprec);
1925 mpf_div_ui(jjm,jm,(
unsigned long)j);
1926 mpf_pow_ui(jm,jjm,(
unsigned long)m);
1927 mpf_div_2exp(jjm,jm,(
unsigned long)j);
1928 if ( s == -1 && j%2 == 1 ) mpf_sub(sum,sum,jjm);
1929 else mpf_add(sum,sum,jjm);
1931 mpf_clear(jjm); mpf_clear(jm);
1939void SimpleDeltaC(mpf_t sum,
int m)
1942 long prec = AC.DefaultPrecision;
1943 unsigned long xprec = (
unsigned long)prec, x;
1946 mpf_init(jm); mpf_init(jjm);
1947 if ( m < 0 ) { s = -1; m = -m; }
1957 while ( x ) { x >>= 1; n++; }
1962 jmax = (int)((
int)xprec - (n-1)*m);
1967 if ( jmax < 0 ) jmax = 1;
1970 x = (
unsigned long)jmax;
1971 while (x) { x >>= 1; n++; }
1974 }
while ( jmax + m * n <= prec );
1975 if ( s < 0 ) jmax /= 2;
1977 for ( j = 1; j <= jmax; j++ ) {
1980 mpf_set_prec_raw(jm,xprec);
1981 mpf_set_prec_raw(jjm,xprec);
1984 mpf_div_ui(jjm,jm,(
unsigned long)j);
1985 mpf_pow_ui(jm,jjm,(
unsigned long)m);
1986 if ( s == -1 ) mpf_div_2exp(jjm,jm,2*(
unsigned long)j);
1987 else mpf_div_2exp(jjm,jm,(
unsigned long)j);
1988 mpf_add(sum,sum,jjm);
1990 mpf_clear(jjm); mpf_clear(jm);
1998void SingleTable(mpf_t *tabl,
int N,
int m,
int pow)
2015 long prec = mpf_get_default_prec();
2018 mpf_init(jm); mpf_init(jjm);
2019 if ( pow < 1 || pow > 2 ) {
2020 MLOCK(ErrorMessageLock);
2021 MesPrint(
"Wrong parameter pow in SingleTable: %d\n",pow);
2022 MUNLOCK(ErrorMessageLock);
2025 if ( m < 0 ) { m = -m; s = -1; }
2026 mpf_set_si(auxsum,0L);
2027 for ( j = N; j > 0; j-- ) {
2029 mpf_set_prec_raw(jm,prec-j);
2030 mpf_set_prec_raw(jjm,prec-j);
2033 mpf_div_ui(jjm,jm,(
unsigned long)j);
2034 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2035 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2036 if ( pow == 2 ) mpf_add(auxsum,auxsum,jjm);
2037 else if ( s == -1 && j%2 == 1 ) mpf_sub(auxsum,auxsum,jjm);
2038 else mpf_add(auxsum,auxsum,jjm);
2042 mpf_set(tabl[j],auxsum);
2044 mpf_clear(jjm); mpf_clear(jm);
2052void DoubleTable(mpf_t *tabout, mpf_t *tabin,
int N,
int m,
int pow)
2057 long prec = mpf_get_default_prec();
2061 mpf_init(jm); mpf_init(jjm);
2062 if ( pow < -1 || pow > 2 ) {
2063 MLOCK(ErrorMessageLock);
2064 MesPrint(
"Wrong parameter pow in DoubleTable: %d\n",pow);
2065 MUNLOCK(ErrorMessageLock);
2068 if ( m < 0 ) { m = -m; s = -1; }
2069 mpf_set_ui(auxsum,0L);
2070 for ( j = N; j > 0; j-- ) {
2072 mpf_set_prec_raw(jm,prec-j);
2073 mpf_set_prec_raw(jjm,prec-j);
2076 mpf_div_ui(jjm,jm,(
unsigned long)j);
2077 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2079 mpf_mul_2exp(jjm,jm,(
unsigned long)j);
2080 mpf_mul(jm,jjm,tabin[j+1]);
2082 else if ( pow > 0 ) {
2083 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2084 mpf_mul(jm,jjm,tabin[j+1]);
2087 mpf_mul(jm,jm,tabin[j+1]);
2089 if ( pow == 2 ) mpf_add(auxsum,auxsum,jm);
2090 else if ( s == -1 && j%2 == 1 ) mpf_sub(auxsum,auxsum,jm);
2091 else mpf_add(auxsum,auxsum,jm);
2095 mpf_set(tabout[j],auxsum);
2097 mpf_clear(jjm); mpf_clear(jm);
2105void EndTable(mpf_t sum, mpf_t *tabin,
int N,
int m,
int pow)
2109 long prec = mpf_get_default_prec();
2113 mpf_init(jm); mpf_init(jjm);
2114 if ( pow < -1 || pow > 2 ) {
2115 MLOCK(ErrorMessageLock);
2116 MesPrint(
"Wrong parameter pow in EndTable: %d\n",pow);
2117 MUNLOCK(ErrorMessageLock);
2120 if ( m < 0 ) { m = -m; s = -1; }
2122 for ( j = N; j > 0; j-- ) {
2124 mpf_set_prec_raw(jm,prec-j);
2125 mpf_set_prec_raw(jjm,prec-j);
2128 mpf_div_ui(jjm,jm,(
unsigned long)j);
2129 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2131 mpf_mul_2exp(jjm,jm,(
unsigned long)j);
2132 mpf_mul(jm,jjm,tabin[j+1]);
2134 else if ( pow > 0 ) {
2135 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2136 mpf_mul(jm,jjm,tabin[j+1]);
2139 mpf_mul(jm,jm,tabin[j+1]);
2141 if ( s == -1 && j%2 == 1 ) mpf_sub(sum,sum,jm);
2142 else mpf_add(sum,sum,jm);
2144 mpf_clear(jjm); mpf_clear(jm);
2152void deltaMZV(mpf_t result, WORD *indexes,
int depth)
2160 if ( indexes[0] == 1 ) {
2161 mpf_set(result,mpfdelta1);
2164 SimpleDelta(result,indexes[0]);
2166 else if ( depth == 2 ) {
2167 if ( indexes[0] == 1 && indexes[1] == 1 ) {
2168 mpf_pow_ui(result,mpfdelta1,2);
2169 mpf_div_2exp(result,result,1);
2172 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+1,indexes[0],1);
2173 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,indexes[1],0);
2176 else if ( depth > 2 ) {
2182 for ( d = 0; d < depth; d++ ) {
2183 if ( indexes[d] != 1 )
break;
2186 mpf_pow_ui(result,mpfdelta1,depth);
2187 for ( d = 2; d <= depth; d++ ) {
2188 mpf_div_ui(result,result,(
unsigned long)d);
2193 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,1);
2196 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,0);
2199 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,*indexes,0);
2202 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2203 AT.mpf_tab2 = (
void *)mpftab3;
2207 else if ( depth == 0 ) {
2208 mpf_set_ui(result,1L);
2219void deltaEuler(mpf_t result, WORD *indexes,
int depth)
2225 printf(
" deltaEuler(");
2226 for ( i = 0; i < depth; i++ ) {
2227 if ( i != 0 ) printf(
",");
2228 printf(
"%d",indexes[i]);
2233 SimpleDelta(result,indexes[0]);
2235 else if ( depth == 2 ) {
2236 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+1,indexes[0],1);
2237 m = indexes[1];
if ( indexes[0] < 0 ) m = -m;
2238 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,m,0);
2240 else if ( depth > 2 ) {
2244 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,1);
2246 m = *indexes;
if ( indexes[-1] < 0 ) m = -m;
2248 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,m,0);
2250 m = *indexes;
if ( indexes[-1] < 0 ) m = -m;
2252 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,m,0);
2255 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2256 AT.mpf_tab2 = (
void *)mpftab3;
2259 else if ( depth == 0 ) {
2260 mpf_set_ui(result,1L);
2263 gmp_printf(
"%.*Fe\n",40,result);
2275void deltaEulerC(mpf_t result, WORD *indexes,
int depth)
2281 printf(
" deltaEulerC(");
2282 for ( i = 0; i < depth; i++ ) {
2283 if ( i != 0 ) printf(
",");
2284 printf(
"%d",indexes[i]);
2288 mpf_set_ui(result,0);
2290 if ( indexes[0] == 0 ) {
2291 MLOCK(ErrorMessageLock);
2292 MesPrint(
"Illegal index in depth=1 deltaEulerC: %d\n",indexes[0]);
2293 MUNLOCK(ErrorMessageLock);
2296 if ( indexes[0] < 0 ) SimpleDeltaC(result,indexes[0]);
2297 else SimpleDelta(result,indexes[0]);
2299 else if ( depth == 2 ) {
2302 if ( m < 0 ) SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+depth,-m,2);
2303 else SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+depth, m,1);
2305 if ( m < 0 ) { m = -m; par = indexes[0] < 0 ? 0: 1; }
2306 else { par = indexes[0] < 0 ? -1: 0; }
2307 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,m,par);
2309 else if ( depth > 2 ) {
2314 ZeroTable(mpftab1,AC.DefaultPrecision+1);
2315 if ( m < 0 ) SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d+1,-m,2);
2316 else SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d+1, m,1);
2317 d--; indexes++; m = indexes[0];
2318 if ( m < 0 ) { m = -m; par = indexes[-1] < 0 ? 0: 1; }
2319 else { par = indexes[-1] < 0 ? -1: 0; }
2321 ZeroTable(mpftab2,AC.DefaultPrecision-AC.MaxWeight+d);
2322 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,m,par);
2323 d--; indexes++; m = indexes[0];
2324 if ( m < 0 ) { m = -m; par = indexes[-1] < 0 ? 0: 1; }
2325 else { par = indexes[-1] < 0 ? -1: 0; }
2327 mpf_set_ui(result,0);
2328 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,m,par);
2331 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2332 AT.mpf_tab2 = (
void *)mpftab3;
2335 else if ( depth == 0 ) {
2336 mpf_set_ui(result,1L);
2339 gmp_printf(
"%.*Fe\n",40,result);
2351void CalculateMZVhalf(mpf_t result, WORD *indexes,
int depth)
2355 MLOCK(ErrorMessageLock);
2356 MesPrint(
"Illegal depth in CalculateMZVhalf: %d",depth);
2357 MUNLOCK(ErrorMessageLock);
2360 for ( i = 0; i < depth; i++ ) {
2361 if ( indexes[i] <= 0 ) {
2362 MLOCK(ErrorMessageLock);
2363 MesPrint(
"Illegal index[%d] in CalculateMZVhalf: %d",i,indexes[i]);
2364 MUNLOCK(ErrorMessageLock);
2368 deltaMZV(result,indexes,depth);
2376void CalculateMZV(mpf_t result, WORD *indexes,
int depth)
2379 int num1, num2 = 0, i, j = 0;
2381 MLOCK(ErrorMessageLock);
2382 MesPrint(
"Illegal depth in CalculateMZV: %d",depth);
2383 MUNLOCK(ErrorMessageLock);
2386 if ( indexes[0] == 1 ) {
2387 MLOCK(ErrorMessageLock);
2388 MesPrint(
"Divergent MZV in CalculateMZV");
2389 MUNLOCK(ErrorMessageLock);
2393 for ( i = 0; i < depth; i++ ) {
2394 if ( indexes[i] <= 0 ) {
2395 MLOCK(ErrorMessageLock);
2396 MesPrint(
"Illegal index[%d] in CalculateMZV: %d",i,indexes[i]);
2397 MUNLOCK(ErrorMessageLock);
2400 AT.indi1[i] = indexes[i];
2402 num1 = depth; i = 0;
2403 deltaMZV(result,indexes,depth);
2405 if ( AT.indi1[0] > 1 ) {
2407 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2408 AT.indi2[0] = 1; num2++;
2412 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2414 if ( num1 == 0 )
break;
2416 deltaMZV(aux1,AT.indi1,num1);
2417 deltaMZV(aux2,AT.indi2,num2);
2418 mpf_mul(aux3,aux1,aux2);
2419 mpf_add(result,result,aux3);
2421 deltaMZV(aux3,AT.indi2,num2);
2422 mpf_add(result,result,aux3);
2447void CalculateEuler(mpf_t result, WORD *Zindexes,
int depth)
2450 int s1, num1, num2, i, j;
2452 WORD *indexes = AT.WorkPointer;
2453 for ( i = 0; i < depth; i++ ) indexes[i] = Zindexes[i];
2454 for ( i = 0; i < depth-1; i++ ) {
2455 if ( Zindexes[i] < 0 ) {
2456 for ( j = i+1; j < depth; j++ ) indexes[j] = -indexes[j];
2461 MLOCK(ErrorMessageLock);
2462 MesPrint(
"Illegal depth in CalculateEuler: %d\n",depth);
2463 MUNLOCK(ErrorMessageLock);
2466 if ( indexes[0] == 1 ) {
2467 MLOCK(ErrorMessageLock);
2468 MesPrint(
"Divergent Euler sum in CalculateEuler\n");
2469 MUNLOCK(ErrorMessageLock);
2472 for ( i = 0, j = 0; i < depth; i++ ) {
2473 if ( indexes[i] == 0 ) {
2474 MLOCK(ErrorMessageLock);
2475 MesPrint(
"Illegal index[%d] in CalculateEuler: %d\n",i,indexes[i]);
2476 MUNLOCK(ErrorMessageLock);
2479 if ( indexes[i] < 0 ) j = 1;
2480 AT.indi1[i] = indexes[i];
2483 CalculateMZV(result,indexes,depth);
2486 num1 = depth; AT.indi2[0] = 0; num2 = 0;
2487 deltaEuler(result,AT.indi1,depth);
2491 if ( AT.indi1[0] > 1 ) {
2493 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2494 AT.indi2[0] = 1; num2++;
2496 else if ( AT.indi1[0] < -1 ) {
2498 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2499 AT.indi2[0] = 1; num2++;
2501 else if ( AT.indi1[0] == -1 ) {
2502 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2503 AT.indi2[0] = -1; num2++;
2504 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2508 AT.indi2[0] = AT.indi2[0] < 0 ? AT.indi2[0]-1: AT.indi2[0]+1;
2509 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2512 if ( num1 == 0 )
break;
2513 deltaEuler(aux1,AT.indi1,num1);
2514 deltaEulerC(aux2,AT.indi2,num2);
2515 mpf_mul(aux3,aux1,aux2);
2516 if ( (depth+num1+num2+s1)%2 == 0 ) mpf_add(result,result,aux3);
2517 else mpf_sub(result,result,aux3);
2519 deltaEulerC(aux3,AT.indi2,num2);
2520 if ( (depth+num2+s1)%2 == 0 ) mpf_add(result,result,aux3);
2521 else mpf_sub(result,result,aux3);
2529int ExpandMZV(WORD *term, WORD level)
2541int ExpandEuler(WORD *term, WORD level)
2569int EvaluateEuler(PHEAD WORD *term, WORD level, WORD par)
2571 WORD *t, *tstop, *tt, *tnext, sumweight, depth, first = 1, *newterm, i;
2572 WORD *oldworkpointer = AT.WorkPointer, nsize, *indexes;
2574 tstop = term + *term; tstop -= ABS(tstop[-1]);
2575 if ( AT.WorkPointer < term+*term ) AT.WorkPointer = term + *term;
2580 while ( t < tstop ) {
2581 if ( ( *t == par ) || ( ( par == ALLMZVFUNCTIONS ) && (
2582 *t == MZV || *t == EULER || *t == MZVHALF ) ) ) {
2584 indexes = AT.WorkPointer;
2585 sumweight = 0; depth = 0;
2586 tnext = t + t[1]; tt = t + FUNHEAD;
2587 while ( tt < tnext ) {
2588 if ( *tt != -SNUMBER )
goto nextfun;
2589 if ( tt[1] == 0 )
goto nextfun;
2590 indexes[depth] = tt[1];
2591 sumweight += ABS(tt[1]); depth++;
2595 if ( depth == 0)
goto nextfun;
2596 if ( sumweight > AC.MaxWeight ) {
2597 MLOCK(ErrorMessageLock);
2598 MesPrint(
"Error: Weight of Euler/MZV sum greater than %d.",AC.MaxWeight);
2599 MesPrint(
"Please increase the maximum weight in %#startfloat.");
2600 MUNLOCK(ErrorMessageLock);
2606 AT.WorkPointer += depth;
2608 if ( *t == MZV ) CalculateMZV(aux4,indexes,depth);
2609 else if ( *t == EULER ) CalculateEuler(aux4,indexes,depth);
2610 else if ( *t == MZVHALF ) CalculateMZVhalf(aux4,indexes,depth);
2614 if ( *t == MZV ) CalculateMZV(aux5,indexes,depth);
2615 else if ( *t == EULER ) CalculateEuler(aux5,indexes,depth);
2616 else if ( *t == MZVHALF ) CalculateMZVhalf(aux5,indexes,depth);
2617 mpf_mul(aux4,aux4,aux5);
2624 if ( first == 1 )
return(
Generator(BHEAD term,level));
2630 nsize = term[*term-1];
2636 if ( tstop[0] != 1 ) {
2637 mpf_mul_ui(aux4,aux4,(ULONG)((UWORD)tstop[0]));
2639 if ( tstop[1] != 1 ) {
2640 mpf_div_ui(aux4,aux4,(ULONG)((UWORD)tstop[1]));
2644 RatToFloat(aux5,(UWORD *)tstop,nsize);
2645 mpf_mul(aux4,aux4,aux5);
2651 while ( t < tstop ) {
2652 if ( *t == FLOATFUN ) {
2653 UnpackFloat(aux5,t);
2654 mpf_mul(aux4,aux4,aux5);
2662 newterm = AT.WorkPointer;
2664 while ( t < tstop ) {
2665 if ( *t == 0 || *t == FLOATFUN ) t += t[1];
2667 i = t[1]; NCOPY(tt,t,i);
2672 *tt++ = 1; *tt++ = 1; *tt++ = 3;
2673 *newterm = tt-newterm;
2674 AT.WorkPointer = tt;
2675 retval =
Generator(BHEAD newterm,level);
2676 AT.WorkPointer = oldworkpointer;
2689int CoEvaluate(UBYTE *s)
2695 if ( AT.aux_ == 0 ) {
2696 MesPrint(
"&Illegal attempt to evaluate a function without activating floating point numbers.");
2697 MesPrint(
"&Forgotten %#startfloat instruction?");
2700 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2705 Add3Com(TYPEEVALUATE,ALLFUNCTIONS);
2709 Add3Com(TYPEEVALUATE,ALLMZVFUNCTIONS);
2714 while ( FG.cTable[*s] == 0 ) s++;
2715 if ( *s ==
'2' ) s++;
2716 if ( *s ==
'_' ) s++;
2721 if ( ( ( type = GetName(AC.varnames,subkey,&numfun,NOAUTO) ) != CFUNCTION )
2722 || ( functions[numfun].spec != 0 ) ) {
2724 if ( type == CSYMBOL ) {
2725 Add4Com(TYPEEVALUATE,SYMBOL,numfun);
2731 MesPrint(
"&%s should be a built in function that can be evaluated numerically.",s);
2735 switch ( numfun+FUNCTION ) {
2766 Add3Com(TYPEEVALUATE,numfun+FUNCTION);
2769 MesPrint(
"&%s should be a built in function that can be evaluated numerically.",s);
2775 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
int Generator(PHEAD WORD *, WORD)