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)
1148 int totnum = AM.totalnumberofthreads, id;
1150 totnum = totnum + GetNumberOfSortBots(totnum - 1);
1151 for (
id = 0;
id < totnum;
id++ ) {
1156 AB[id]->T.aux_ = (
void *)Malloc1(
sizeof(mpf_t)*8,
"AB[id]->T.aux_");
1157 a = (mpf_t *)AB[
id]->T.aux_;
1158 mpf_inits(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],(mpf_ptr)0);
1159 if ( AB[
id]->T.indi1 ) M_free(AB[
id]->T.indi1,
"indi1");
1160 AB[id]->T.indi1 = (WORD *)Malloc1(
sizeof(WORD)*AC.MaxWeight*2,
"indi1");
1161 AB[id]->T.indi2 = AB[id]->T.indi1 + AC.MaxWeight;
1164 AT.aux_ = (
void *)Malloc1(
sizeof(mpf_t)*8,
"AT.aux_");
1165 mpf_inits(aux1,aux2,aux3,aux4,aux5,auxjm,auxjjm,auxsum,(mpf_ptr)0);
1166 if ( AT.indi1 ) M_free(AT.indi1,
"indi1");
1167 AT.indi1 = (WORD *)Malloc1(
sizeof(WORD)*AC.MaxWeight*2,
"indi1");
1168 AT.indi2 = AT.indi1 + AC.MaxWeight;
1177void ClearMZVTables(
void)
1182 totnum = AM.totalnumberofthreads;
1183 for (
id = 0;
id < totnum;
id++ ) {
1184 if ( AB[
id]->T.mpf_tab1 ) {
1189 a = (mpf_t *)AB[
id]->T.mpf_tab1;
1190 for ( i = 0; i <=AC.DefaultPrecision; i++ ) {
1193 M_free(AB[
id]->T.mpf_tab1,
"mpftab1");
1194 AB[id]->T.mpf_tab1 = 0;
1196 if ( AB[
id]->T.mpf_tab2 ) {
1197 a = (mpf_t *)AB[
id]->T.mpf_tab2;
1198 for ( i = 0; i <=AC.DefaultPrecision; i++ ) {
1201 M_free(AB[
id]->T.mpf_tab2,
"mpftab2");
1202 AB[id]->T.mpf_tab2 = 0;
1205 totnum = totnum + GetNumberOfSortBots(totnum - 1);
1206 for (
id = 0;
id < totnum;
id++ ) {
1207 if ( AB[
id]->T.aux_ ) {
1208 a = (mpf_t *)AB[
id]->T.aux_;
1209 mpf_clears(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],(mpf_ptr)0);
1210 M_free(AB[
id]->T.aux_,
"AB[id]->T.aux_");
1213 if ( AB[
id]->T.indi1 ) { M_free(AB[
id]->T.indi1,
"indi1"); AB[id]->T.indi1 = 0; }
1217 if ( AT.mpf_tab1 ) {
1218 for ( i = 0; i <= AC.DefaultPrecision; i++ ) {
1219 mpf_clear(mpftab1[i]);
1221 M_free(AT.mpf_tab1,
"mpftab1");
1224 if ( AT.mpf_tab2 ) {
1225 for ( i = 0; i <= AC.DefaultPrecision; i++ ) {
1226 mpf_clear(mpftab2[i]);
1228 M_free(AT.mpf_tab2,
"mpftab2");
1232 mpf_clears(aux1,aux2,aux3,aux4,aux5,auxjm,auxjjm,auxsum,(mpf_ptr)0);
1233 M_free(AT.aux_,
"AT.aux_");
1236 if ( AT.indi1 ) { M_free(AT.indi1,
"indi1"); AT.indi1 = 0; }
1238 if ( AO.floatspace ) { M_free(AO.floatspace,
"floatspace"); AO.floatspace = 0;
1241 mpf_clear(mpfdelta1);
1242 M_free(AS.delta_1,
"delta1");
1252int CoToFloat(UBYTE *s)
1255 if ( AT.aux_ == 0 ) {
1256 MesPrint(
"&Illegal attempt to convert to float_ without activating floating point numbers.");
1257 MesPrint(
"&Forgotten %#startfloat instruction?");
1260 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1262 MesPrint(
"&Illegal argument(s) in ToFloat statement: '%s'",s);
1265 Add2Com(TYPETOFLOAT);
1274int CoToRat(UBYTE *s)
1277 if ( AT.aux_ == 0 ) {
1278 MesPrint(
"&Illegal attempt to convert from float_ without activating floating point numbers.");
1279 MesPrint(
"&Forgotten %#startfloat instruction?");
1282 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1284 MesPrint(
"&Illegal argument(s) in ToRat statement: '%s'",s);
1301int CoStrictRounding(UBYTE *s)
1306 if ( AT.aux_ == 0 ) {
1307 MesPrint(
"&Illegal attempt for strict rounding without activating floating point numbers.");
1308 MesPrint(
"&Forgotten %#startfloat instruction?");
1311 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1314 x = AC.DefaultPrecision - AC.MaxWeight - 1;
1317 else if ( FG.cTable[*s] == 1 ) {
1319 if ( tolower(*s) ==
'd' ) { base = 10; s++; }
1320 else if ( tolower(*s) ==
'b' ){ base = 2; s++; }
1326 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1331 MesPrint(
"&Illegal argument(s) in StrictRounding statement: '%s'",s);
1334 Add4Com(TYPESTRICTROUNDING,x,base);
1355 if ( AT.aux_ == 0 ) {
1356 MesPrint(
"&Illegal attempt to chop a float_ without activating floating point numbers.");
1357 MesPrint(
"&Forgotten %#startfloat instruction?");
1361 MesPrint(
"&Chop needs a number (float, rational or power) as an argument.");
1365 w = OldWork = AT.WorkPointer;
1369 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
1376 if ( FG.cTable[*s] == 1 || *s ==
'.' ) {
1378 ss = CheckFloat(s, &spec);
1386 ReadFloat((SBYTE *)s);
1393 if ( FG.cTable[*s] == 1 ) {
1397 while ( *s ==
' ' || *s ==
'\t' ) s++;
1399 if ( *s ==
'/' || *s ==
'^' ) {
1401 while ( *s ==
' ' || *s ==
'\t' ) s++;
1402 if ( *s ==
'-' ) { s++; pow = -1; }
1404 if ( FG.cTable[*s] == 1 ) {
1408 MesPrint(
"&Division by zero in chop statement.");
1412 mpf_div_ui(aux1, aux1,x);
1415 mpf_pow_ui(aux1,aux1,x);
1417 mpf_ui_div(aux1,(
unsigned long) 1, aux1);
1428 MesPrint(
"&Illegal argument(s) in Chop statement: '%s'.",s);
1431 AT.WorkPointer = OldWork;
1432 AT.WorkPointer[1] = w - AT.WorkPointer;
1433 AddNtoL(AT.WorkPointer[1],AT.WorkPointer);
1444int ToFloat(PHEAD WORD *term, WORD level)
1446 WORD *t, *tstop, nsize, nsign = 3;
1450 if ( t[-1] < 0 ) { nsign = -nsign; }
1451 if ( nsize == 3 && t[-2] == 1 && t[-3] == 1 ) {
1453 while ( t < tstop ) {
1454 if ( ( *t == FLOATFUN ) && ( t+t[1] == tstop ) ) {
1460 RatToFloat(aux4,(UWORD *)tstop,nsize);
1461 PackFloat(tstop,aux4);
1463 *tstop++ = 1; *tstop++ = 1; *tstop++ = nsign;
1464 *term = tstop - term;
1465 AT.WorkPointer = tstop;
1476int ToRat(PHEAD WORD *term, WORD level)
1478 WORD *tstop, *t, nsize, nsign, ncoef;
1482 tstop = term + *term; nsize = ABS(tstop[-1]);
1483 nsign = tstop[-1] < 0 ? -1: 1; tstop -= nsize;
1485 while ( t < tstop ) {
1486 if ( *t == FLOATFUN && t + t[1] == tstop && TestFloat(t) &&
1487 nsize == 3 && tstop[0] == 1 && tstop[1] == 1 )
break;
1495 UnpackFloat(aux4,t);
1497 if ( mpf_sgn(aux4) == 0 )
return(0);
1498 if ( FloatToRat((UWORD *)t,&ncoef,aux4) == 0 ) {
1500 if ( t[0] == 0 && t[1] == 1 && ncoef == 3 )
return(0);
1502 t[-1] = ncoef*nsign;
1516int StrictRounding(PHEAD WORD *term, WORD level, WORD prec, WORD base) {
1518 int sign,size,maxprec = AC.DefaultPrecision-AC.MaxWeight-1;
1520 if ( base == 2 && prec > maxprec ) {
1523 if ( base == 10 && prec > (
int)(maxprec*log10(2.0)) ) {
1524 prec = maxprec*log10(2.0);
1527 tstop = term + *term; size = ABS(tstop[-1]);
1528 sign = tstop[-1] < 0 ? -1: 1; tstop -= size;
1530 while ( t < tstop ) {
1531 if ( *t == FLOATFUN && t + t[1] == tstop && TestFloat(t) &&
1532 size == 3 && tstop[0] == 1 && tstop[1] == 1) {
1545 UnpackFloat(aux4,t);
1551 s = (
char *)AO.floatspace;
1553 mpf_get_str(s,&exp, base, prec, aux4);
1554 while ( *s != 0 ) s++;
1556 snprintf(s,AO.floatsize-(s-(
char *)AO.floatspace),
"%ld",exp);
1558 mpf_set_str(aux4,(
char *)AO.floatspace,-base);
1562 *t++ = 1; *t++ = 1; *t++ = 3*sign;
1578int Chop(PHEAD WORD *term, WORD level)
1580 WORD *tstop, *t, nsize, *threshold;
1581 CBUF *C = cbuf+AM.rbufnum;
1583 tstop = term + *term;
1584 nsize = ABS(tstop[-1]); tstop -= nsize;
1586 while ( t < tstop ) {
1587 if ( *t == FLOATFUN && t + t[1] == tstop && TestFloat(t) &&
1588 nsize == 3 && tstop[0] == 1 && tstop[1] == 1 )
break;
1593 threshold = C->
lhs[level];
1595 UnpackFloat(aux5, threshold);
1598 UnpackFloat(aux4, t);
1599 mpf_abs(aux4, aux4);
1602 if ( mpf_cmp(aux4, aux5) < 0 )
return(0);
1647int AddWithFloat(PHEAD WORD **ps1, WORD **ps2)
1651 WORD *coef1, *coef2, size1, size2, *fun1, *fun2, *fun3;
1652 WORD *s1,*s2,sign3,j,jj, *t1, *t2, i;
1655 coef1 = s1+*s1; size1 = coef1[-1]; coef1 -= ABS(coef1[-1]);
1656 coef2 = s2+*s2; size2 = coef2[-1]; coef2 -= ABS(coef2[-1]);
1657 if ( AT.SortFloatMode == 3 ) {
1658 fun1 = s1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1659 fun2 = s2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1660 UnpackFloat(aux1,fun1);
1661 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1662 UnpackFloat(aux2,fun2);
1663 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1665 else if ( AT.SortFloatMode == 1 ) {
1666 fun1 = s1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1667 UnpackFloat(aux1,fun1);
1668 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1670 RatToFloat(aux2,(UWORD *)coef2,size2);
1672 else if ( AT.SortFloatMode == 2 ) {
1673 fun2 = s2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1675 RatToFloat(aux1,(UWORD *)coef1,size1);
1676 UnpackFloat(aux2,fun2);
1677 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1681 MLOCK(ErrorMessageLock);
1682 MesPrint(
"!>Illegal value %d for AT.SortFloatMode in AddWithFloat.",AT.SortFloatMode);
1683 MUNLOCK(ErrorMessageLock);
1688 mpf_add(aux3,aux1,aux2);
1689 sign3 = mpf_sgn(aux3);
1690 if ( sign3 < 0 ) mpf_neg(aux3,aux3);
1691 fun3 = TermMalloc(
"AddWithFloat");
1692 PackFloat(fun3,aux3);
1703 if ( AT.SortFloatMode == 3 ) {
1704 if ( fun1[1] == fun3[1] ) {
1706 i = fun3[1]; t1 = fun1; t2 = fun3; NCOPY(t1,t2,i);
1707 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1708 *s1 = t1-s1;
goto Finished;
1710 else if ( fun2[1] == fun3[1] ) {
1712 i = fun3[1]; t1 = fun2; t2 = fun3; NCOPY(t1,t2,i);
1713 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1714 *s2 = t1-s2; *ps1 = s2;
goto Finished;
1716 else if ( fun1[1] >= fun3[1] )
goto Over1;
1717 else if ( fun2[1] >= fun3[1] )
goto Over2;
1719 else if ( AT.SortFloatMode == 1 ) {
1720 if ( fun1[1] >= fun3[1] )
goto Over1;
1721 else if ( fun3[1]+3 <= ABS(size2) )
goto Over2;
1723 else if ( AT.SortFloatMode == 2 ) {
1724 if ( fun2[1] >= fun3[1] )
goto Over2;
1725 else if ( fun3[1]+3 <= ABS(size1) )
goto Over1;
1732 if ( (S->sFill + j) >= S->sTop2 ) {
1738 for ( i = 0; i < jj; i++ ) *t1++ = s1[i];
1739 i = fun3[1]; s1 = fun3; NCOPY(t1,s1,i);
1740 *t1++ = 1; *t1++ = 1; *t1++ = sign3 < 0 ? -3: 3;
1746 TermFree(fun3,
"AddWithFloat");
1747 AT.SortFloatMode = 0;
1748 if ( **ps1 > AM.MaxTer/((LONG)(
sizeof(WORD))) ) {
1749 MLOCK(ErrorMessageLock);
1750 MesPrint(
"Term too complex after addition in sort. MaxTermSize = %10l",
1751 AM.MaxTer/
sizeof(WORD));
1752 MUNLOCK(ErrorMessageLock);
1755 if ( **ps1 > S->verbMaxTermSize ) S->verbMaxTermSize = **ps1;
1768int MergeWithFloat(PHEAD WORD **interm1, WORD **interm2)
1771 WORD *coef1, *coef2, size1, size2, *fun1, *fun2, *fun3, *tt;
1772 WORD sign3,jj, *t1, *t2, i, *term1 = *interm1, *term2 = *interm2;
1774 coef1 = term1+*term1; size1 = coef1[-1]; coef1 -= ABS(size1);
1775 coef2 = term2+*term2; size2 = coef2[-1]; coef2 -= ABS(size2);
1776 if ( AT.SortFloatMode == 3 ) {
1777 fun1 = term1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1778 fun2 = term2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1779 UnpackFloat(aux1,fun1);
1780 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1781 UnpackFloat(aux2,fun2);
1782 if ( size2 < 0 ) mpf_neg(aux2,aux2);
1784 else if ( AT.SortFloatMode == 1 ) {
1785 fun1 = term1+1;
while ( fun1 < coef1 && fun1[0] != FLOATFUN ) fun1 += fun1[1];
1786 UnpackFloat(aux1,fun1);
1787 if ( size1 < 0 ) mpf_neg(aux1,aux1);
1789 RatToFloat(aux2,(UWORD *)coef2,size2);
1791 else if ( AT.SortFloatMode == 2 ) {
1792 fun2 = term2+1;
while ( fun2 < coef2 && fun2[0] != FLOATFUN ) fun2 += fun2[1];
1794 RatToFloat(aux1,(UWORD *)coef1,size1);
1795 UnpackFloat(aux2,fun2);
1796 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);
1807 mpf_add(aux3,aux1,aux2);
1808 sign3 = mpf_sgn(aux3);
1812 if ( sign3 < 0 ) mpf_neg(aux3,aux3);
1813 fun3 = TermMalloc(
"MergeWithFloat");
1814 PackFloat(fun3,aux3);
1815 if ( AT.SortFloatMode == 3 ) {
1816 if ( fun1[1] + ABS(size1) == fun3[1] + 3 ) {
1817OnTopOf1: t1 = fun3; t2 = fun1;
1818 for ( i = 0; i < fun3[1]; i++ ) *t2++ = *t1++;
1819 *t2++ = 1; *t2++ = 1; *t2++ = sign3 < 0 ? -3: 3;
1822 else if ( fun1[1] + ABS(size1) > fun3[1] + 3 ) {
1823Shift1: t2 = term1 + *term1; tt = t2;
1824 *--t2 = sign3 < 0 ? -3: 3; *--t2 = 1; *--t2 = 1;
1825 t1 = fun3 + fun3[1];
for ( i = 0; i < fun3[1]; i++ ) *--t2 = *--t1;
1827 while ( t1 > term1 ) *--t2 = *--t1;
1828 *t2 = tt-t2; term1 = t2;
1832 jj = fun3[1]-fun1[1]+3-ABS(size1);
1833Over1: t2 = term1-jj; t1 = term1;
1834 while ( t1 < fun1 ) *t2++ = *t1++;
1837 for ( i = 0; i < fun3[1]; i++ ) *t2++ = fun3[i];
1838 *t2++ = 1; *t2++ = 1; *t2++ = sign3 < 0 ? -3: 3;
1842 else if ( AT.SortFloatMode == 1 ) {
1843 if ( fun1[1] + ABS(size1) == fun3[1] + 3 )
goto OnTopOf1;
1844 else if ( fun1[1] + ABS(size1) > fun3[1] + 3 )
goto Shift1;
1846 jj = fun3[1]-fun1[1]+3-ABS(size1);
1851 if ( fun3[1] + 3 == ABS(size1) )
goto OnTopOf1;
1852 else if ( fun3[1] + 3 < ABS(size1) )
goto Shift1;
1854 jj = fun3[1]+3-ABS(size1);
1859 TermFree(fun3,
"MergeWithFloat");
1860 AT.SortFloatMode = 0;
1881void SimpleDelta(mpf_t sum,
int m)
1884 long prec = AC.DefaultPrecision;
1885 unsigned long xprec = (
unsigned long)prec, x;
1888 mpf_init(jm); mpf_init(jjm);
1889 if ( m < 0 ) { s = -1; m = -m; }
1900 while ( x ) { x >>= 1; n++; }
1905 jmax = (int)((
int)xprec - (n-1)*m);
1910 if ( jmax < 0 ) jmax = 1;
1913 x = (
unsigned long)jmax;
1914 while (x) { x >>= 1; n++; }
1917 }
while ( jmax + m * n <= prec );
1919 for ( j = 1; j <= jmax; j++ ) {
1922 mpf_set_prec_raw(jm,xprec);
1923 mpf_set_prec_raw(jjm,xprec);
1926 mpf_div_ui(jjm,jm,(
unsigned long)j);
1927 mpf_pow_ui(jm,jjm,(
unsigned long)m);
1928 mpf_div_2exp(jjm,jm,(
unsigned long)j);
1929 if ( s == -1 && j%2 == 1 ) mpf_sub(sum,sum,jjm);
1930 else mpf_add(sum,sum,jjm);
1932 mpf_clear(jjm); mpf_clear(jm);
1940void SimpleDeltaC(mpf_t sum,
int m)
1943 long prec = AC.DefaultPrecision;
1944 unsigned long xprec = (
unsigned long)prec, x;
1947 mpf_init(jm); mpf_init(jjm);
1948 if ( m < 0 ) { s = -1; m = -m; }
1958 while ( x ) { x >>= 1; n++; }
1963 jmax = (int)((
int)xprec - (n-1)*m);
1968 if ( jmax < 0 ) jmax = 1;
1971 x = (
unsigned long)jmax;
1972 while (x) { x >>= 1; n++; }
1975 }
while ( jmax + m * n <= prec );
1976 if ( s < 0 ) jmax /= 2;
1978 for ( j = 1; j <= jmax; j++ ) {
1981 mpf_set_prec_raw(jm,xprec);
1982 mpf_set_prec_raw(jjm,xprec);
1985 mpf_div_ui(jjm,jm,(
unsigned long)j);
1986 mpf_pow_ui(jm,jjm,(
unsigned long)m);
1987 if ( s == -1 ) mpf_div_2exp(jjm,jm,2*(
unsigned long)j);
1988 else mpf_div_2exp(jjm,jm,(
unsigned long)j);
1989 mpf_add(sum,sum,jjm);
1991 mpf_clear(jjm); mpf_clear(jm);
1999void SingleTable(mpf_t *tabl,
int N,
int m,
int pow)
2016 long prec = mpf_get_default_prec();
2019 mpf_init(jm); mpf_init(jjm);
2020 if ( pow < 1 || pow > 2 ) {
2022 MLOCK(ErrorMessageLock);
2023 MesPrint(
"!>Wrong parameter pow in SingleTable: %d\n",pow);
2024 MUNLOCK(ErrorMessageLock);
2028 if ( m < 0 ) { m = -m; s = -1; }
2029 mpf_set_si(auxsum,0L);
2030 for ( j = N; j > 0; j-- ) {
2032 mpf_set_prec_raw(jm,prec-j);
2033 mpf_set_prec_raw(jjm,prec-j);
2036 mpf_div_ui(jjm,jm,(
unsigned long)j);
2037 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2038 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2039 if ( pow == 2 ) mpf_add(auxsum,auxsum,jjm);
2040 else if ( s == -1 && j%2 == 1 ) mpf_sub(auxsum,auxsum,jjm);
2041 else mpf_add(auxsum,auxsum,jjm);
2045 mpf_set(tabl[j],auxsum);
2047 mpf_clear(jjm); mpf_clear(jm);
2055void DoubleTable(mpf_t *tabout, mpf_t *tabin,
int N,
int m,
int pow)
2060 long prec = mpf_get_default_prec();
2064 mpf_init(jm); mpf_init(jjm);
2065 if ( pow < -1 || pow > 2 ) {
2067 MLOCK(ErrorMessageLock);
2068 MesPrint(
"!>Wrong parameter pow in DoubleTable: %d\n",pow);
2069 MUNLOCK(ErrorMessageLock);
2073 if ( m < 0 ) { m = -m; s = -1; }
2074 mpf_set_ui(auxsum,0L);
2075 for ( j = N; j > 0; j-- ) {
2077 mpf_set_prec_raw(jm,prec-j);
2078 mpf_set_prec_raw(jjm,prec-j);
2081 mpf_div_ui(jjm,jm,(
unsigned long)j);
2082 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2084 mpf_mul_2exp(jjm,jm,(
unsigned long)j);
2085 mpf_mul(jm,jjm,tabin[j+1]);
2087 else if ( pow > 0 ) {
2088 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2089 mpf_mul(jm,jjm,tabin[j+1]);
2092 mpf_mul(jm,jm,tabin[j+1]);
2094 if ( pow == 2 ) mpf_add(auxsum,auxsum,jm);
2095 else if ( s == -1 && j%2 == 1 ) mpf_sub(auxsum,auxsum,jm);
2096 else mpf_add(auxsum,auxsum,jm);
2100 mpf_set(tabout[j],auxsum);
2102 mpf_clear(jjm); mpf_clear(jm);
2110void EndTable(mpf_t sum, mpf_t *tabin,
int N,
int m,
int pow)
2114 long prec = mpf_get_default_prec();
2118 mpf_init(jm); mpf_init(jjm);
2119 if ( pow < -1 || pow > 2 ) {
2121 MLOCK(ErrorMessageLock);
2122 MesPrint(
"!>Wrong parameter pow in EndTable: %d\n",pow);
2123 MUNLOCK(ErrorMessageLock);
2127 if ( m < 0 ) { m = -m; s = -1; }
2129 for ( j = N; j > 0; j-- ) {
2131 mpf_set_prec_raw(jm,prec-j);
2132 mpf_set_prec_raw(jjm,prec-j);
2135 mpf_div_ui(jjm,jm,(
unsigned long)j);
2136 mpf_pow_ui(jm,jjm,(
unsigned long)m);
2138 mpf_mul_2exp(jjm,jm,(
unsigned long)j);
2139 mpf_mul(jm,jjm,tabin[j+1]);
2141 else if ( pow > 0 ) {
2142 mpf_div_2exp(jjm,jm,pow*(
unsigned long)j);
2143 mpf_mul(jm,jjm,tabin[j+1]);
2146 mpf_mul(jm,jm,tabin[j+1]);
2148 if ( s == -1 && j%2 == 1 ) mpf_sub(sum,sum,jm);
2149 else mpf_add(sum,sum,jm);
2151 mpf_clear(jjm); mpf_clear(jm);
2159void deltaMZV(mpf_t result, WORD *indexes,
int depth)
2167 if ( indexes[0] == 1 ) {
2168 mpf_set(result,mpfdelta1);
2171 SimpleDelta(result,indexes[0]);
2173 else if ( depth == 2 ) {
2174 if ( indexes[0] == 1 && indexes[1] == 1 ) {
2175 mpf_pow_ui(result,mpfdelta1,2);
2176 mpf_div_2exp(result,result,1);
2179 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+1,indexes[0],1);
2180 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,indexes[1],0);
2183 else if ( depth > 2 ) {
2189 for ( d = 0; d < depth; d++ ) {
2190 if ( indexes[d] != 1 )
break;
2193 mpf_pow_ui(result,mpfdelta1,depth);
2194 for ( d = 2; d <= depth; d++ ) {
2195 mpf_div_ui(result,result,(
unsigned long)d);
2200 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,1);
2203 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,0);
2206 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,*indexes,0);
2209 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2210 AT.mpf_tab2 = (
void *)mpftab3;
2214 else if ( depth == 0 ) {
2215 mpf_set_ui(result,1L);
2226void deltaEuler(mpf_t result, WORD *indexes,
int depth)
2232 printf(
" deltaEuler(");
2233 for ( i = 0; i < depth; i++ ) {
2234 if ( i != 0 ) printf(
",");
2235 printf(
"%d",indexes[i]);
2240 SimpleDelta(result,indexes[0]);
2242 else if ( depth == 2 ) {
2243 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+1,indexes[0],1);
2244 m = indexes[1];
if ( indexes[0] < 0 ) m = -m;
2245 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,m,0);
2247 else if ( depth > 2 ) {
2251 SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,*indexes,1);
2253 m = *indexes;
if ( indexes[-1] < 0 ) m = -m;
2255 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,m,0);
2257 m = *indexes;
if ( indexes[-1] < 0 ) m = -m;
2259 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,m,0);
2262 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2263 AT.mpf_tab2 = (
void *)mpftab3;
2266 else if ( depth == 0 ) {
2267 mpf_set_ui(result,1L);
2270 gmp_printf(
"%.*Fe\n",40,result);
2282void deltaEulerC(mpf_t result, WORD *indexes,
int depth)
2288 printf(
" deltaEulerC(");
2289 for ( i = 0; i < depth; i++ ) {
2290 if ( i != 0 ) printf(
",");
2291 printf(
"%d",indexes[i]);
2295 mpf_set_ui(result,0);
2297 if ( indexes[0] == 0 ) {
2298 MLOCK(ErrorMessageLock);
2299 MesPrint(
"Illegal index in depth=1 deltaEulerC: %d\n",indexes[0]);
2300 MUNLOCK(ErrorMessageLock);
2303 if ( indexes[0] < 0 ) SimpleDeltaC(result,indexes[0]);
2304 else SimpleDelta(result,indexes[0]);
2306 else if ( depth == 2 ) {
2309 if ( m < 0 ) SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+depth,-m,2);
2310 else SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+depth, m,1);
2312 if ( m < 0 ) { m = -m; par = indexes[0] < 0 ? 0: 1; }
2313 else { par = indexes[0] < 0 ? -1: 0; }
2314 EndTable(result,mpftab1,AC.DefaultPrecision-AC.MaxWeight,m,par);
2316 else if ( depth > 2 ) {
2321 ZeroTable(mpftab1,AC.DefaultPrecision+1);
2322 if ( m < 0 ) SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d+1,-m,2);
2323 else SingleTable(mpftab1,AC.DefaultPrecision-AC.MaxWeight+d+1, m,1);
2324 d--; indexes++; m = indexes[0];
2325 if ( m < 0 ) { m = -m; par = indexes[-1] < 0 ? 0: 1; }
2326 else { par = indexes[-1] < 0 ? -1: 0; }
2328 ZeroTable(mpftab2,AC.DefaultPrecision-AC.MaxWeight+d);
2329 DoubleTable(mpftab2,mpftab1,AC.DefaultPrecision-AC.MaxWeight+d,m,par);
2330 d--; indexes++; m = indexes[0];
2331 if ( m < 0 ) { m = -m; par = indexes[-1] < 0 ? 0: 1; }
2332 else { par = indexes[-1] < 0 ? -1: 0; }
2334 mpf_set_ui(result,0);
2335 EndTable(result,mpftab2,AC.DefaultPrecision-AC.MaxWeight,m,par);
2338 mpftab3 = (mpf_t *)AT.mpf_tab1; AT.mpf_tab1 = AT.mpf_tab2;
2339 AT.mpf_tab2 = (
void *)mpftab3;
2342 else if ( depth == 0 ) {
2343 mpf_set_ui(result,1L);
2346 gmp_printf(
"%.*Fe\n",40,result);
2358void CalculateMZVhalf(mpf_t result, WORD *indexes,
int depth)
2362 MLOCK(ErrorMessageLock);
2363 MesPrint(
"Illegal depth in CalculateMZVhalf: %d",depth);
2364 MUNLOCK(ErrorMessageLock);
2367 for ( i = 0; i < depth; i++ ) {
2368 if ( indexes[i] <= 0 ) {
2369 MLOCK(ErrorMessageLock);
2370 MesPrint(
"Illegal index[%d] in CalculateMZVhalf: %d",i,indexes[i]);
2371 MUNLOCK(ErrorMessageLock);
2375 deltaMZV(result,indexes,depth);
2383void CalculateMZV(mpf_t result, WORD *indexes,
int depth)
2386 int num1, num2 = 0, i, j = 0;
2388 MLOCK(ErrorMessageLock);
2389 MesPrint(
"Illegal depth in CalculateMZV: %d",depth);
2390 MUNLOCK(ErrorMessageLock);
2393 if ( indexes[0] == 1 ) {
2394 MLOCK(ErrorMessageLock);
2395 MesPrint(
"Divergent MZV in CalculateMZV");
2396 MUNLOCK(ErrorMessageLock);
2400 for ( i = 0; i < depth; i++ ) {
2401 if ( indexes[i] <= 0 ) {
2402 MLOCK(ErrorMessageLock);
2403 MesPrint(
"Illegal index[%d] in CalculateMZV: %d",i,indexes[i]);
2404 MUNLOCK(ErrorMessageLock);
2407 AT.indi1[i] = indexes[i];
2409 num1 = depth; i = 0;
2410 deltaMZV(result,indexes,depth);
2412 if ( AT.indi1[0] > 1 ) {
2414 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2415 AT.indi2[0] = 1; num2++;
2419 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2421 if ( num1 == 0 )
break;
2423 deltaMZV(aux1,AT.indi1,num1);
2424 deltaMZV(aux2,AT.indi2,num2);
2425 mpf_mul(aux3,aux1,aux2);
2426 mpf_add(result,result,aux3);
2428 deltaMZV(aux3,AT.indi2,num2);
2429 mpf_add(result,result,aux3);
2454void CalculateEuler(mpf_t result, WORD *Zindexes,
int depth)
2457 int s1, num1, num2, i, j;
2459 WORD *indexes = AT.WorkPointer;
2460 for ( i = 0; i < depth; i++ ) indexes[i] = Zindexes[i];
2461 for ( i = 0; i < depth-1; i++ ) {
2462 if ( Zindexes[i] < 0 ) {
2463 for ( j = i+1; j < depth; j++ ) indexes[j] = -indexes[j];
2468 MLOCK(ErrorMessageLock);
2469 MesPrint(
"Illegal depth in CalculateEuler: %d\n",depth);
2470 MUNLOCK(ErrorMessageLock);
2473 if ( indexes[0] == 1 ) {
2474 MLOCK(ErrorMessageLock);
2475 MesPrint(
"Divergent Euler sum in CalculateEuler\n");
2476 MUNLOCK(ErrorMessageLock);
2479 for ( i = 0, j = 0; i < depth; i++ ) {
2480 if ( indexes[i] == 0 ) {
2481 MLOCK(ErrorMessageLock);
2482 MesPrint(
"Illegal index[%d] in CalculateEuler: %d\n",i,indexes[i]);
2483 MUNLOCK(ErrorMessageLock);
2486 if ( indexes[i] < 0 ) j = 1;
2487 AT.indi1[i] = indexes[i];
2490 CalculateMZV(result,indexes,depth);
2493 num1 = depth; AT.indi2[0] = 0; num2 = 0;
2494 deltaEuler(result,AT.indi1,depth);
2498 if ( AT.indi1[0] > 1 ) {
2500 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2501 AT.indi2[0] = 1; num2++;
2503 else if ( AT.indi1[0] < -1 ) {
2505 for ( j = num2; j > 0; j-- ) AT.indi2[j] = AT.indi2[j-1];
2506 AT.indi2[0] = 1; num2++;
2508 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++;
2511 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2515 AT.indi2[0] = AT.indi2[0] < 0 ? AT.indi2[0]-1: AT.indi2[0]+1;
2516 for ( j = 1; j < num1; j++ ) AT.indi1[j-1] = AT.indi1[j];
2519 if ( num1 == 0 )
break;
2520 deltaEuler(aux1,AT.indi1,num1);
2521 deltaEulerC(aux2,AT.indi2,num2);
2522 mpf_mul(aux3,aux1,aux2);
2523 if ( (depth+num1+num2+s1)%2 == 0 ) mpf_add(result,result,aux3);
2524 else mpf_sub(result,result,aux3);
2526 deltaEulerC(aux3,AT.indi2,num2);
2527 if ( (depth+num2+s1)%2 == 0 ) mpf_add(result,result,aux3);
2528 else mpf_sub(result,result,aux3);
2536int ExpandMZV(WORD *term, WORD level)
2548int ExpandEuler(WORD *term, WORD level)
2576int EvaluateEuler(PHEAD WORD *term, WORD level, WORD par)
2578 WORD *t, *tstop, *tt, *tnext, sumweight, depth, first = 1, *newterm, i;
2579 WORD *oldworkpointer = AT.WorkPointer, nsize, *indexes;
2581 tstop = term + *term; tstop -= ABS(tstop[-1]);
2582 if ( AT.WorkPointer < term+*term ) AT.WorkPointer = term + *term;
2587 while ( t < tstop ) {
2588 if ( ( *t == par ) || ( ( par == ALLMZVFUNCTIONS ) && (
2589 *t == MZV || *t == EULER || *t == MZVHALF ) ) ) {
2591 indexes = AT.WorkPointer;
2592 sumweight = 0; depth = 0;
2593 tnext = t + t[1]; tt = t + FUNHEAD;
2594 while ( tt < tnext ) {
2595 if ( *tt != -SNUMBER )
goto nextfun;
2596 if ( tt[1] == 0 )
goto nextfun;
2597 indexes[depth] = tt[1];
2598 sumweight += ABS(tt[1]); depth++;
2602 if ( depth == 0)
goto nextfun;
2603 if ( sumweight > AC.MaxWeight ) {
2604 MLOCK(ErrorMessageLock);
2605 MesPrint(
"Error: Weight of Euler/MZV sum greater than %d.",AC.MaxWeight);
2606 MesPrint(
"Please increase the maximum weight in %#startfloat.");
2607 MUNLOCK(ErrorMessageLock);
2613 AT.WorkPointer += depth;
2615 if ( *t == MZV ) CalculateMZV(aux4,indexes,depth);
2616 else if ( *t == EULER ) CalculateEuler(aux4,indexes,depth);
2617 else if ( *t == MZVHALF ) CalculateMZVhalf(aux4,indexes,depth);
2621 if ( *t == MZV ) CalculateMZV(aux5,indexes,depth);
2622 else if ( *t == EULER ) CalculateEuler(aux5,indexes,depth);
2623 else if ( *t == MZVHALF ) CalculateMZVhalf(aux5,indexes,depth);
2624 mpf_mul(aux4,aux4,aux5);
2631 if ( first == 1 )
return(
Generator(BHEAD term,level));
2637 nsize = term[*term-1];
2643 if ( tstop[0] != 1 ) {
2644 mpf_mul_ui(aux4,aux4,(ULONG)((UWORD)tstop[0]));
2646 if ( tstop[1] != 1 ) {
2647 mpf_div_ui(aux4,aux4,(ULONG)((UWORD)tstop[1]));
2651 RatToFloat(aux5,(UWORD *)tstop,nsize);
2652 mpf_mul(aux4,aux4,aux5);
2658 while ( t < tstop ) {
2659 if ( *t == FLOATFUN ) {
2660 UnpackFloat(aux5,t);
2661 mpf_mul(aux4,aux4,aux5);
2669 newterm = AT.WorkPointer;
2671 while ( t < tstop ) {
2672 if ( *t == 0 || *t == FLOATFUN ) t += t[1];
2674 i = t[1]; NCOPY(tt,t,i);
2679 *tt++ = 1; *tt++ = 1; *tt++ = 3;
2680 *newterm = tt-newterm;
2681 AT.WorkPointer = tt;
2682 retval =
Generator(BHEAD newterm,level);
2683 AT.WorkPointer = oldworkpointer;
2696int CoEvaluate(UBYTE *s)
2702 if ( AT.aux_ == 0 ) {
2703 MesPrint(
"&Illegal attempt to evaluate a function without activating floating point numbers.");
2704 MesPrint(
"&Forgotten %#startfloat instruction?");
2707 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
2712 Add3Com(TYPEEVALUATE,ALLFUNCTIONS);
2716 Add3Com(TYPEEVALUATE,ALLMZVFUNCTIONS);
2721 while ( FG.cTable[*s] == 0 ) s++;
2722 if ( *s ==
'2' ) s++;
2723 if ( *s ==
'_' ) s++;
2728 if ( ( ( type = GetName(AC.varnames,subkey,&numfun,NOAUTO) ) != CFUNCTION )
2729 || ( functions[numfun].spec != 0 ) ) {
2731 if ( type == CSYMBOL ) {
2732 Add4Com(TYPEEVALUATE,SYMBOL,numfun);
2738 MesPrint(
"&%s should be a built in function that can be evaluated numerically.",s);
2742 switch ( numfun+FUNCTION ) {
2773 Add3Com(TYPEEVALUATE,numfun+FUNCTION);
2776 MesPrint(
"&%s should be a built in function that can be evaluated numerically.",s);
2782 while ( *s ==
' ' || *s ==
',' || *s ==
'\t' ) s++;
int Generator(PHEAD WORD *, WORD)