45int PackFloat(WORD *,mpf_t);
46int UnpackFloat(mpf_t, WORD *);
47void RatToFloat(mpf_t result, UWORD *formrat,
int ratsize);
55int CompareFunctions(WORD *fleft,WORD *fright)
58 if ( AC.properorderflag ) {
59 if ( ( *fleft >= (FUNCTION+WILDOFFSET)
60 && functions[*fleft-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION )
61 || ( *fleft >= FUNCTION && *fleft < (FUNCTION + WILDOFFSET)
62 && functions[*fleft-FUNCTION].spec >= TENSORFUNCTION ) ) {}
64 WORD *s1, *s2, *ss1, *ss2;
65 s1 = fleft+FUNHEAD; s2 = fright+FUNHEAD;
66 ss1 = fleft + fleft[1]; ss2 = fright + fright[1];
67 while ( s1 < ss1 && s2 < ss2 ) {
69 if ( k > 0 )
return(1);
70 if ( k < 0 )
return(0);
74 if ( s1 < ss1 )
return(1);
77 k = fleft[1] - FUNHEAD;
78 kk = fright[1] - FUNHEAD;
81 while ( k > 0 && kk > 0 ) {
82 if ( *fleft < *fright )
return(0);
83 else if ( *fleft++ > *fright++ )
return(1);
86 if ( k > 0 )
return(1);
90 k = fleft[1] - FUNHEAD;
91 kk = fright[1] - FUNHEAD;
94 while ( k > 0 && kk > 0 ) {
95 if ( *fleft < *fright )
return(0);
96 else if ( *fleft++ > *fright++ )
return(1);
99 if ( k > 0 )
return(1);
119int Commute(WORD *fleft, WORD *fright)
122 if ( *fleft == DOLLAREXPRESSION || *fright == DOLLAREXPRESSION )
return(0);
123 fun1 = ABS(*fleft); fun2 = ABS(*fright);
124 if ( *fleft >= GAMMA && *fleft <= GAMMASEVEN
125 && *fright >= GAMMA && *fright <= GAMMASEVEN ) {
126 if ( fleft[FUNHEAD] < AM.OffsetIndex && fleft[FUNHEAD] > fright[FUNHEAD] )
130 if ( fun1 >= WILDOFFSET ) fun1 -= WILDOFFSET;
131 if ( fun2 >= WILDOFFSET ) fun2 -= WILDOFFSET;
132 if ( ( ( functions[fun1-FUNCTION].flags & COULDCOMMUTE ) == 0 )
133 || ( ( functions[fun2-FUNCTION].flags & COULDCOMMUTE ) == 0 ) )
return(0);
138 if ( AC.CommuteInSet == 0 )
return(0);
153 if ( fun1 >= fun2 ) {
154 WORD *group = AC.CommuteInSet, *g1, *g2, *g3;
155 while ( *group > 0 ) {
159 if ( *g1 == fun1 || ( fun1 <= GAMMASEVEN && fun1 >= GAMMA
160 && *g1 <= GAMMASEVEN && *g1 >= GAMMA ) ) {
163 if ( g1 != g2 && ( *g2 == fun2 ||
164 ( fun2 <= GAMMASEVEN && fun2 >= GAMMA
165 && *g2 <= GAMMASEVEN && *g2 >= GAMMA ) ) ) {
166 if ( fun1 != fun2 )
return(1);
167 if ( *fleft < 0 )
return(0);
168 if ( *fright < 0 )
return(1);
169 return(CompareFunctions(fleft,fright));
193int Normalize(PHEAD WORD *term)
199 WORD *t, *m, *r, i, j, k, l, nsym, *ss, *tt, *u;
200 WORD shortnum, stype;
201 WORD *stop, *to = 0, *from = 0;
203 WORD *ppsym, *ppvec, *ppdot, *ppdel;
204 WORD nvec, ndot, ndel, nind, neps, nden, ncom, nnco, ncon;
208 if ( AT.NormDepth > 2 ) {
213 if ( AT.NormDepth > AT.NormDataSize ) {
214 NORMDATA **top = AT.NormData + AT.NormDataSize;
215 DoubleBuffer((
void **)&(AT.NormData), (
void **)&(top),
216 sizeof(*AT.NormData),
"double NormData pointers");
217 AT.NormDataSize *= 2;
218 for ( LONG i = AT.NormDepth-1; i < AT.NormDataSize; i++ ) {
219 AT.NormData[i] = NULL;
222 if ( AT.NormData[AT.NormDepth-1] == NULL ) {
223 AT.NormData[AT.NormDepth-1] = AllocNormData();
226 WORD *psym = AT.NormData[AT.NormDepth-1]->psym;
227 WORD *pvec = AT.NormData[AT.NormDepth-1]->pvec;
228 WORD *pdot = AT.NormData[AT.NormDepth-1]->pdot;
229 WORD *pdel = AT.NormData[AT.NormDepth-1]->pdel;
230 WORD *pind = AT.NormData[AT.NormDepth-1]->pind;
231 WORD **peps = AT.NormData[AT.NormDepth-1]->peps;
232 WORD **pden = AT.NormData[AT.NormDepth-1]->pden;
233 WORD **pcom = AT.NormData[AT.NormDepth-1]->pcom;
234 WORD **pnco = AT.NormData[AT.NormDepth-1]->pnco;
235 WORD **pcon = AT.NormData[AT.NormDepth-1]->pcon;
238 WORD *n_llnum, *lnum, nnum;
239 WORD *termout, oldtoprhs = 0, subtype;
240 WORD ReplaceType, ReplaceVeto = 0, didcontr;
244 CBUF *C = cbuf+AT.ebufnum;
245 WORD *ANsc = 0, *ANsm = 0, *ANsr = 0, PolyFunMode;
248 WORD *firstfloat = 0;
250 LONG oldcpointer = 0, x;
251 n_coef = TermMalloc(
"NormCoef");
252 n_llnum = TermMalloc(
"n_llnum");
263 if ( AT.SS == AT.S0 ) {
264 if ( *term > AT.SS->verbMaxTermSize ) {
265 AT.SS->verbMaxTermSize = *term;
275 TermFree(n_coef,
"NormCoef");
276 TermFree(n_llnum,
"n_llnum");
286 termout = AT.WorkPointer;
287 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
288 fillsetexp = termout+1;
289 AN.PolyNormFlag = 0; PolyFunMode = AN.PolyFunTodo;
297 nsym = nvec = ndot = ndel = neps = nden =
298 nind = ncom = nnco = ncon = 0;
317 if ( *t <= DENOMINATORSYMBOL && *t >= COEFFSYMBOL ) {
323 if ( AN.cTerm ) m = AN.cTerm;
326 ncoef = REDLENG(ncoef);
327 if ( *t == COEFFSYMBOL ) {
329 nnum = REDLENG(m[-1]);
333 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
334 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
340 if ( DivRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
341 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
349 if ( *t == NUMERATORSYMBOL ) { m -= nnum + 1; }
351 while ( *m == 0 && nnum > 1 ) { m--; nnum--; }
353 if ( i < 0 && *t == NUMERATORSYMBOL ) nnum = -nnum;
357 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)m,nnum) )
364 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)m,nnum) )
370 ncoef = INCLENG(ncoef);
374 else if ( *t == DIMENSIONSYMBOL ) {
375 if ( AN.cTerm ) m = AN.cTerm;
377 k = DimensionTerm(m);
378 if ( k == 0 )
goto NormZero;
379 if ( k == MAXPOSITIVE ) {
380 MLOCK(ErrorMessageLock);
381 MesPrint(
"Dimension_ is undefined in term %t");
382 MUNLOCK(ErrorMessageLock);
385 if ( k == -MAXPOSITIVE ) {
386 MLOCK(ErrorMessageLock);
387 MesPrint(
"Dimension_ out of range in term %t");
388 MUNLOCK(ErrorMessageLock);
391 if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
392 else { *((UWORD *)lnum) = -k; nnum = -1; }
393 ncoef = REDLENG(ncoef);
394 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
395 ncoef = INCLENG(ncoef);
399 if ( ( *t >= MAXPOWER && *t < 2*MAXPOWER )
400 || ( *t < -MAXPOWER && *t > -2*MAXPOWER ) ) {
407 if ( t[1] & 1 ) ncoef = -ncoef;
409 else if ( *t == MAXPOWER ) {
410 if ( t[1] > 0 )
goto NormZero;
418 if ( t[1] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[1]))) )
420 ncoef = REDLENG(ncoef);
422 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
425 else if ( t[1] > 0 ) {
426 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
429 ncoef = INCLENG(ncoef);
436 if ( ( *t <= NumSymbols && *t > -MAXPOWER )
437 && ( symbols[*t].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
438 if ( t[1] <= 2*MAXPOWER && t[1] >= -2*MAXPOWER ) {
439 t[1] %= symbols[*t].maxpower;
440 if ( t[1] < 0 ) t[1] += symbols[*t].maxpower;
441 if ( ( symbols[*t].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
442 if ( ( ( symbols[*t].maxpower & 1 ) == 0 ) &&
443 ( t[1] >= symbols[*t].maxpower/2 ) ) {
444 t[1] -= symbols[*t].maxpower/2; ncoef = -ncoef;
447 if ( t[1] == 0 ) { t += 2;
goto NextSymbol; }
456 if ( *t > 2*MAXPOWER || *t < -2*MAXPOWER
457 || *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
458 MLOCK(ErrorMessageLock);
459 MesPrint(
"Illegal wildcard power combination.");
460 MUNLOCK(ErrorMessageLock);
464 if ( ( t[-1] <= NumSymbols && t[-1] > -MAXPOWER )
465 && ( symbols[t[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
466 *m %= symbols[t[-1]].maxpower;
467 if ( *m < 0 ) *m += symbols[t[-1]].maxpower;
468 if ( ( symbols[t[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
469 if ( ( ( symbols[t[-1]].maxpower & 1 ) == 0 ) &&
470 ( *m >= symbols[t[-1]].maxpower/2 ) ) {
471 *m -= symbols[t[-1]].maxpower/2; ncoef = -ncoef;
475 if ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
476 MLOCK(ErrorMessageLock);
477 MesPrint(
"Power overflow during normalization");
478 MUNLOCK(ErrorMessageLock);
484 { *m = m[2]; m++; *m = m[2]; m++; i++; }
491 }
while ( *t < *m && --i > 0 );
494 { m--; m[2] = *m; m--; m[2] = *m; i++; }
506 if ( t[0] == AM.vectorzero )
goto NormZero;
507 if ( t[1] == FUNNYVEC ) {
511 else if ( t[1] < 0 ) {
512 if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
514 if ( t[1] == AM.vectorzero )
goto NormZero;
515 *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++;
518 else { *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2; }
524 if ( t[2] == 0 ) t += 3;
525 else if ( ndot > 0 && t[0] == ppdot[-3]
526 && t[1] == ppdot[-2] ) {
529 if ( ppdot[-1] == 0 ) { ppdot -= 3; ndot--; }
531 else if ( t[0] == AM.vectorzero || t[1] == AM.vectorzero ) {
532 if ( t[2] > 0 )
goto NormZero;
536 *ppdot++ = *t++; *ppdot++ = *t++;
537 *ppdot++ = *t++; ndot++;
544 if ( WildFill(BHEAD termout,term,AT.dummysubexp) < 0 )
goto FromNorm;
546 t = termout; m = term;
549 case DOLLAREXPRESSION :
556 if ( AR.Eside != LHSIDE ) {
559 int nummodopt, ptype = -1;
560 if ( AS.MultiThreaded ) {
561 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
562 if ( t[2] == ModOptdollars[nummodopt].number )
break;
564 if ( nummodopt < NumModOptdollars ) {
565 ptype = ModOptdollars[nummodopt].type;
566 if ( DollarLocalCopy(ptype) ) {
567 d = ModOptdollars[nummodopt].dstruct+AT.identity;
570 LOCK(d->pthreadslock);
575 if ( d->type == DOLZERO ) {
577 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
579 if ( t[3] == 0 )
goto NormZZ;
580 if ( t[3] < 0 )
goto NormInf;
583 else if ( d->type == DOLNUMBER ) {
586 nnum = d->where[nnum-1];
587 if ( nnum < 0 ) { ncoef = -ncoef; nnum = -nnum; }
589 for ( i = 1; i <= nnum; i++ ) lnum[i-1] = d->where[i];
591 if ( nnum == 0 || ( nnum == 1 && lnum[0] == 0 ) ) {
593 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
595 if ( t[3] < 0 )
goto NormInf;
596 else if ( t[3] == 0 )
goto NormZZ;
599 if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) )
goto FromNorm;
600 ncoef = REDLENG(ncoef);
602 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
604 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
609 else if ( t[3] > 0 ) {
610 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
612 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
617 ncoef = INCLENG(ncoef);
619 else if ( d->type == DOLINDEX ) {
620 if ( d->index == 0 ) {
622 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
626 if ( d->index != NOINDEX ) pind[nind++] = d->index;
628 else if ( d->type == DOLTERMS ) {
629 if ( t[3] >= MAXPOWER || t[3] <= -MAXPOWER ) {
630 if ( d->where[0] == 0 )
goto NormZero;
631 if ( d->where[d->where[0]] != 0 ) {
633 MLOCK(ErrorMessageLock);
634 MesPrint(
"!!!Illegal $ expansion with wildcard power!!!");
635 MUNLOCK(ErrorMessageLock);
642 { WORD *td, *tdstop, dj;
644 tdstop = d->where+d->where[0];
645 if ( tdstop[-1] != 3 || tdstop[-2] != 1
646 || tdstop[-3] != 1 )
goto IllDollarExp;
648 if ( td >= tdstop )
goto IllDollarExp;
649 while ( td < tdstop ) {
650 if ( *td == SYMBOL ) {
651 for ( dj = 2; dj < td[1]; dj += 2 ) {
652 if ( td[dj+1] == 1 ) {
657 else if ( td[dj+1] == -1 ) {
662 else goto IllDollarExp;
665 else if ( *td == DOTPRODUCT ) {
666 for ( dj = 2; dj < td[1]; dj += 3 ) {
667 if ( td[dj+2] == 1 ) {
673 else if ( td[dj+2] == -1 ) {
679 else goto IllDollarExp;
682 else goto IllDollarExp;
689 t[0] = SUBEXPRESSION;
693 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
700 if ( *t == DOLLAREXPRESSION ) {
702 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
706 if ( AS.MultiThreaded ) {
707 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
708 if ( t[2] == ModOptdollars[nummodopt].number )
break;
710 if ( nummodopt < NumModOptdollars ) {
711 ptype = ModOptdollars[nummodopt].type;
712 if ( DollarLocalCopy(ptype) ) {
713 d = ModOptdollars[nummodopt].dstruct+AT.identity;
716 LOCK(d->pthreadslock);
721 if ( d->type == DOLTERMS ) {
722 t[0] = SUBEXPRESSION;
729 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
735 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
737 MLOCK(ErrorMessageLock);
738 MesPrint(
"!!!This $ variation has not been implemented yet!!!");
739 MUNLOCK(ErrorMessageLock);
743 if ( ptype > 0 && ! DollarLocalCopy(ptype) ) { UNLOCK(d->pthreadslock); }
759 if ( *t == SUMMEDIND ) {
760 if ( t[1] < -NMIN4SHIFT ) {
761 k = -t[1]-NMIN4SHIFT;
762 k = ExtraSymbol(k,1,nsym,ppsym,&ncoef);
766 else if ( t[1] == 0 )
goto NormZero;
776 ncoef = REDLENG(ncoef);
777 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
779 ncoef = INCLENG(ncoef);
783 else if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
784 else if ( *t == EMPTYINDEX && t[1] == EMPTYINDEX ) {
785 *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2;
789 *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++;
792 *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2;
797 *ppvec++ = t[1]; *ppvec++ = *t; t+=2; nvec += 2;
799 else { *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2; }
807 if ( t[FUNHEAD] == -SNUMBER && t[1] == FUNHEAD+2
808 && t[FUNHEAD+1] >= 0 ) {
809 if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
812 ncoef = REDLENG(ncoef);
813 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
814 ncoef = INCLENG(ncoef);
816 else pcom[ncom++] = t;
818 case BERNOULLIFUNCTION :
822 if ( ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 )
823 && ( t[1] == FUNHEAD+2 || ( t[1] == FUNHEAD+4 &&
824 t[FUNHEAD+2] == -SNUMBER && ABS(t[FUNHEAD+3]) == 1 ) ) ) {
826 if ( Bernoulli(t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
828 if ( nnum == 0 )
goto NormZero;
829 inum = nnum;
if ( inum < 0 ) inum = -inum;
832 while ( lnum[mnum-1] == 0 ) mnum--;
833 if ( nnum < 0 ) mnum = -mnum;
834 ncoef = REDLENG(ncoef);
835 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,mnum) )
goto FromNorm;
837 while ( lnum[inum+mnum-1] == 0 ) mnum--;
838 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(lnum+inum),mnum) )
goto FromNorm;
839 ncoef = INCLENG(ncoef);
840 if ( t[1] == FUNHEAD+4 && t[FUNHEAD+1] == 1
841 && t[FUNHEAD+3] == -1 ) ncoef = -ncoef;
843 else pcom[ncom++] = t;
855 if ( k == 0 )
goto NormZero;
856 *((UWORD *)lnum) = k;
864 if ( *t == -EXPRESSION ) {
865 k = AS.OldNumFactors[t[1]];
867 else if ( *t == -DOLLAREXPRESSION ) {
868 k = Dollars[t[1]].nfactors;
874 if ( k == 0 )
goto NormZero;
875 *((UWORD *)lnum) = k;
882 if ( t[FUNHEAD] < 0 ) {
883 if ( t[FUNHEAD] <= -FUNCTION && t[1] == FUNHEAD+1 )
break;
884 if ( t[FUNHEAD] > -FUNCTION && t[1] == FUNHEAD+2 ) {
885 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 )
goto NormZero;
891 if ( t[FUNHEAD] > 0 && t[FUNHEAD] == t[1]-FUNHEAD ) {
893 t += FUNHEAD+ARGHEAD;
898 if ( k == 0 )
goto NormZero;
899 *((UWORD *)lnum) = k;
903 else pcom[ncom++] = t;
907 k = CountFun(AN.cTerm,t);
910 k = CountFun(term,t);
912 if ( k == 0 )
goto NormZero;
913 if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
914 else { *((UWORD *)lnum) = -k; nnum = -1; }
918 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] == -SNUMBER
919 && t[1] == FUNHEAD+4 && t[FUNHEAD+3] > 1 ) {
921 if ( t[FUNHEAD+1] == 0 )
goto NormZero;
922 if ( t[FUNHEAD+1] < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; sgn = -1; }
924 if ( MakeRational(t[FUNHEAD+1],t[FUNHEAD+3],x1,x1+1) ) {
925 static int warnflag = 1;
927 MesPrint(
"%w Warning: fraction could not be reconstructed in MakeRational_");
930 x1[0] = t[FUNHEAD+1]; x1[1] = 1;
932 if ( sgn < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; x1[0] = -x1[0]; }
933 if ( x1[0] < 0 ) { sgn = -1; x1[0] = -x1[0]; }
935 ncoef = REDLENG(ncoef);
936 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)x1,sgn,
937 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
938 ncoef = INCLENG(ncoef);
941 WORD narg = 0, *tt, *ttstop, *arg1 = 0, *arg2 = 0;
944 ttstop = t + t[1]; tt = t+FUNHEAD;
945 while ( tt < ttstop ) {
947 if ( narg == 1 ) arg1 = tt;
951 if ( narg != 2 )
goto defaultcase;
952 if ( *arg2 == -SNUMBER && arg2[1] <= 1 )
goto defaultcase;
953 else if ( *arg2 > 0 && ttstop[-1] < 0 )
goto defaultcase;
954 x1 = NumberMalloc(
"Norm-MakeRational");
955 if ( *arg1 == -SNUMBER ) {
956 if ( arg1[1] == 0 ) {
957 NumberFree(x1,
"Norm-MakeRational");
960 if ( arg1[1] < 0 ) { x1[0] = -arg1[1]; nx1 = -1; }
961 else { x1[0] = arg1[1]; nx1 = 1; }
963 else if ( *arg1 > 0 ) {
965 nx1 = (ABS(arg2[-1])-1)/2;
966 tc = arg1+ARGHEAD+1+nx1;
968 NumberFree(x1,
"Norm-MakeRational");
971 for ( i = 1; i < nx1; i++ )
if ( tc[i] != 0 ) {
972 NumberFree(x1,
"Norm-MakeRational");
976 for ( i = 0; i < nx1; i++ ) x1[i] = tc[i];
977 if ( arg2[-1] < 0 ) nx1 = -nx1;
980 NumberFree(x1,
"Norm-MakeRational");
983 x2 = NumberMalloc(
"Norm-MakeRational");
984 if ( *arg2 == -SNUMBER ) {
985 if ( arg2[1] <= 1 ) {
986 NumberFree(x2,
"Norm-MakeRational");
987 NumberFree(x1,
"Norm-MakeRational");
990 else { x2[0] = arg2[1]; nx2 = 1; }
992 else if ( *arg2 > 0 ) {
994 nx2 = (ttstop[-1]-1)/2;
995 tc = arg2+ARGHEAD+1+nx2;
997 NumberFree(x2,
"Norm-MakeRational");
998 NumberFree(x1,
"Norm-MakeRational");
1001 for ( i = 1; i < nx2; i++ )
if ( tc[i] != 0 ) {
1002 NumberFree(x2,
"Norm-MakeRational");
1003 NumberFree(x1,
"Norm-MakeRational");
1006 tc = arg2+ARGHEAD+1;
1007 for ( i = 0; i < nx2; i++ ) x2[i] = tc[i];
1010 NumberFree(x2,
"Norm-MakeRational");
1011 NumberFree(x1,
"Norm-MakeRational");
1014 if ( BigLong(x1,ABS(nx1),x2,nx2) >= 0 ) {
1015 UWORD *x3 = NumberMalloc(
"Norm-MakeRational");
1016 UWORD *x4 = NumberMalloc(
"Norm-MakeRational");
1018 DivLong(x1,nx1,x2,nx2,x3,&nx3,x4,&nx4);
1019 for ( i = 0; i < ABS(nx4); i++ ) x1[i] = x4[i];
1021 NumberFree(x4,
"Norm-MakeRational");
1022 NumberFree(x3,
"Norm-MakeRational");
1024 xx = (UWORD *)(TermMalloc(
"Norm-MakeRational"));
1025 if ( MakeLongRational(BHEAD x1,nx1,x2,nx2,xx,&nxx) ) {
1026 static int warnflag = 1;
1028 MesPrint(
"%w Warning: fraction could not be reconstructed in MakeRational_");
1031 ncoef = REDLENG(ncoef);
1032 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,x1,nx1) )
1036 ncoef = REDLENG(ncoef);
1037 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,xx,nxx,
1038 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1040 ncoef = INCLENG(ncoef);
1041 TermFree(xx,
"Norm-MakeRational");
1042 NumberFree(x2,
"Norm-MakeRational");
1043 NumberFree(x1,
"Norm-MakeRational");
1047 if ( t[1] == FUNHEAD && AN.cTerm ) {
1048 ANsr = r; ANsm = m; ANsc = AN.cTerm;
1052 ncoef = REDLENG(ncoef);
1053 nnum = REDLENG(m[-1]);
1055 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
1056 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1057 ncoef = INCLENG(ncoef);
1062 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1063 if ( GetFirstBracket(termout,t[FUNHEAD+1]) < 0 )
goto FromNorm;
1064 if ( *termout == 0 )
goto NormZero;
1065 if ( *termout > 4 ) {
1067 while ( r < m ) *t++ = *r++;
1069 r2 = termout + *termout; r2 -= ABS(r2[-1]);
1070 while ( r < r1 ) *r2++ = *r++;
1072 while ( r3 < r2 ) *t++ = *r3++;
1074 if ( AT.WorkPointer > term && AT.WorkPointer < t )
1082 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1085 POSITION oldondisk = AS.OldOnFile[t[FUNHEAD+1]];
1086 if ( e->replace == NEWLYDEFINEDEXPRESSION ) {
1087 AS.OldOnFile[t[FUNHEAD+1]] = e->onfile;
1089 if ( *t == FIRSTTERM ) {
1090 if (
GetFirstTerm(termout,t[FUNHEAD+1],0) < 0 )
goto FromNorm;
1092 else if ( *t == CONTENTTERM ) {
1093 if ( GetContent(termout,t[FUNHEAD+1]) < 0 )
goto FromNorm;
1095 AS.OldOnFile[t[FUNHEAD+1]] = oldondisk;
1096 if ( *termout == 0 )
goto NormZero;
1100 WORD *r1, *r2, *r3, *r4, *r5, nr1, *rterm;
1101 r2 = termout + *termout; lnum = r2 - ABS(r2[-1]);
1102 nnum = REDLENG(r2[-1]);
1104 r1 = term + *term; r3 = r1 - ABS(r1[-1]);
1105 nr1 = REDLENG(r1[-1]);
1106 if ( Mully(BHEAD (UWORD *)lnum,&nnum,(UWORD *)r3,nr1) )
goto FromNorm;
1107 nnum = INCLENG(nnum); nr1 = ABS(nnum); lnum[nr1-1] = nnum;
1108 rterm = TermMalloc(
"FirstTerm/ContentTerm");
1109 r4 = rterm+1; r5 = term+1;
while ( r5 < t ) *r4++ = *r5++;
1110 r5 = termout+1;
while ( r5 < lnum ) *r4++ = *r5++;
1111 r5 = r;
while ( r5 < r3 ) *r4++ = *r5++;
1112 r5 = lnum; NCOPY(r4,r5,nr1);
1114 nr1 = *rterm; r1 = term; r2 = rterm; NCOPY(r1,r2,nr1);
1115 TermFree(rterm,
"FirstTerm/ContentTerm");
1116 if ( AT.WorkPointer > term && AT.WorkPointer < r1 )
1117 AT.WorkPointer = r1;
1121 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
1122 DOLLARS d = Dollars + t[FUNHEAD+1], newd = 0;
1125 int nummodopt, dtype = -1;
1126 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1127 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1128 if ( t[FUNHEAD+1] == ModOptdollars[nummodopt].number )
break;
1130 if ( nummodopt < NumModOptdollars ) {
1131 dtype = ModOptdollars[nummodopt].type;
1132 if ( DollarLocalCopy(dtype) ) {
1133 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1138 if ( d->where && ( d->type == DOLTERMS || d->type == DOLNUMBER ) ) {
1142 if ( ( newd = DolToTerms(BHEAD t[FUNHEAD+1]) ) == 0 )
1145 if ( newd->where[0] == 0 ) {
1146 M_free(newd,
"Copy of dollar variable");
1149 if ( *t == FIRSTTERM ) {
1150 idol = newd->where[0];
1151 for ( ido = 0; ido < idol; ido++ ) termout[ido] = newd->where[ido];
1153 else if ( *t == CONTENTTERM ) {
1155 tterm = newd->where;
1157 for ( ido = 0; ido < idol; ido++ ) termout[ido] = tterm[ido];
1160 if ( ContentMerge(BHEAD termout,tterm) < 0 )
goto FromNorm;
1165 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
1166 M_free(newd,
"Copy of dollar variable");
1174 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1175 x = TermsInExpression(t[FUNHEAD+1]);
1176multermnum:
if ( x == 0 )
goto NormZero;
1179 if ( x > (LONG)WORDMASK ) { lnum[0] = x & WORDMASK;
1180 lnum[1] = x >> BITSINWORD; nnum = -2;
1182 else { lnum[0] = x; nnum = -1; }
1184 else if ( x > (LONG)WORDMASK ) {
1185 lnum[0] = x & WORDMASK;
1186 lnum[1] = x >> BITSINWORD;
1189 else { lnum[0] = x; nnum = 1; }
1190 ncoef = REDLENG(ncoef);
1191 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
1193 ncoef = INCLENG(ncoef);
1195 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
1196 x = TermsInDollar(t[FUNHEAD+1]);
1199 else { pcom[ncom++] = t; }
1202 case SIZEOFFUNCTION:
1204 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1205 x = SizeOfExpression(t[FUNHEAD+1]);
1208 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
1209 x = SizeOfDollar(t[FUNHEAD+1]);
1212 else { pcom[ncom++] = t; }
1216 case PATTERNFUNCTION:
1223 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1224 && t[FUNHEAD+1] >= 0 && t[FUNHEAD+2] == -SNUMBER
1225 && t[FUNHEAD+3] >= 0 && t[FUNHEAD+1] >= t[FUNHEAD+3] ) {
1226 if ( t[FUNHEAD+1] > t[FUNHEAD+3] ) {
1227 if ( GetBinom((UWORD *)lnum,&nnum,
1228 t[FUNHEAD+1],t[FUNHEAD+3]) )
goto FromNorm;
1229 if ( nnum == 0 )
goto NormZero;
1233 else pcom[ncom++] = t;
1239 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1240 if ( ( t[FUNHEAD+1] & 1 ) != 0 ) ncoef = -ncoef;
1242 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
1243 && ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) ) {
1244 UWORD *numer1,*denom1;
1245 WORD nsize = abs(t[t[1]-1]), nnsize, isize;
1246 nnsize = (nsize-1)/2;
1247 numer1 = (UWORD *)(t + FUNHEAD+ARGHEAD+1);
1248 denom1 = numer1 + nnsize;
1249 for ( isize = 1; isize < nnsize; isize++ ) {
1250 if ( denom1[isize] )
break;
1252 if ( ( denom1[0] != 1 ) || isize < nnsize ) {
1256 if ( ( numer1[0] & 1 ) != 0 ) ncoef = -ncoef;
1270 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1271 if ( t[FUNHEAD+1] < 0 ) ncoef = -ncoef;
1273 else if ( ( t[1] == FUNHEAD+2 ) && ( t[FUNHEAD] == -SYMBOL )
1274 && ( ( t[FUNHEAD+1] <= NumSymbols && t[FUNHEAD+1] > -MAXPOWER )
1275 && ( symbols[t[FUNHEAD+1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) ) {
1285 *m %= symbols[k].maxpower;
1286 if ( ( symbols[k].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
1287 if ( ( ( symbols[k].maxpower & 1 ) == 0 ) &&
1288 ( *m >= symbols[k].maxpower/2 ) ) {
1289 *m -= symbols[k].maxpower/2; ncoef = -ncoef;
1295 { *m = m[2]; m++; *m = m[2]; m++; i++; }
1301 }
while ( k < *m && --i > 0 );
1304 { m--; m[2] = *m; m--; m[2] = *m; i++; }
1312 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] ) ) {
1313 if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
1314 if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
1319 else if ( ( t[FUNHEAD+ARGHEAD]+FUNHEAD+ARGHEAD == t[1] )
1320 && ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) ) {
1321 WORD *ts = t + FUNHEAD+ARGHEAD+3;
1322 WORD its = ts[-1]-2;
1324 if ( ( *ts != 0 ) && ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
1325 || ( symbols[*ts].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY ) ) {
1334 if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
1335 ts = t + FUNHEAD+ARGHEAD+3;
1346 if ( ( ts[-1] <= NumSymbols && ts[-1] > -MAXPOWER ) &&
1347 ( symbols[ts[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
1348 *m %= symbols[ts[-1]].maxpower;
1349 if ( *m < 0 ) *m += symbols[ts[-1]].maxpower;
1350 if ( ( symbols[ts[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
1351 if ( ( ( symbols[ts[-1]].maxpower & 1 ) == 0 ) &&
1352 ( *m >= symbols[ts[-1]].maxpower/2 ) ) {
1353 *m -= symbols[ts[-1]].maxpower/2; ncoef = -ncoef;
1360 { *m = m[2]; m++; *m = m[2]; m++; i++; }
1367 }
while ( *ts < *m && --i > 0 );
1370 { m--; m[2] = *m; m--; m[2] = *m; i++; }
1380signogood: pcom[ncom++] = t;
1383 else pcom[ncom++] = t;
1390 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1392 if ( k < 0 ) k = -k;
1393 if ( k == 0 )
goto NormZero;
1394 *((UWORD *)lnum) = k; nnum = 1;
1398 else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SYMBOL ) {
1400 if ( ( k > NumSymbols || k <= -MAXPOWER )
1401 || ( symbols[k].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
1404 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
1405 && ( t[1] == FUNHEAD+ARGHEAD+t[FUNHEAD+ARGHEAD] ) ) {
1406 if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
1408absnosymbols: ts = t + t[1] -1;
1409 ncoef = REDLENG(ncoef);
1410 nnum = REDLENG(*ts);
1411 if ( nnum < 0 ) nnum = -nnum;
1412 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,
1413 (UWORD *)(ts-ABS(*ts)+1),nnum,
1414 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1415 ncoef = INCLENG(ncoef);
1420 else if ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) {
1421 WORD *ts = t+FUNHEAD+ARGHEAD+1;
1422 WORD its = ts[1] - 2;
1426 else if ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
1427 || ( symbols[*ts].complex & VARTYPEROOTOFUNITY )
1428 != VARTYPEROOTOFUNITY )
goto absnogood;
1434absnogood: pcom[ncom++] = t;
1437 else pcom[ncom++] = t;
1445 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1446 && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+3] > 1 ) {
1448 tmod = (t[FUNHEAD+1]%t[FUNHEAD+3]);
1449 if ( tmod < 0 ) tmod += t[FUNHEAD+3];
1450 if ( *t == MOD2FUNCTION && tmod > t[FUNHEAD+3]/2 )
1451 tmod -= t[FUNHEAD+3];
1453 *((UWORD *)lnum) = -tmod;
1456 else if ( tmod > 0 ) {
1457 *((UWORD *)lnum) = tmod;
1463 else if ( t[1] > t[FUNHEAD+2] && t[FUNHEAD] > 0
1464 && t[FUNHEAD+t[FUNHEAD]] == -SNUMBER
1465 && t[FUNHEAD+t[FUNHEAD]+1] > 1
1466 && t[1] == FUNHEAD+2+t[FUNHEAD] ) {
1467 WORD *ttt = t+FUNHEAD, iii;
1469 if ( *ttt == ttt[ARGHEAD]+ARGHEAD &&
1470 ttt[ARGHEAD] == ABS(iii)+1 ) {
1472 WORD cmod = ttt[*ttt+1];
1474 if ( *t == MODFUNCTION ) {
1475 if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
1476 ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|NOINVERSES) )
1480 if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
1481 ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|POSNEG|NOINVERSES) )
1484 if ( *t == MOD2FUNCTION && ttt[ARGHEAD+1] > cmod/2 && iii > 0 ) {
1485 ttt[ARGHEAD+1] -= cmod;
1487 if ( ttt[ARGHEAD+1] < 0 ) {
1488 *((UWORD *)lnum) = -ttt[ARGHEAD+1];
1491 else if ( ttt[ARGHEAD+1] > 0 ) {
1492 *((UWORD *)lnum) = ttt[ARGHEAD+1];
1499 else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1500 *((UWORD *)lnum) = t[FUNHEAD+1];
1501 if ( *lnum == 0 )
goto NormZero;
1505 else if ( ( ( t[FUNHEAD] < 0 ) && ( t[FUNHEAD] == -SNUMBER )
1506 && ( t[1] >= ( FUNHEAD+6+ARGHEAD ) )
1507 && ( t[FUNHEAD+2] >= 4+ARGHEAD )
1508 && ( t[t[1]-1] == t[FUNHEAD+2+ARGHEAD]-1 ) ) ||
1509 ( ( t[FUNHEAD] > 0 )
1510 && ( t[FUNHEAD]-ARGHEAD-1 == ABS(t[FUNHEAD+t[FUNHEAD]-1]) )
1511 && ( t[FUNHEAD+t[FUNHEAD]]-ARGHEAD-1 == t[t[1]-1] ) ) ) {
1515 WORD *ttt = t + t[1], iii, iii1;
1516 UWORD coefbuf[2], *coef2, ncoef2;
1517 iii = (ttt[-1]-1)/2;
1519 if ( ttt[-1] != 1 ) {
1525 for ( iii1 = 0; iii1 < iii; iii1++ ) {
1526 if ( ttt[iii1] != 0 )
goto exitfromhere;
1537 nnum = -1; lnum[0] = -ttt[1]; lnum[1] = 1;
1540 nnum = 1; lnum[0] = ttt[1]; lnum[1] = 1;
1544 nnum = ABS(ttt[ttt[0]-1] - 1);
1545 for ( iii = 0; iii < nnum; iii++ ) {
1546 lnum[iii] = ttt[ARGHEAD+1+iii];
1549 if ( ttt[ttt[0]-1] < 0 ) nnum = -nnum;
1554 ncoef2 = 3; *coef2 = (UWORD)(ttt[1]);
1558 coef2 = (UWORD *)(ttt+ARGHEAD+1);
1559 ncoef2 = (ttt[ttt[0]-1]-1)/2;
1561 if ( TakeModulus((UWORD *)lnum,&nnum,(UWORD *)coef2,ncoef2,
1562 UNPACK|NOINVERSES|FROMFUNCTION) ) {
1565 if ( *t == MOD2FUNCTION && nnum > 0 ) {
1566 UWORD *coef3 = NumberMalloc(
"Mod2Function"), two = 2;
1568 if ( MulLong((UWORD *)lnum,nnum,&two,1,coef3,&ncoef3) )
1570 if ( BigLong(coef3,ncoef3,(UWORD *)coef2,ncoef2) > 0 ) {
1572 AddLong((UWORD *)lnum,nnum,(UWORD *)coef2,ncoef2
1573 ,(UWORD *)lnum,&nnum);
1576 NumberFree(coef3,
"Mod2Function");
1581 ncoef = REDLENG(ncoef);
1582 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
1584 ncoef = INCLENG(ncoef);
1586 else pcom[ncom++] = t;
1590 WORD argcount = 0, *tc, *ts, xc, xs, *tcc;
1591 UWORD *Num1, *Num2, *Num3, *Num4;
1592 WORD size1, size2, size3, size4, space;
1593 tc = t+FUNHEAD; ts = t + t[1];
1594 while ( argcount < 3 && tc < ts ) { NEXTARG(tc); argcount++; }
1595 if ( argcount != 2 )
goto defaultcase;
1596 if ( t[FUNHEAD] == -SNUMBER ) {
1597 if ( t[FUNHEAD+1] <= 1 )
goto defaultcase;
1598 if ( t[FUNHEAD+2] == -SNUMBER ) {
1599 if ( t[FUNHEAD+3] <= 1 )
goto defaultcase;
1600 Num2 = NumberMalloc(
"modinverses");
1601 *Num2 = t[FUNHEAD+3]; size2 = 1;
1604 if ( ts[-1] < 0 )
goto defaultcase;
1605 if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 )
goto defaultcase;
1608 if ( *tcc != 1 )
goto defaultcase;
1609 for ( i = 1; i < xs; i++ ) {
1610 if ( tcc[i] != 0 )
goto defaultcase;
1612 Num2 = NumberMalloc(
"modinverses");
1614 for ( i = 0; i < xs; i++ ) Num2[i] = t[FUNHEAD+ARGHEAD+3+i];
1616 Num1 = NumberMalloc(
"modinverses");
1617 *Num1 = t[FUNHEAD+1]; size1 = 1;
1620 tc = t + FUNHEAD + t[FUNHEAD];
1621 if ( tc[-1] < 0 )
goto defaultcase;
1622 if ( tc[-1] != t[FUNHEAD]-ARGHEAD-1 )
goto defaultcase;
1625 if ( *tcc != 1 )
goto defaultcase;
1626 for ( i = 1; i < xc; i++ ) {
1627 if ( tcc[i] != 0 )
goto defaultcase;
1629 if ( *tc == -SNUMBER ) {
1630 if ( tc[1] <= 1 )
goto defaultcase;
1631 Num2 = NumberMalloc(
"modinverses");
1632 *Num2 = tc[1]; size2 = 1;
1635 if ( ts[-1] < 0 )
goto defaultcase;
1636 if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 )
goto defaultcase;
1639 if ( *tcc != 1 )
goto defaultcase;
1640 for ( i = 1; i < xs; i++ ) {
1641 if ( tcc[i] != 0 )
goto defaultcase;
1643 Num2 = NumberMalloc(
"modinverses");
1645 for ( i = 0; i < xs; i++ ) Num2[i] = tc[ARGHEAD+1+i];
1647 Num1 = NumberMalloc(
"modinverses");
1649 for ( i = 0; i < xc; i++ ) Num1[i] = t[FUNHEAD+ARGHEAD+1+i];
1651 Num3 = NumberMalloc(
"modinverses");
1652 Num4 = NumberMalloc(
"modinverses");
1653 GetLongModInverses(BHEAD Num1,size1,Num2,size2
1654 ,Num3,&size3,Num4,&size4);
1663 if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) space += 2;
1664 else space += ARGHEAD + 2*ABS(size3) + 2;
1665 if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) space += 2;
1666 else space += ARGHEAD + 2*ABS(size4) + 2;
1667 tt = term + *term; u = tt + space;
1668 while ( tt >= ts ) *--u = *--tt;
1669 m += space; r += space;
1672 if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) {
1673 *ts++ = -SNUMBER; *ts = (WORD)(*Num3);
1674 if ( size3 < 0 ) *ts = -*ts;
1678 *ts++ = 2*ABS(size3)+ARGHEAD+2;
1679 *ts++ = 0; FILLARG(ts)
1680 *ts++ = 2*ABS(size3)+1;
1681 for ( i = 0; i < ABS(size3); i++ ) *ts++ = Num3[i];
1683 for ( i = 1; i < ABS(size3); i++ ) *ts++ = 0;
1684 if ( size3 < 0 ) *ts++ = 2*size3-1;
1685 else *ts++ = 2*size3+1;
1687 if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) {
1688 *ts++ = -SNUMBER; *ts = *Num4;
1689 if ( size4 < 0 ) *ts = -*ts;
1693 *ts++ = 2*ABS(size4)+ARGHEAD+2;
1694 *ts++ = 0; FILLARG(ts)
1695 *ts++ = 2*ABS(size4)+2;
1696 for ( i = 0; i < ABS(size4); i++ ) *ts++ = Num4[i];
1698 for ( i = 1; i < ABS(size4); i++ ) *ts++ = 0;
1699 if ( size4 < 0 ) *ts++ = 2*size4-1;
1700 else *ts++ = 2*size4+1;
1702 NumberFree(Num4,
"modinverses");
1703 NumberFree(Num3,
"modinverses");
1704 NumberFree(Num1,
"modinverses");
1705 NumberFree(Num2,
"modinverses");
1712#ifdef NEWGCDFUNCTION
1718 WORD *num1, *num2, size1, size2, stor1, stor2, *ttt, ti;
1719 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1720 && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+1] != 0
1721 && t[FUNHEAD+3] != 0 ) {
1722 stor1 = t[FUNHEAD+1];
1723 stor2 = t[FUNHEAD+3];
1724 if ( stor1 < 0 ) stor1 = -stor1;
1725 if ( stor2 < 0 ) stor2 = -stor2;
1726 num1 = &stor1; num2 = &stor2;
1730 else if ( t[1] > FUNHEAD+4 ) {
1731 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] != 0
1732 && t[FUNHEAD+2] == t[1]-FUNHEAD-2 &&
1733 ABS(t[t[1]-1]) == t[FUNHEAD+2]-1-ARGHEAD ) {
1735 size2 = ABS(num2[-1]);
1738 size2 = (size2-1)/2;
1740 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1741 if ( ti == 1 && ttt[-1] == 1 ) {
1742 stor1 = t[FUNHEAD+1];
1743 if ( stor1 < 0 ) stor1 = -stor1;
1748 else pcom[ncom++] = t;
1750 else if ( t[FUNHEAD] > 0 &&
1751 t[FUNHEAD]-1-ARGHEAD == ABS(t[t[FUNHEAD]+FUNHEAD-1]) ) {
1752 num1 = t + FUNHEAD + t[FUNHEAD];
1753 size1 = ABS(num1[-1]);
1756 size1 = (size1-1)/2;
1758 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1759 if ( ti == 1 && ttt[-1] == 1 ) {
1760 if ( t[1]-FUNHEAD == t[FUNHEAD]+2 && t[t[1]-2] == -SNUMBER
1761 && t[t[1]-1] != 0 ) {
1763 if ( stor2 < 0 ) stor2 = -stor2;
1768 else if ( t[1]-FUNHEAD == t[FUNHEAD]+t[FUNHEAD+t[FUNHEAD]]
1769 && ABS(t[t[1]-1]) == t[FUNHEAD+t[FUNHEAD]] - ARGHEAD-1 ) {
1771 size2 = ABS(num2[-1]);
1774 size2 = (size2-1)/2;
1776 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1777 if ( ti == 1 && ttt[-1] == 1 ) {
1778gcdcalc:
if ( GcdLong(BHEAD (UWORD *)num1,size1,(UWORD *)num2,size2
1779 ,(UWORD *)lnum,&nnum) )
goto FromNorm;
1782 else pcom[ncom++] = t;
1784 else pcom[ncom++] = t;
1786 else pcom[ncom++] = t;
1788 else pcom[ncom++] = t;
1790 else pcom[ncom++] = t;
1794 WORD *gcd = AT.WorkPointer;
1795 if ( ( gcd = EvaluateGcd(BHEAD t) ) == 0 )
goto FromNorm;
1796 if ( *gcd == 4 && gcd[1] == 1 && gcd[2] == 1 && gcd[4] == 0 ) {
1797 AT.WorkPointer = gcd;
1799 else if ( gcd[*gcd] == 0 ) {
1800 WORD *t1, iii, change, *num, *den, numsize, densize;
1801 if ( gcd[*gcd-1] < *gcd-1 ) {
1803 for ( iii = 2; iii < t1[1]; iii += 2 ) {
1804 change = ExtraSymbol(t1[iii],t1[iii+1],nsym,ppsym,&ncoef);
1806 ppsym += change * 2;
1810 iii = t1[-1]; num = t1-iii; numsize = (iii-1)/2;
1811 den = num + numsize; densize = numsize;
1812 while ( numsize > 1 && num[numsize-1] == 0 ) numsize--;
1813 while ( densize > 1 && den[densize-1] == 0 ) densize--;
1814 if ( numsize > 1 || num[0] != 1 ) {
1815 ncoef = REDLENG(ncoef);
1816 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)num,numsize) )
goto FromNorm;
1817 ncoef = INCLENG(ncoef);
1819 if ( densize > 1 || den[0] != 1 ) {
1820 ncoef = REDLENG(ncoef);
1821 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)den,densize) )
goto FromNorm;
1822 ncoef = INCLENG(ncoef);
1824 AT.WorkPointer = gcd;
1838 LONG size = AT.WorkPointer - gcd;
1840 ss =
AddRHS(AT.ebufnum,1);
1844 C->
rhs[C->numrhs+1] = ss;
1847 t[0] = SUBEXPRESSION;
1854 while ( r < tt ) *t++ = *r++;
1863 MesPrint(
" Unexpected call to EvaluateGCD");
1869 if ( t[1] == FUNHEAD )
break;
1871 WORD *ttt = t + FUNHEAD;
1872 WORD *tttstop = t + t[1];
1874 while ( ttt < tttstop ) {
1876 if ( ttt[ARGHEAD]-1 > ABS(ttt[*ttt-1]) )
goto nospec;
1880 if ( *ttt != -SNUMBER )
goto nospec;
1891 for ( iii = 0; iii < ttt[ARGHEAD]; iii++ )
1892 n_llnum[iii] = ttt[ARGHEAD+iii];
1897 if ( ttt[1] == 0 ) {
1898 n_llnum[0] = n_llnum[1] = n_llnum[2] = n_llnum[3] = 0;
1902 if ( ttt[1] > 0 ) { n_llnum[1] = ttt[1]; n_llnum[3] = 3; }
1903 else { n_llnum[1] = -ttt[1]; n_llnum[3] = -3; }
1911 while ( ttt < tttstop ) {
1913 if ( n_llnum[0] == 0 ) {
1914 if ( ( *t == MINFUNCTION && ttt[*ttt-1] < 0 )
1915 || ( *t == MAXFUNCTION && ttt[*ttt-1] > 0 ) )
1921 if ( ( iii > 0 && *t == MINFUNCTION )
1922 || ( iii < 0 && *t == MAXFUNCTION ) ) {
1923 for ( iii = 0; iii < ttt[0]; iii++ )
1924 n_llnum[iii] = ttt[iii];
1930 if ( n_llnum[0] == 0 ) {
1931 if ( ( *t == MINFUNCTION && ttt[1] < 0 )
1932 || ( *t == MAXFUNCTION && ttt[1] > 0 ) )
1935 else if ( ttt[1] == 0 ) {
1936 if ( ( *t == MINFUNCTION && n_llnum[*n_llnum-1] > 0 )
1937 || ( *t == MAXFUNCTION && n_llnum[*n_llnum-1] < 0 ) ) {
1942 tterm[0] = 4; tterm[2] = 1;
1943 if ( ttt[1] < 0 ) { tterm[1] = -ttt[1]; tterm[3] = -3; }
1944 else { tterm[1] = ttt[1]; tterm[3] = 3; }
1946 if ( ( iii > 0 && *t == MINFUNCTION )
1947 || ( iii < 0 && *t == MAXFUNCTION ) ) {
1948 for ( iii = 0; iii < 4; iii++ )
1949 n_llnum[iii] = tterm[iii];
1955 if ( n_llnum[0] == 0 )
goto NormZero;
1956 ncoef = REDLENG(ncoef);
1957 nnum = REDLENG(n_llnum[*n_llnum-1]);
1958 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)lnum,nnum,
1959 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1960 ncoef = INCLENG(ncoef);
1963 case INVERSEFACTORIAL:
1964 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 ) {
1965 if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
1967 ncoef = REDLENG(ncoef);
1968 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
1969 ncoef = INCLENG(ncoef);
1972nospec: pcom[ncom++] = t;
1976 if ( ( t[FUNHEAD] == -SYMBOL )
1977 && ( t[FUNHEAD+1] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
1978 *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].maxpower;
1982 else { pcom[ncom++] = t; }
1985 if ( ( t[FUNHEAD] == -SYMBOL )
1986 && ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
1987 *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].minpower;
1991 else { pcom[ncom++] = t; }
1994 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER
1995 && t[FUNHEAD+1] > 0 ) {
1996 UWORD xp = (UWORD)(
NextPrime(BHEAD t[FUNHEAD+1]));
1997 ncoef = REDLENG(ncoef);
1998 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,&xp,1) )
goto FromNorm;
1999 ncoef = INCLENG(ncoef);
2001 else goto defaultcase;
2007 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER
2008 && t[FUNHEAD+1] > 0 ) {
2009 WORD val = Moebius(BHEAD t[FUNHEAD+1]);
2010 if ( val == 0 )
goto NormZero;
2011 if ( val < 0 ) ncoef = -ncoef;
2018 ncoef = REDLENG(ncoef);
2019 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(t+3),t[2]) )
goto FromNorm;
2020 ncoef = INCLENG(ncoef);
2025 if ( t[3] & 1 ) ncoef = -ncoef;
2027 else if ( t[2] == 0 ) {
2028 if ( t[3] < 0 )
goto NormInf;
2033 if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) )
goto FromNorm;
2034 ncoef = REDLENG(ncoef);
2036 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
2039 else if ( t[3] > 0 ) {
2040 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
2043 ncoef = INCLENG(ncoef);
2050 if ( t[1] == FUNHEAD ) {
2051 MLOCK(ErrorMessageLock);
2052 MesPrint(
"Gamma matrix without spin line encountered.");
2053 MUNLOCK(ErrorMessageLock);
2061 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) {
2063 t[2] |= DIRTYSYMFLAG;
2066ScanCont:
while ( t < r ) {
2067 if ( *t >= AM.OffsetIndex &&
2068 ( *t >= AM.DumInd || ( *t < AM.WilInd &&
2069 indices[*t-AM.OffsetIndex].dimension ) ) )
2079 if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) )
2081 if ( *rr == -SNUMBER && rr[1] == 1 )
break;
2082 if ( *rr <= -FUNCTION ) k = *rr;
2084 if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) ) {
2085 if ( k == 0 )
goto NormZZ;
2088 if ( *rr == -SNUMBER && rr[1] > 0 && rr[1] < MAXPOWER && k < 0 ) {
2090 if ( functions[k-FUNCTION].commute ) {
2091 for ( i = 0; i < rr[1]; i++ ) pnco[nnco++] = rr-1;
2094 for ( i = 0; i < rr[1]; i++ ) pcom[ncom++] = rr-1;
2098 if ( k == 0 )
goto NormZero;
2099 if ( t[FUNHEAD] == -SYMBOL && *rr == -SNUMBER && t[1] == FUNHEAD+4 ) {
2100 if ( rr[1] < MAXPOWER ) {
2101 t[FUNHEAD+2] = t[FUNHEAD+1]; t += FUNHEAD+2;
2111 t[2] &= ~DIRTYSYMFLAG;
2117 t[2] &= ~DIRTYSYMFLAG;
2124 if ( *t == 0 || *t == AM.vectorzero )
goto NormZero;
2125 if ( *t > 0 && *t < AM.OffsetIndex ) {
2128 ncoef = REDLENG(ncoef);
2129 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
2131 ncoef = INCLENG(ncoef);
2133 else if ( *t == NOINDEX ) t++;
2134 else pind[nind++] = *t++;
2137 case SUBEXPRESSION :
2138 if ( t[3] == 0 )
break;
2150 if ( t[2] == 0 )
goto defaultcase;
2151 if ( t[FUNHEAD] != -SNUMBER || t[FUNHEAD+1] < 0 )
goto defaultcase;
2152 if ( t[FUNHEAD+2] == -SNUMBER ) {
2153 if ( t[FUNHEAD+1] == 0 && t[FUNHEAD+3] == 0 )
goto NormZZ;
2154 if ( t[FUNHEAD+1] == 0 )
break;
2155 if ( t[FUNHEAD+3] < 0 ) {
2156 AT.WorkPointer[0] = -t[FUNHEAD+3];
2160 AT.WorkPointer[0] = t[FUNHEAD+3];
2163 AT.WorkPointer[1] = 1;
2165 else if ( t[FUNHEAD+2] == t[1]-FUNHEAD-2
2166 && t[FUNHEAD+2] == t[FUNHEAD+2+ARGHEAD]+ARGHEAD
2167 && ABS(t[t[1]-1]) == t[FUNHEAD+2+ARGHEAD] - 1 ) {
2169 if ( t[FUNHEAD+1] == 0 )
break;
2170 i = t[t[1]-1]; r1 = t + FUNHEAD+ARGHEAD+3;
2173 r2 = AT.WorkPointer;
2174 while ( --i >= 0 ) *r2++ = *r1++;
2176 else goto defaultcase;
2177 if ( TakeRatRoot((UWORD *)AT.WorkPointer,&nc,t[FUNHEAD+1]) ) {
2181 ncoef = REDLENG(ncoef);
2182 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,nc) )
2184 if ( nc < 0 ) nc = -nc;
2185 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(AT.WorkPointer+nc),nc) )
2187 ncoef = INCLENG(ncoef);
2190 case RANDOMFUNCTION :
2192 WORD nnc, nc, nca, nr;
2203 if ( t[1] == FUNHEAD )
goto defaultcase;
2204 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER &&
2205 t[FUNHEAD+1] > 0 ) {
2206 if ( t[FUNHEAD+1] == 1 )
break;
2208 ((UWORD *)AT.WorkPointer)[0] = wranf(BHEAD0);
2209 ((UWORD *)AT.WorkPointer)[1] = wranf(BHEAD0);
2211 if ( ((UWORD *)AT.WorkPointer)[1] == 0 ) {
2213 if ( ((UWORD *)AT.WorkPointer)[0] == 0 ) {
2217 xx = (UWORD)(t[FUNHEAD+1]);
2219 DivLong((UWORD *)AT.WorkPointer,nr
2221 ,((UWORD *)AT.WorkPointer)+4,&nnc
2222 ,((UWORD *)AT.WorkPointer)+2,&nc);
2223 ((UWORD *)AT.WorkPointer)[4] = 0;
2224 ((UWORD *)AT.WorkPointer)[5] = 0;
2225 ((UWORD *)AT.WorkPointer)[6] = 1;
2226 DivLong((UWORD *)AT.WorkPointer+4,3
2228 ,((UWORD *)AT.WorkPointer)+9,&nnc
2229 ,((UWORD *)AT.WorkPointer)+7,&nca);
2230 AddLong((UWORD *)AT.WorkPointer+4,3
2231 ,((UWORD *)AT.WorkPointer)+7,-nca
2232 ,((UWORD *)AT.WorkPointer)+9,&nnc);
2233 if ( BigLong((UWORD *)AT.WorkPointer,nr
2234 ,((UWORD *)AT.WorkPointer)+9,nnc) >= 0 )
goto redoshort;
2238 AT.WorkPointer[2] = (WORD)xx;
2241 ncoef = REDLENG(ncoef);
2242 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+2,nc) )
2244 ncoef = INCLENG(ncoef);
2246 else if ( t[FUNHEAD] > 0 && t[1] == t[FUNHEAD]+FUNHEAD
2247 && ABS(t[t[1]-1]) == t[FUNHEAD]-1-ARGHEAD && t[t[1]-1] > 0 ) {
2248 WORD nna, nnb, nni, nnb2, nnb2a;
2253 nnt = (UWORD *)(t+t[1]-1-nnb);
2254 if ( *nnt != 1 )
goto defaultcase;
2255 for ( nni = 1; nni < nnb; nni++ ) {
2256 if ( nnt[nni] != 0 )
goto defaultcase;
2258 nnt = (UWORD *)(t + FUNHEAD + ARGHEAD + 1);
2260 for ( nni = 0; nni < nnb2; nni++ ) {
2261 ((UWORD *)AT.WorkPointer)[nni] = wranf(BHEAD0);
2264 while ( nnb2a > 0 && ((UWORD *)AT.WorkPointer)[nnb2a-1] == 0 ) nnb2a--;
2266 DivLong((UWORD *)AT.WorkPointer,nnb2a
2268 ,((UWORD *)AT.WorkPointer)+2*nnb2,&nnc
2269 ,((UWORD *)AT.WorkPointer)+nnb2,&nc);
2270 for ( nni = 0; nni < nnb2; nni++ ) {
2271 ((UWORD *)AT.WorkPointer)[nni+2*nnb2] = 0;
2273 ((UWORD *)AT.WorkPointer)[3*nnb2] = 1;
2274 DivLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
2276 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc
2277 ,((UWORD *)AT.WorkPointer)+3*nnb2+1,&nca);
2278 AddLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
2279 ,((UWORD *)AT.WorkPointer)+3*nnb2+1,-nca
2280 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc);
2281 if ( BigLong((UWORD *)AT.WorkPointer,nnb2a
2282 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,nnc) >= 0 )
goto redoshort;
2286 for ( nni = 0; nni < nnb; nni++ ) {
2287 ((UWORD *)AT.WorkPointer)[nnb2+nni] = nnt[nni];
2291 ncoef = REDLENG(ncoef);
2292 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+nnb2,nc) )
2294 ncoef = INCLENG(ncoef);
2296 else goto defaultcase;
2300 if ( *t == RANPERM && t[1] > FUNHEAD && t[FUNHEAD] <= -FUNCTION ) {
2302 WORD *mm, *ww, *ow = AT.WorkPointer;
2303 WORD *Array, *targ, *argstop, narg = 0, itot;
2307 while ( targ < argstop ) {
2308 narg++; NEXTARG(targ);
2310 WantAddPointers(narg);
2311 pwork = AT.pWorkSpace + AT.pWorkPointer;
2312 targ = t+FUNHEAD+1; narg = 0;
2313 while ( targ < argstop ) {
2314 pwork[narg++] = targ;
2321 ow = AT.WorkPointer;
2322 Array = AT.WorkPointer;
2323 AT.WorkPointer += narg;
2324 for ( i = 0; i < narg; i++ ) Array[i] = i;
2325 for ( i = 2; i <= narg; i++ ) {
2326 itot = (WORD)(iranf(BHEAD i));
2327 for ( j = 0; j < itot; j++ ) CYCLE1(WORD,Array,i)
2329 mm = AT.WorkPointer;
2330 *mm++ = -t[FUNHEAD];
2332 for ( ie = 2; ie < FUNHEAD; ie++ ) *mm++ = t[ie];
2333 for ( i = 0; i < narg; i++ ) {
2334 ww = pwork[Array[i]];
2337 mm = AT.WorkPointer; t++; ww = t;
2338 i = mm[1]; NCOPY(ww,mm,i)
2339 AT.WorkPointer = ow;
2345 if ( ( t[2] & DIRTYFLAG ) != 0 && t[FUNHEAD] <= -FUNCTION
2346 && t[FUNHEAD+1] == -SNUMBER && t[FUNHEAD+2] > 0 ) {
2347 WORD *rr = t+t[1], *mm = t+FUNHEAD+3, *tt, *tt1, *tt2, num = 0;
2351 while ( mm < rr ) { num++; NEXTARG(mm); }
2352 if ( num < t[FUNHEAD+2] ) { pnco[nnco++] = t;
break; }
2354 *t = -t[FUNHEAD]; mm = t+FUNHEAD+3;
2357 while ( --i > 0 ) { NEXTARG(mm); }
2361 tt = TermMalloc(
"Select_");
2365 for ( i = 0; i < *mm; i++ ) *tt1++ = mm[i];
2368 else if ( *mm <= -FUNCTION ) { *tt1++ = *mm; }
2370 else { *tt1++ = mm[0]; *tt1++ = mm[1]; }
2374 while ( tt2 < mm ) *tt1++ = *tt2++;
2377 i = tt1-tt; tt1 = tt; tt2 = t+FUNHEAD;
2381 TermFree(tt,
"Select_");
2384 while ( argTail < rr ) *tt2++ = *argTail++;
2389 while ( argTail < rr ) *tt2++ = *argTail++;
2391 if ( functions[*t-FUNCTION].spec == TENSORFUNCTION ) {
2395 WORD *dst = t + FUNHEAD;
2396 WORD *src = dst + 1;
2398 while ( src < t + t[1] ) {
2400 dst++; src++; src++;
2405 while ( src < term + *term ) {
2412 else pnco[nnco++] = t;
2420 if ( withfloat == 0 ) {
2421 if ( TestFloat(t) == 0 )
goto defaultcase;
2426 if ( TestFloat(t) == 0 )
goto defaultcase;
2427 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
2429 UnpackFloat(aux5,t);
2430 mpf_mul(aux4,aux4,aux5);
2443 if ( t[1] <= FUNHEAD )
break;
2448 if ( *to == ARGHEAD )
goto NormZero;
2452 if ( to[ARGHEAD] != j+1 )
goto NoInteg;
2453 if ( rr >= r ) k = -1;
2454 else if ( *rr == ARGHEAD ) { k = 0; rr += ARGHEAD; }
2455 else if ( *rr == -SNUMBER ) { k = rr[1]; rr += 2; }
2457 if ( rr != r )
goto NoInteg;
2458 if ( k > 1 || k < -1 )
goto NoInteg;
2461 i = ( i < 0 ) ? -j: j;
2462 UnPack((UWORD *)to,i,&den,&num);
2470 if ( AN.NoScrat2 == 0 ) {
2471 AN.NoScrat2 = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"Normalize");
2473 if ( DivLong((UWORD *)to,num,(UWORD *)(to+j),den
2474 ,(UWORD *)AT.WorkPointer,&num,AN.NoScrat2,&den) )
goto FromNorm;
2475 if ( k < 0 && den < 0 ) {
2478 if ( AddLong((UWORD *)AT.WorkPointer,num
2479 ,AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
2482 else if ( k > 0 && den > 0 ) {
2485 if ( AddLong((UWORD *)AT.WorkPointer,num,
2486 AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
2491 else if ( *to == -SNUMBER ) {
2492 if ( to[1] < 0 ) { *AT.WorkPointer = -to[1]; num = -1; }
2493 else if ( to[1] == 0 )
goto NormZero;
2494 else { *AT.WorkPointer = to[1]; num = 1; }
2497 if ( num == 0 )
goto NormZero;
2498 ncoef = REDLENG(ncoef);
2499 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,num) )
2501 ncoef = INCLENG(ncoef);
2510 if ( *t < FUNCTION ) {
2511 MLOCK(ErrorMessageLock);
2512 MesPrint(
"Illegal code in Norm");
2516 AO.OutFill = AO.OutputLine = OutBuf;
2521 while ( --i >= 0 ) {
2522 TalToLine((UWORD)(*t++));
2523 TokenToLine((UBYTE *)
" ");
2529 MUNLOCK(ErrorMessageLock);
2532 if ( *t == REPLACEMENT ) {
2533 if ( AR.Eside != LHSIDE ) ReplaceVeto--;
2541 if ( *t == DUMMYFUN || *t == DUMMYTEN ) {}
2543 if ( *t < (FUNCTION + WILDOFFSET) ) {
2544 if ( ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2545 || ( functions[*t-FUNCTION].minnumargs > 0 ) )
2546 && ( ( t[2] & DIRTYFLAG ) != 0 ) ) {
2550 WORD *ta = t + FUNHEAD, *tb = t + t[1];
2552 while ( ta < tb ) { numarg++; NEXTARG(ta) }
2553 if ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2554 && ( numarg >= functions[*t-FUNCTION].maxnumargs ) )
2556 if ( ( functions[*t-FUNCTION].minnumargs > 0 )
2557 && ( numarg < functions[*t-FUNCTION].minnumargs ) )
2561 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION].tabl == 0 ) ) {
2563 t[2] |= DIRTYSYMFLAG;
2565 if ( functions[*t-FUNCTION].commute ) { pnco[nnco++] = t; }
2566 else { pcom[ncom++] = t; }
2569 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION-WILDOFFSET].tabl == 0 ) ) {
2571 t[2] |= DIRTYSYMFLAG;
2573 if ( functions[*t-FUNCTION-WILDOFFSET].commute ) {
2576 else { pcom[ncom++] = t; }
2582 if ( ( *t < (FUNCTION + WILDOFFSET)
2583 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) || (
2584 *t >= (FUNCTION + WILDOFFSET)
2585 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
2586 if ( *t >= GAMMA && *t <= GAMMASEVEN ) t++;
2589 if ( *t == AM.vectorzero )
goto NormZero;
2590 if ( *t >= AM.OffsetIndex && ( *t >= AM.DumInd
2591 || ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2594 else if ( *t == FUNNYWILD ) { t++; }
2609 else if ( *t <= -FUNCTION ) t++;
2610 else if ( *t == -INDEX ) {
2611 if ( t[1] >= AM.OffsetIndex &&
2612 ( t[1] >= AM.DumInd || ( t[1] < AM.WilInd
2613 && indices[t[1]-AM.OffsetIndex].dimension ) ) )
2617 else if ( *t == -SYMBOL ) {
2618 if ( t[1] >= MAXPOWER && t[1] < 2*MAXPOWER ) {
2622 else if ( t[1] < -MAXPOWER && t[1] > -2*MAXPOWER ) {
2638 r = t = ANsr; m = ANsm;
2639 ANsc = ANsm = ANsr = 0;
2652 for ( k = 0, i = 0; i < nden; i++ ) {
2654 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2655 r = t + t[1]; m = t + FUNHEAD;
2657 for ( j = i+1; j < nden; j++ ) pden[j-1] = pden[j];
2659 for ( j = 0; j < nnco; j++ )
if ( pnco[j] == t )
break;
2660 for ( j++; j < nnco; j++ ) pnco[j-1] = pnco[j];
2666 if ( m >= r )
continue;
2671 k = 1; to = termout; from = term;
2673 while ( from < t ) *to++ = *from++;
2677 *to++ = DENOMINATOR;
2678 for ( j = 1; j < FUNHEAD; j++ ) *to++ = 0;
2679 if ( *m < -FUNCTION ) *to++ = *m++;
2680 else if ( *m < 0 ) { *to++ = *m++; *to++ = *m++; }
2682 j = *m;
while ( --j >= 0 ) *to++ = *m++;
2684 stop[1] = WORDDIF(to,stop);
2687 if ( i == nden - 1 ) {
2688 stop = term + *term;
2689 while ( from < stop ) *to++ = *from++;
2690 i = *termout = WORDDIF(to,termout);
2691 to = term; from = termout;
2692 while ( --i >= 0 ) *to++ = *from++;
2697 for ( i = 0; i < nden; i++ ) {
2699 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2701 if ( t[FUNHEAD] == -SYMBOL ) {
2704 change = ExtraSymbol(*t,-1,nsym,ppsym,&ncoef);
2706 ppsym += change * 2;
2709 else if ( t[FUNHEAD] == -SNUMBER ) {
2711 if ( *t == 0 )
goto NormInf;
2712 if ( *t < 0 ) { *AT.WorkPointer = -*t; j = -1; }
2713 else { *AT.WorkPointer = *t; j = 1; }
2714 ncoef = REDLENG(ncoef);
2715 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,j) )
2717 ncoef = INCLENG(ncoef);
2720 else if ( t[FUNHEAD] == ARGHEAD )
goto NormInf;
2721 else if ( t[FUNHEAD] > 0 && t[FUNHEAD+ARGHEAD] ==
2722 t[FUNHEAD]-ARGHEAD ) {
2725 t += FUNHEAD + ARGHEAD + 1;
2727 m = r - ABS(*r) + 1;
2728 if ( j != 3 || ( ( *m != 1 ) || ( m[1] != 1 ) ) ) {
2729 ncoef = REDLENG(ncoef);
2730 if ( DivRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,REDLENG(j),(UWORD *)n_coef,&ncoef) )
goto FromNorm;
2731 ncoef = INCLENG(ncoef);
2733 t[-FUNHEAD-ARGHEAD] -= j;
2741 if ( *t == SYMBOL || *t == DOTPRODUCT ) {
2744 pden[i][FUNHEAD] -= k;
2745 pden[i][FUNHEAD+ARGHEAD] -= k;
2750 if ( *t == SYMBOL ) {
2754 change = ExtraSymbol(*t,-t[1],nsym,ppsym,&ncoef);
2756 ppsym += change * 2;
2769 while ( to < stop ) *to++ = *from++;
2773 else if ( *t == FLOATFUN && TestFloat(t) ) {
2776 pden[i][FUNHEAD] -= k;
2777 pden[i][FUNHEAD+ARGHEAD] -= k;
2778 UnpackFloat(aux5,t);
2779 if ( withfloat == 0 ) {
2780 mpf_ui_div(aux4,1,aux5);
2784 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
2785 mpf_div(aux4,aux4,aux5);
2789 while ( r < m ) *to++ = *r++;
2790 *to++ = 1; *to++ = 1; *to++ = 3;
2791 if ( ncoef < 0 ) t[-1] = -t[-1];
2799 if ( pden[i][1] == 4+FUNHEAD+ARGHEAD ) {
2801 for ( j = 0; j < nnco; j++ ) {
2802 if ( pden[i] == pnco[j] ) {
2804 while ( j < nnco ) {
2805 pnco[j] = pnco[j+1];
2811 pden[i--] = pden[--nden];
2822 for ( i = 0; i < ndel; i += 2 ) {
2823 if ( t[0] == t[1] ) {
2824 if ( t[0] == EMPTYINDEX ) {}
2825 else if ( *t < AM.OffsetIndex ) {
2826 k = AC.FixIndices[*t];
2827 if ( k < 0 ) { j = -1; k = -k; }
2828 else if ( k > 0 ) j = 1;
2832 else if ( *t >= AM.DumInd ) {
2834 if ( k )
goto docontract;
2836 else if ( *t >= AM.WilInd ) {
2837 k = indices[*t-AM.OffsetIndex-WILDOFFSET].dimension;
2838 if ( k )
goto docontract;
2840 else if ( ( k = indices[*t-AM.OffsetIndex].dimension ) != 0 ) {
2844WithFix: shortnum = k;
2845 ncoef = REDLENG(ncoef);
2846 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),j) )
2848 ncoef = INCLENG(ncoef);
2852 change = ExtraSymbol((WORD)(-k),(WORD)1,nsym,ppsym,&ncoef);
2854 ppsym += change * 2;
2856 t[1] = pdel[ndel-1];
2857 t[0] = pdel[ndel-2];
2864 if ( *t < AM.OffsetIndex && t[1] < AM.OffsetIndex )
goto NormZero;
2865 j = *t - AM.OffsetIndex;
2866 if ( j >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
2867 || ( *t < AM.WilInd && indices[j].dimension ) ) ) {
2868 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2871 *m++ = pdel[ndel-2];
2875 else if ( *t == m[1] ) {
2877 *m++ = pdel[ndel-2];
2883 j = t[1]-AM.OffsetIndex;
2884 if ( j >= 0 && ( ( t[1] >= AM.DumInd && AC.lDefDim )
2885 || ( t[1] < AM.WilInd && indices[j].dimension ) ) ) {
2886 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2889 *m++ = pdel[ndel-2];
2893 else if ( t[1] == m[1] ) {
2895 *m++ = pdel[ndel-2];
2907 for ( i = 0; i < ndel; i++ ) {
2908 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2909 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2911 for ( j = 1; j < nvec; j += 2 ) {
2915 *t-- = pdel[--ndel];
2920 t[1] = pdel[--ndel];
2923 *t-- = pdel[--ndel];
2932 if ( ndel > 0 && ncon ) {
2934 for ( i = 0; i < ndel; i++ ) {
2935 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2936 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2937 for ( j = 0; j < ncon; j++ ) {
2938 if ( *pcon[j] == *t ) {
2941 *t-- = pdel[--ndel];
2946 t[1] = pdel[--ndel];
2949 *t-- = pdel[--ndel];
2952 for ( j = 0; j < nnco; j++ ) {
2954 if ( r > m && r < m+m[1] ) {
2955 m[2] |= DIRTYSYMFLAG;
2959 for ( j = 0; j < ncom; j++ ) {
2961 if ( r > m && r < m+m[1] ) {
2962 m[2] |= DIRTYSYMFLAG;
2966 for ( j = 0; j < neps; j++ ) {
2968 if ( r > m && r < m+m[1] ) {
2969 m[2] |= DIRTYSYMFLAG;
2984 for ( i = 3; i < nvec; i += 2 ) {
2985 k = *t - AM.OffsetIndex;
2986 if ( k >= 0 && ( ( *t > AM.DumInd && AC.lDefDim )
2987 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
2989 for ( j = i; j < nvec; j += 2 ) {
2995 *r-- = pvec[--nvec];
2997 *t-- = pvec[--nvec];
2998 *t-- = pvec[--nvec];
3007 if ( nvec > 0 && ncon ) {
3009 for ( i = 1; i < nvec; i += 2 ) {
3010 k = *t - AM.OffsetIndex;
3011 if ( k >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
3012 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
3013 for ( j = 0; j < ncon; j++ ) {
3014 if ( *pcon[j] == *t ) {
3016 *t-- = pvec[--nvec];
3017 *t-- = pvec[--nvec];
3019 pcon[j] = pcon[--ncon];
3021 for ( j = 0; j < nnco; j++ ) {
3023 if ( r > m && r < m+m[1] ) {
3024 m[2] |= DIRTYSYMFLAG;
3028 for ( j = 0; j < ncom; j++ ) {
3030 if ( r > m && r < m+m[1] ) {
3031 m[2] |= DIRTYSYMFLAG;
3035 for ( j = 0; j < neps; j++ ) {
3037 if ( r > m && r < m+m[1] ) {
3038 m[2] |= DIRTYSYMFLAG;
3056 for ( i = 0; i < nnco; i++ ) {
3058 if ( ( *t >= (FUNCTION+WILDOFFSET)
3059 && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
3060 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3061 && functions[*t-FUNCTION].spec <= 0 ) ) {
3067 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
3070 pnco[i][2] |= DIRTYSYMFLAG;
3082 for ( i = 0; i < nnco; i++ ) {
3084 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) && *t != DOLLAREXPRESSION ) {
3086 if ( ( *t >= (FUNCTION+WILDOFFSET)
3087 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
3088 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3089 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
3090 if ( *t >= (FUNCTION+WILDOFFSET) ) {
3092 j = FullSymmetrize(BHEAD t,l);
3095 else j = FullSymmetrize(BHEAD t,l);
3096 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3097 if ( ( j & 2 ) != 0 )
goto NormZero;
3098 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
3101 else t[2] &= ~DIRTYSYMFLAG;
3109 for ( i = 0; i < k; i++ ) {
3111 while ( Commute(pnco[j],pnco[j+1]) ) {
3112 t = pnco[j]; pnco[j] = pnco[j+1]; pnco[j+1] = t;
3114 while ( l >= 0 && Commute(pnco[l],pnco[l+1]) ) {
3115 t = pnco[l]; pnco[l] = pnco[l+1]; pnco[l+1] = t;
3118 if ( ++j >= k )
break;
3125 for ( i = 0; i < nnco; i++ ) {
3127 if ( *t == IDFUNCTION ) AN.idfunctionflag = 1;
3128 if ( *t >= GAMMA && *t <= GAMMASEVEN ) {
3134 *m++ = stype = t[FUNHEAD];
3139 if ( *t == GAMMAFIVE ) {
3140 gtype = GAMMA5; t += FUNHEAD;
goto onegammamatrix; }
3141 else if ( *t == GAMMASIX ) {
3142 gtype = GAMMA6; t += FUNHEAD;
goto onegammamatrix; }
3143 else if ( *t == GAMMASEVEN ) {
3144 gtype = GAMMA7; t += FUNHEAD;
goto onegammamatrix; }
3149 if ( gtype == GAMMA5 ) {
3150 if ( j == GAMMA1 ) j = GAMMA5;
3151 else if ( j == GAMMA5 ) j = GAMMA1;
3152 else if ( j == GAMMA7 ) ncoef = -ncoef;
3153 if ( nnum & 1 ) ncoef = -ncoef;
3155 else if ( gtype == GAMMA6 || gtype == GAMMA7 ) {
3157 if ( gtype == GAMMA6 ) gtype = GAMMA7;
3158 else gtype = GAMMA6;
3160 if ( j == GAMMA1 ) j = gtype;
3161 else if ( j == GAMMA5 ) {
3163 if ( j == GAMMA7 ) ncoef = -ncoef;
3165 else if ( j != gtype )
goto NormZero;
3168 ncoef = REDLENG(ncoef);
3169 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),1) )
goto FromNorm;
3170 ncoef = INCLENG(ncoef);
3174 *m++ = gtype; nnum++;
3179 }
while ( ( ++i < nnco ) && ( *(t = pnco[i]) >= GAMMA
3180 && *t <= GAMMASEVEN ) && ( t[FUNHEAD] == stype ) );
3183 k = WORDDIF(m,to) - FUNHEAD-1;
3186 while ( --k >= 0 ) *from-- = *--r;
3189 to[1] = WORDDIF(m,to);
3191 else if ( *t < 0 ) {
3192 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3196 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
3197 && *t != REPLACEMENT && *t != DOLLAREXPRESSION
3198 && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
3210 for ( i = 0; i < ncom; i++ ) {
3212 if ( ( *t >= (FUNCTION+WILDOFFSET)
3213 && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
3214 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3215 && functions[*t-FUNCTION].spec <= 0 ) ) {
3221 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
3224 pcom[i][2] |= DIRTYSYMFLAG;
3234 for ( i = 0; i < ncom; i++ ) {
3236 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) ) {
3238 if ( ( *t >= (FUNCTION+WILDOFFSET)
3239 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
3240 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3241 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
3242 if ( *t >= (FUNCTION+WILDOFFSET) ) {
3244 j = FullSymmetrize(BHEAD t,l);
3247 else j = FullSymmetrize(BHEAD t,l);
3248 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3249 if ( ( j & 2 ) != 0 )
goto NormZero;
3250 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
3253 else t[2] &= ~DIRTYSYMFLAG;
3262 for ( i = 1; i < ncom; i++ ) {
3263 for ( j = i; j > 0; j-- ) {
3269 if ( *r < 0 ) {
if ( *t >= *r )
goto NextI; }
3270 else {
if ( -*t <= *r )
goto NextI; }
3273 else if ( *r < 0 ) {
3274 if ( *t < -*r )
goto NextI;
3277 else if ( *t != *r ) {
3278 if ( *t < *r )
goto NextI;
3279jexch: t = pcom[j]; pcom[j] = pcom[jj]; pcom[jj] = t;
3282 if ( AC.properorderflag ) {
3283 if ( ( *t >= (FUNCTION+WILDOFFSET)
3284 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION )
3285 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3286 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) ) {}
3288 WORD *s1, *s2, *ss1, *ss2;
3289 s1 = t+FUNHEAD; s2 = r+FUNHEAD;
3290 ss1 = t + t[1]; ss2 = r + r[1];
3291 while ( s1 < ss1 && s2 < ss2 ) {
3293 if ( k > 0 )
goto jexch;
3294 if ( k < 0 )
goto NextI;
3298 if ( s1 < ss1 )
goto jexch;
3302 kk = r[1] - FUNHEAD;
3305 while ( k > 0 && kk > 0 ) {
3306 if ( *t < *r )
goto NextI;
3307 else if ( *t++ > *r++ )
goto jexch;
3310 if ( k > 0 )
goto jexch;
3316 kk = r[1] - FUNHEAD;
3319 while ( k > 0 && kk > 0 ) {
3320 if ( *t < *r )
goto NextI;
3321 else if ( *t++ > *r++ )
goto jexch;
3324 if ( k > 0 )
goto jexch;
3330 for ( i = 0; i < ncom; i++ ) {
3332 if ( *t == THETA || *t == THETA2 ) {
3333 if ( ( k = DoTheta(BHEAD t) ) == 0 )
goto NormZero;
3339 else if ( *t == DELTA2 || *t == DELTAP ) {
3340 if ( ( k = DoDelta(t) ) == 0 )
goto NormZero;
3346 else if ( *t == AR.PolyFunInv && AR.PolyFunType == 2 ) {
3351 WORD *mm, *tt = t, numt = 0;
3353 while ( tt < t+t[1] ) { numt++; NEXTARG(tt) }
3355 tt = t; mm = m; k = t[1];
3361 if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
3362 else { *tt++ = *mm++; *tt++ = *mm++; }
3365 k = *mm; NCOPY(tt,mm,k)
3369 if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
3370 else { *tt++ = *mm++; *tt++ = *mm++; }
3373 k = *mm; NCOPY(tt,mm,k)
3376 t[2] |= MUSTCLEANPRF;
3380 else if ( *t == AR.PolyFun ) {
3381 if ( AR.PolyFunType == 1 ) {
3382 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3383 t[1] == FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER )
goto NormZero;
3384 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) {
3385 if ( AN.PolyNormFlag == 0 ) {
3386 AN.PolyNormFlag = 1;
3393 else if ( AR.PolyFunType == 2 ) {
3404 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3405 t[1] > FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER ) {
3406 u = t + FUNHEAD + 2;
3408 if ( *u <= -FUNCTION ) {}
3409 else if ( t[1] == FUNHEAD+4 && t[FUNHEAD+2] == -SNUMBER
3410 && t[FUNHEAD+3] == 0 )
goto NormPRF;
3411 else if ( t[1] == FUNHEAD+4 )
goto NormZero;
3413 else if ( t[1] == *u+FUNHEAD+2 )
goto NormZero;
3416 u = t+FUNHEAD; NEXTARG(u);
3417 if ( *u == -SNUMBER && u[1] == 0 )
goto NormInf;
3419 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3420 else if ( i < ncom-1 && pcom[i+1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3422 if ( AN.PolyNormFlag ) {
3423 if ( AR.PolyFunExp == 0 ) {
3427 else if ( AR.PolyFunExp == 1 ) {
3428 if ( PolyFunMode == 0 ) {
3435 if ( TreatPolyRatFun(BHEAD mmm) != 0 )
3441 if ( PolyFunMode == 0 ) {
3448 if ( ExpandRat(BHEAD mmm) != 0 )
3455 if ( AR.PolyFunExp == 0 ) {
3459 else if ( AR.PolyFunExp == 1 ) {
3462 if ( TreatPolyRatFun(BHEAD mmm) != 0 )
3469 if ( ExpandRat(BHEAD mmm) != 0 )
3476 else if ( *t > 0 ) {
3477 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
3478 && *t != REPLACEMENT && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
3483 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3492 if ( ReplaceVeto < 0 ) {
3502 WORD *ma = fillsetexp, *mb, *mc;
3505 if ( *ma != REPLACEMENT ) {
3509 if ( *ma == REPLACEMENT && ReplaceType == -1 ) {
3512 if ( AN.RSsize < 2*ma[1]+SUBEXPSIZE ) {
3513 if ( AN.ReplaceScrat ) M_free(AN.ReplaceScrat,
"AN.ReplaceScrat");
3514 AN.RSsize = 2*ma[1]+SUBEXPSIZE+40;
3515 AN.ReplaceScrat = (WORD *)Malloc1((AN.RSsize+1)*
sizeof(WORD),
"AN.ReplaceScrat");
3518 ReplaceSub = AN.ReplaceScrat;
3519 ReplaceSub += SUBEXPSIZE;
3521 if ( *ma > 0 )
goto NoRep;
3522 if ( *ma <= -FUNCTION ) {
3523 *ReplaceSub++ = FUNTOFUN;
3525 *ReplaceSub++ = -*ma++;
3526 if ( *ma > -FUNCTION )
goto NoRep;
3527 *ReplaceSub++ = -*ma++;
3529 else if ( ma+4 > mb )
goto NoRep;
3531 if ( *ma == -SYMBOL ) {
3532 if ( ma[2] == -SYMBOL && ma+4 <= mb )
3533 *ReplaceSub++ = SYMTOSYM;
3534 else if ( ma[2] == -SNUMBER && ma+4 <= mb ) {
3535 *ReplaceSub++ = SYMTONUM;
3536 if ( ReplaceType == 0 ) {
3537 oldtoprhs = C->numrhs;
3542 else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
3543 *ReplaceSub++ = SYMTONUM;
3545 *ReplaceSub++ = ma[1];
3554 else if ( ma[2] > 0 ) {
3555 WORD *sstop, *ttstop, n;
3559 while ( ss < sstop ) {
3561 ttstop = tt - ABS(tt[-1]);
3563 while ( ss < ttstop ) {
3564 if ( *ss == INDEX )
goto NoRep;
3570 if ( ReplaceType == 0 ) {
3571 oldtoprhs = C->numrhs;
3575 ss =
AddRHS(AT.ebufnum,1);
3580 while ( --n >= 0 ) *ss++ = *tt++;
3582 C->
rhs[C->numrhs+1] = ss;
3584 *ReplaceSub++ = subtype;
3586 *ReplaceSub++ = ma[1];
3587 *ReplaceSub++ = C->numrhs;
3593 else if ( ( *ma == -VECTOR || *ma == -MINVECTOR ) && ma+4 <= mb ) {
3594 if ( ma[2] == -VECTOR ) {
3595 if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOVEC;
3596 else *ReplaceSub++ = VECTOMIN;
3598 else if ( ma[2] == -MINVECTOR ) {
3599 if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOMIN;
3600 else *ReplaceSub++ = VECTOVEC;
3606 else if ( ma[2] > 0 ) {
3607 WORD *sstop, *ttstop, *w, *mm, n, count;
3609 if ( *ma == -MINVECTOR ) {
3613 while ( ss < sstop ) {
3622 while ( ss < sstop ) {
3624 ttstop = tt - ABS(tt[-1]);
3627 while ( ss < ttstop ) {
3628 if ( *ss == INDEX ) {
3629 n = ss[1] - 2; ss += 2;
3630 while ( --n >= 0 ) {
3631 if ( *ss < MINSPEC ) count++;
3637 if ( count != 1 )
goto NoRep;
3641 if ( ReplaceType == 0 ) {
3642 oldtoprhs = C->numrhs;
3646 mm =
AddRHS(AT.ebufnum,1);
3647 *ReplaceSub++ = subtype;
3649 *ReplaceSub++ = ma[1];
3650 *ReplaceSub++ = C->numrhs;
3654 while ( (mm + n + 10) > C->
Top )
3656 while ( --n >= 0 ) *mm++ = *w++;
3658 C->
rhs[C->numrhs+1] = mm;
3660 mm =
AddRHS(AT.ebufnum,1);
3664 while ( (mm + n + 13) > C->
Top )
3667 while ( w < sstop ) {
3668 tt = w + *w; ttstop = tt - ABS(tt[-1]);
3670 while ( w < ttstop ) {
3671 if ( *w != INDEX ) {
3680 while ( --n >= 0 ) {
3681 if ( *w >= MINSPEC ) *mm++ = *w++;
3686 if ( n <= 2 ) mm -= 2;
3695 while ( w < tt ) *mm++ = *w++;
3696 *ss = WORDDIF(mm,ss);
3699 C->
rhs[C->numrhs+1] = mm;
3701 if ( mm > C->
Top ) {
3702 MLOCK(ErrorMessageLock);
3703 MesPrint(
"Internal error in Normalize with extra compiler buffer");
3704 MUNLOCK(ErrorMessageLock);
3712 else if ( *ma == -INDEX ) {
3713 if ( ( ma[2] == -INDEX || ma[2] == -VECTOR )
3715 *ReplaceSub++ = INDTOIND;
3716 else if ( ma[1] >= AM.OffsetIndex ) {
3717 if ( ma[2] == -SNUMBER && ma+4 <= mb
3718 && ma[3] >= 0 && ma[3] < AM.OffsetIndex )
3719 *ReplaceSub++ = INDTOIND;
3720 else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
3721 *ReplaceSub++ = INDTOIND;
3723 *ReplaceSub++ = ma[1];
3734 *ReplaceSub++ = ma[1];
3735 *ReplaceSub++ = ma[3];
3740 AN.ReplaceScrat[1] = ReplaceSub-AN.ReplaceScrat;
3745 while ( mb < m ) *mc++ = *mb++;
3749 if ( ReplaceType > 0 ) {
3750 C->numrhs = oldtoprhs;
3754 if ( ++ReplaceVeto >= 0 )
break;
3765 for ( i = 0; i < neps; i++ ) {
3767 if ( ( t[2] & DIRTYSYMFLAG ) != DIRTYSYMFLAG )
continue;
3768 t[2] &= ~DIRTYSYMFLAG;
3769 if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
3778 if ( *r != FUNNYWILD ) { r++;
continue; }
3779 k = r[1]; u = r + 2;
3782 if ( *u != FUNNYWILD ) ncoef = -ncoef;
3785 tt[-2] = FUNNYWILD; tt[-1] = k; m -= 2;
3789 for ( r = t + 1; r < m; r++ ) {
3790 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3791 else if ( *r == *t )
goto NormZero;
3796 for ( r = t + 2; r < tt; r += 2 ) {
3797 if ( r[1] < t[1] ) {
3798 k = r[1]; r[1] = t[1]; t[1] = k; ncoef = -ncoef; }
3799 else if ( r[1] == t[1] )
goto NormZero;
3808 for ( r = t + 1; r < m; r++ ) {
3809 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3810 else if ( *r == *t )
goto NormZero;
3819 for ( i = 0; i < (neps-1); i++ ) {
3821 for ( j = i+1; j < neps; j++ ) {
3823 if ( t[1] > r[1] ) {
3824 peps[i] = m = r; peps[j] = r = t; t = m;
3826 else if ( t[1] == r[1] ) {
3832 m = peps[j]; peps[j] = t; peps[i] = t = m;
3835 else if ( *r++ > *m++ )
break;
3836 }
while ( --k > 0 );
3841 for ( i = 0; i < neps; i++ ) {
3853 for ( i = 0; i < ndel; i += 2, r += 2 ) {
3854 if ( r[1] < r[0] ) { k = *r; *r = r[1]; r[1] = k; }
3856 for ( i = 2; i < ndel; i += 2, t += 2 ) {
3858 for ( j = i; j < ndel; j += 2 ) {
3859 if ( *r > *t ) { r += 2; }
3860 else if ( *r < *t ) {
3861 k = *r; *r++ = *t; *t++ = k;
3862 k = *r; *r++ = *t; *t-- = k;
3865 if ( *++r < t[1] ) {
3866 k = *r; *r = t[1]; t[1] = k;
3884 for ( i = 0; i < nind; i++ ) {
3886 for ( j = i+1; j < nind; j++ ) {
3888 k = *r; *r = *t; *t = k;
3906 for ( i = 2; i < nvec; i += 2 ) {
3908 for ( j = i; j < nvec; j += 2 ) {
3910 if ( *++r < t[1] ) {
3911 k = *r; *r = t[1]; t[1] = k;
3915 else if ( *r < *t ) {
3916 k = *r; *r++ = *t; *t++ = k;
3917 k = *r; *r++ = *t; *t-- = k;
3937 while ( --i >= 0 ) {
3938 if ( *t > t[1] ) { j = *t; *t = t[1]; t[1] = j; }
3944 while ( t < (m-3) ) {
3948 if ( *++r == *++t ) {
3950 if ( ( *r < MAXPOWER && t[1] < MAXPOWER )
3951 || ( *r > -MAXPOWER && t[1] > -MAXPOWER ) ) {
3954 if ( *t > MAXPOWER || *t < -MAXPOWER ) {
3955 MLOCK(ErrorMessageLock);
3956 MesPrint(
"Exponent of dotproduct out of range: %d",*t);
3957 MUNLOCK(ErrorMessageLock);
3973 else if ( *r < *++t ) {
3974 k = *r; *r++ = *t; *t = k;
3979 else if ( *r < *t ) {
3980 k = *r; *r++ = *t; *t++ = k;
3981 k = *r; *r++ = *t; *t = k;
3984 else { r += 2; t--; }
3986 else if ( *r < *t ) {
3987 k = *r; *r++ = *t; *t++ = k;
3988 k = *r; *r++ = *t; *t++ = k;
3989 k = *r; *r++ = *t; *t = k;
3998 if ( ( i = ndot ) > 0 ) {
4013 *m++ = ( i = nsym ) + 2;
4016 if ( t[1] < (2*MAXPOWER) ) {
4017 if ( t[1] & 1 ) { *m++ = 0; *m++ = 1; }
4019 if ( *++t & 2 ) ncoef = -ncoef;
4023 else if ( *t <= NumSymbols && *t > -2*MAXPOWER ) {
4024 if ( ( ( ( t[1] > symbols[*t].maxpower ) && ( symbols[*t].maxpower < MAXPOWER ) ) ||
4025 ( ( t[1] < symbols[*t].minpower ) && ( symbols[*t].minpower > -MAXPOWER ) ) ) &&
4026 ( t[1] < 2*MAXPOWER ) && ( t[1] > -2*MAXPOWER ) ) {
4027 if ( i <= 2 || t[2] != *t )
goto NormZero;
4029 if ( AN.ncmod == 1 && ( AC.modmode & ALSOPOWERS ) != 0 ) {
4030 if ( AC.cmod[0] == 1 ) t[1] = 0;
4031 else if ( t[1] >= 0 ) t[1] = 1 + (t[1]-1)%(AC.cmod[0]-1);
4033 t[1] = -1 - (-t[1]-1)%(AC.cmod[0]-1);
4034 if ( t[1] < 0 ) t[1] += (AC.cmod[0]-1);
4037 if ( ( t[1] < (2*MAXPOWER) && t[1] >= MAXPOWER )
4038 || ( t[1] > -(2*MAXPOWER) && t[1] <= -MAXPOWER ) ) {
4039 MLOCK(ErrorMessageLock);
4040 MesPrint(
"Exponent out of range: %d",t[1]);
4041 MUNLOCK(ErrorMessageLock);
4044 if ( AT.TrimPower && AR.PolyFunVar == *t && t[1] > AR.PolyFunPow ) {
4051 else { *r -= 2; t += 2; }
4054 *m++ = *t++; *m++ = *t++;
4056 }
while ( (i-=2) > 0 ); }
4057 if ( *r <= 2 ) m = r-1;
4073 if ( ABS(ncoef) == 3 && n_coef[0] == 1 && n_coef[1] == 1 ) {
4074 if ( withfloat == 1 ) {
4080 if ( t[FUNHEAD+3] < 0 ) {
4081 t[FUNHEAD+3] = -t[FUNHEAD+3];
4082 floatsign = -floatsign;
4084 if ( ncoef < 0 ) floatsign = -floatsign;
4088 AT.FloatPos = m-termout;
4089 i = t[1]; NCOPY(m,t,i)
4093 if ( m[FUNHEAD+3] < 0 ) {
4094 m[FUNHEAD+3] = -m[FUNHEAD+3];
4095 floatsign = -floatsign;
4097 if ( ncoef < 0 ) floatsign = -floatsign;
4098 AT.FloatPos = m-termout;
4103 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
4104 RatToFloat(aux5,(UWORD *)n_coef,ncoef);
4105 mpf_mul(aux4,aux4,aux5);
4107 AT.FloatPos = m-termout;
4108 if ( m[FUNHEAD+3] < 0 ) {
4109 m[FUNHEAD+3] = -m[FUNHEAD+3];
4110 floatsign = -floatsign;
4114 n_coef[0] = 1; n_coef[1] = 1; ncoef = floatsign;
4116 else AT.FloatPos = 0;
4123 stop = (WORD *)(((UBYTE *)(termout)) + AM.MaxTer);
4125 if ( ( m + i ) > stop ) {
4126 MLOCK(ErrorMessageLock);
4127 MesPrint(
"Term too complex during normalization");
4128 MUNLOCK(ErrorMessageLock);
4131 if ( AT.SS == AT.S0 ) {
4132 if ( ( m + i - termout ) > AT.SS->verbMaxTermSize ) {
4133 AT.SS->verbMaxTermSize = m+i-termout;
4136 if ( ReplaceType >= 0 ) {
4143 if ( ReplaceType == 0 ) {
4144 AT.WorkPointer = termout+*termout;
4145 WildFill(BHEAD term,termout,AN.ReplaceScrat);
4146 termout = term + *term;
4149 AT.WorkPointer = r = termout + *termout;
4150 WildFill(BHEAD r,termout,AN.ReplaceScrat);
4157 r += *term; r -= ABS(r[-1]);
4160 if ( *m >= FUNCTION && m[1] > FUNHEAD &&
4161 functions[*m-FUNCTION].spec != TENSORFUNCTION )
4175 TermFree(n_llnum,
"n_llnum");
4176 TermFree(n_coef,
"NormCoef");
4195 if ( termout < term + *term && termout >= term ) AT.WorkPointer = term + *term;
4196 else AT.WorkPointer = termout;
4203 TermFree(n_llnum,
"n_llnum");
4204 TermFree(n_coef,
"NormCoef");
4208 MLOCK(ErrorMessageLock);
4209 MesPrint(
"Division by zero during normalization");
4210 MUNLOCK(ErrorMessageLock);
4214 MLOCK(ErrorMessageLock);
4215 MesPrint(
"0^0 during normalization of term");
4216 MUNLOCK(ErrorMessageLock);
4220 MLOCK(ErrorMessageLock);
4221 MesPrint(
"0/0 in polyratfun during normalization of term");
4222 MUNLOCK(ErrorMessageLock);
4227 AT.WorkPointer = termout;
4229 TermFree(n_llnum,
"n_llnum");
4230 TermFree(n_coef,
"NormCoef");
4235 TermFree(n_llnum,
"n_llnum");
4236 TermFree(n_coef,
"NormCoef");
4240 MLOCK(ErrorMessageLock);
4242 MUNLOCK(ErrorMessageLock);
4244 TermFree(n_llnum,
"n_llnum");
4245 TermFree(n_coef,
"NormCoef");
4258int ExtraSymbol(WORD sym, WORD pow, WORD nsym, WORD *ppsym, WORD *ncoef)
4266 if ( pow > 2*MAXPOWER || pow < -2*MAXPOWER
4267 || *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
4268 MLOCK(ErrorMessageLock);
4269 MesPrint(
"Illegal wildcard power combination.");
4270 MUNLOCK(ErrorMessageLock);
4275 if ( ( sym <= NumSymbols && sym > -MAXPOWER )
4276 && ( symbols[sym].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
4277 *m %= symbols[sym].maxpower;
4278 if ( *m < 0 ) *m += symbols[sym].maxpower;
4279 if ( ( symbols[sym].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
4280 if ( ( ( symbols[sym].maxpower & 1 ) == 0 ) &&
4281 ( *m >= symbols[sym].maxpower/2 ) ) {
4282 *m -= symbols[sym].maxpower/2; *ncoef = -*ncoef;
4287 if ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
4288 MLOCK(ErrorMessageLock);
4289 MesPrint(
"Power overflow during normalization");
4290 MUNLOCK(ErrorMessageLock);
4296 { *m = m[2]; m++; *m = m[2]; m++; i++; }
4301 else if ( sym < *m ) {
4309 { m--; m[2] = *m; m--; m[2] = *m; i++; }
4320int DoTheta(PHEAD WORD *t)
4323 WORD k, *r1, *r2, *tstop, type;
4324 WORD ia, *ta, *tb, *stopa, *stopb;
4325 if ( AC.BracketNormalize )
return(-1);
4330 if ( k <= FUNHEAD )
return(1);
4333 if ( r1 == tstop ) {
4337 if ( *t == ARGHEAD ) {
4338 if ( type == THETA )
return(1);
4342 if ( *t == -SNUMBER ) {
4343 if ( t[1] < 0 )
return(0);
4345 if ( type == THETA2 && t[1] == 0 )
return(0);
4352 if ( *t == ABS(k)+1+ARGHEAD ) {
4353 if ( k > 0 )
return(1);
4363 if ( r2 < tstop )
return(-1);
4368 if ( *t == -SNUMBER && *r1 == -SNUMBER ) {
4369 if ( t[1] > r1[1] )
return(0);
4370 else if ( t[1] < r1[1] ) {
4373 else if ( type == THETA )
return(1);
4376 else if ( t[1] == 0 && *t == -SNUMBER ) {
4378 else if ( *t < *r1 )
return(1);
4379 else if ( *t > *r1 )
return(0);
4381 else if ( r1[1] == 0 && *r1 == -SNUMBER ) {
4383 else if ( *t < *r1 )
return(1);
4384 else if ( *t > *r1 )
return(0);
4386 r2 = AT.WorkPointer;
4400 ta += ARGHEAD; tb += ARGHEAD;
4401 while ( ta < stopa ) {
4402 if ( tb >= stopb )
return(0);
4403 if ( ( ia = CompareTerms(BHEAD ta,tb,(WORD)1) ) < 0 )
return(0);
4404 if ( ia > 0 )
return(1);
4408 if ( type == THETA )
return(1);
4419 WORD k, *r1, *r2, *tstop, isnum, isnum2, type = *t;
4420 if ( AC.BracketNormalize )
return(-1);
4422 if ( k <= FUNHEAD )
goto argzero;
4423 if ( k == FUNHEAD+ARGHEAD && t[FUNHEAD] == ARGHEAD )
goto argzero;
4430 if ( *t == -SNUMBER ) { isnum = 1; k = t[1]; }
4436 if ( k == *t-ARGHEAD-1 ) isnum = 1;
4440 if ( r1 >= tstop ) {
4441 if ( !isnum )
return(-1);
4442 if ( k == 0 )
goto argzero;
4447 if ( r2 < tstop )
return(-1);
4449 if ( *r1 == -SNUMBER ) { isnum2 = 1; }
4455 if ( k == *r1-ARGHEAD-1 ) isnum2 = 1;
4458 if ( isnum != isnum2 )
return(-1);
4460 while ( t < tstop && r1 < r2 ) {
4462 if ( !isnum )
return(-1);
4467 if ( t != tstop || r1 != r2 ) {
4468 if ( !isnum )
return(-1);
4472 if ( type == DELTA2 )
return(1);
4475 if ( type == DELTA2 )
return(0);
4484void DoRevert(WORD *fun, WORD *tmp)
4486 WORD *t, *r, *m, *to, *tt, *mm, i, j;
4491 if ( *r == -REVERSEFUNCTION ) {
4493 while ( mm < to ) *m++ = *mm++;
4496 fun[2] |= DIRTYSYMFLAG;
4498 else if ( *r <= -FUNCTION ) r++;
4500 if ( *r == -INDEX && r[1] < MINSPEC ) *r = -VECTOR;
4505 if ( ( *r > ARGHEAD )
4506 && ( r[ARGHEAD+1] == REVERSEFUNCTION )
4507 && ( *r == (r[ARGHEAD]+ARGHEAD) )
4508 && ( r[ARGHEAD] == (r[ARGHEAD+2]+4) )
4509 && ( *(r+*r-3) == 1 )
4510 && ( *(r+*r-2) == 1 )
4511 && ( *(r+*r-1) == 3 ) ) {
4523 while ( --j >= 0 ) {
4526 while ( --i >= 0 ) {
4533 else if ( *t <= -FUNCTION ) *m++ = *t++;
4534 else { *m++ = *t++; *m++ = *t++; }
4545 fun[1] = WORDDIF(t,fun);
4547 fun[2] |= DIRTYSYMFLAG;
4570#define MAXNUMBEROFNONCOMTERMS 2
4572WORD DetCommu(WORD *terms)
4574 WORD *t, *tnext, *tstop;
4576 if ( *terms == 0 )
return(0);
4577 if ( terms[*terms] == 0 )
return(0);
4581 tstop = tnext - ABS(tnext[-1]);
4583 while ( t < tstop ) {
4584 if ( *t >= FUNCTION ) {
4585 if ( functions[*t-FUNCTION].commute ) {
4587 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4591 else if ( *t == SUBEXPRESSION ) {
4592 if ( cbuf[t[4]].CanCommu[t[2]] ) {
4594 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4598 else if ( *t == EXPRESSION ) {
4600 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4603 else if ( *t == DOLLAREXPRESSION ) {
4610 if ( cbuf[AM.dbufnum].CanCommu[t[2]] ) {
4612 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4631WORD DoesCommu(WORD *term)
4635 if ( *term == 0 )
return(0);
4636 tstop = term + *term;
4637 tstop = tstop - ABS(tstop[-1]);
4639 while ( term < tstop ) {
4640 if ( ( *term >= FUNCTION ) && ( functions[*term-FUNCTION].commute ) ) {
4642 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4657WORD *PolyNormPoly (PHEAD WORD *Poly) {
4660 WORD *buffer = AT.WorkPointer;
4662 if (
NewSort(BHEAD0) ) { Terminate(-1); }
4668 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4674 if (
EndSort(BHEAD buffer,1) < 0 ) {
4675 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4679 while ( *p ) p += *p;
4680 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4681 AT.WorkPointer = p + 1;
4708WORD *EvaluateGcd(PHEAD WORD *subterm)
4711 WORD *oldworkpointer = AT.WorkPointer, *work1, *work2, *work3;
4712 WORD *t, *tt, *ttt, *t1, *t2, *t3, *t4, *tstop;
4715 WORD *lnum=n_llnum+1;
4716 WORD *num1, *num2, *num3, *den1, *den2, *den3;
4717 WORD sizenum1, sizenum2, sizenum3, sizeden1, sizeden2, sizeden3;
4718 int i, isnumeric = 0, numarg = 0 ;
4724 tt = subterm + subterm[1]; t = subterm + FUNHEAD;
4728 if ( *t == -SNUMBER ) {
4731 MLOCK(ErrorMessageLock);
4732 MesPrint(
"Trying to take the GCD involving a zero term.");
4733 MUNLOCK(ErrorMessageLock);
4737 t1 = subterm + FUNHEAD;
4738 while ( gcdnum > 1 && t1 < tt ) {
4739 if ( *t1 == -SNUMBER ) {
4741 if ( stor == 0 )
goto gcdzero;
4742 if ( GcdLong(BHEAD (UWORD *)&stor,1,(UWORD *)&gcdnum,1,
4743 (UWORD *)lnum,&nnum) )
goto FromGCD;
4748 else if ( *t1 == -SYMBOL )
goto gcdisone;
4749 else if ( *t1 < 0 )
goto gcdillegal;
4755 ct = *ttt; *ttt = 0;
4757 t1 = PolyNormPoly(BHEAD t1+ARGHEAD);
4766 while ( t3 > t2 && *t3 == 0 ) { t3--; i--; }
4767 if ( GcdLong(BHEAD (UWORD *)t2,(WORD)i,(UWORD *)&gcdnum,1,
4768 (UWORD *)lnum,&nnum) ) {
4773 if ( gcdnum == 1 ) {
4780 AT.WorkPointer = oldworkpointer;
4782 if ( gcdnum == 1 )
goto gcdisone;
4783 oldworkpointer[0] = 4;
4784 oldworkpointer[1] = gcdnum;
4785 oldworkpointer[2] = 1;
4786 oldworkpointer[3] = 3;
4787 oldworkpointer[4] = 0;
4788 AT.WorkPointer = oldworkpointer + 5;
4789 return(oldworkpointer);
4791 else if ( *t == -SYMBOL ) {
4792 t1 = subterm + FUNHEAD;
4795 if ( *t1 == -SNUMBER )
goto gcdisone;
4796 if ( *t1 == -SYMBOL ) {
4797 if ( t1[1] != i )
goto gcdisone;
4800 if ( *t1 < 0 )
goto gcdillegal;
4802 ct = *ttt; *ttt = 0;
4804 t2 = PolyNormPoly(BHEAD t1+ARGHEAD);
4806 else t2 = t1 + ARGHEAD;
4810 tstop = t2 - ABS(t2[-1]);
4811 while ( t3 < tstop ) {
4812 if ( *t3 != SYMBOL ) {
4819 if ( *t4 == i && t4[1] > 0 )
goto nextterminarg;
4829 AT.WorkPointer = oldworkpointer;
4831 oldworkpointer[0] = 8;
4832 oldworkpointer[1] = SYMBOL;
4833 oldworkpointer[2] = 4;
4834 oldworkpointer[3] = t[1];
4835 oldworkpointer[4] = 1;
4836 oldworkpointer[5] = 1;
4837 oldworkpointer[6] = 1;
4838 oldworkpointer[7] = 3;
4839 oldworkpointer[8] = 0;
4840 AT.WorkPointer = oldworkpointer+9;
4841 return(oldworkpointer);
4843 else if ( *t < 0 ) {
4845 MLOCK(ErrorMessageLock);
4846 MesPrint(
"Illegal object in gcd_ function. Object not a number or a symbol.");
4847 MUNLOCK(ErrorMessageLock);
4850 else if ( ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4851 else if ( t[1] != 0 ) {
4852 ttt = t + *t; ct = *ttt; *ttt = 0;
4853 t = PolyNormPoly(BHEAD t+ARGHEAD);
4855 if ( t[*t] == 0 && ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4856 AT.WorkPointer = oldworkpointer;
4871 AT.WorkPointer = oldworkpointer;
4873 t = subterm + FUNHEAD;
4874 for ( i = 1; i < isnumeric; i++ ) {
4878 ttt = t + *t; ct = *ttt; *ttt = 0;
4879 t = PolyNormPoly(BHEAD t+ARGHEAD);
4883 i = (ABS(t[-1])-1)/2;
4886 sizenum1 = sizeden1 = i;
4887 while ( sizenum1 > 1 && num1[sizenum1-1] == 0 ) sizenum1--;
4888 while ( sizeden1 > 1 && den1[sizeden1-1] == 0 ) sizeden1--;
4889 work1 = AT.WorkPointer+1; work2 = work1+sizenum1;
4890 for ( i = 0; i < sizenum1; i++ ) work1[i] = num1[i];
4891 for ( i = 0; i < sizeden1; i++ ) work2[i] = den1[i];
4892 num1 = work1; den1 = work2;
4893 AT.WorkPointer = work2 = work2 + sizeden1;
4894 t = subterm + FUNHEAD;
4896 ttt = t + *t; ct = *ttt; *ttt = 0;
4898 t = PolyNormPoly(BHEAD t+ARGHEAD);
4903 i = (ABS(t[-1])-1)/2;
4906 sizenum2 = sizeden2 = i;
4907 while ( sizenum2 > 1 && num2[sizenum2-1] == 0 ) sizenum2--;
4908 while ( sizeden2 > 1 && den2[sizeden2-1] == 0 ) sizeden2--;
4909 num3 = AT.WorkPointer;
4910 if ( GcdLong(BHEAD (UWORD *)num2,sizenum2,(UWORD *)num1,sizenum1,
4911 (UWORD *)num3,&sizenum3) )
goto FromGCD;
4912 sizenum1 = sizenum3;
4913 for ( i = 0; i < sizenum1; i++ ) num1[i] = num3[i];
4914 den3 = AT.WorkPointer;
4915 if ( GcdLong(BHEAD (UWORD *)den2,sizeden2,(UWORD *)den1,sizeden1,
4916 (UWORD *)den3,&sizeden3) )
goto FromGCD;
4917 sizeden1 = sizeden3;
4918 for ( i = 0; i < sizeden1; i++ ) den1[i] = den3[i];
4919 if ( sizenum1 == 1 && num1[0] == 1 && sizeden1 == 1 && den1[1] == 1 )
4924 AT.WorkPointer = work2;
4926 AT.WorkPointer = oldworkpointer;
4930 if ( sizenum1 > sizeden1 ) {
4931 while ( sizenum1 > sizeden1 ) den1[sizeden1++] = 0;
4933 else if ( sizenum1 < sizeden1 ) {
4934 while ( sizenum1 < sizeden1 ) num1[sizenum1++] = 0;
4939 if ( num1 != t ) { NCOPY(t,num1,sizenum1); }
4941 if ( den1 != t ) { NCOPY(t,den1,sizeden1); }
4946 return(oldworkpointer);
4953 t = subterm + FUNHEAD;
4954 AT.WorkPointer += AM.MaxTer/
sizeof(WORD);
4955 work2 = AT.WorkPointer;
4962 work1 = AT.WorkPointer;
4963 ttt = t + *t; ct = *ttt; *ttt = 0;
4964 t = PolyNormPoly(BHEAD t+ARGHEAD);
4965 if ( *work1 < AT.WorkPointer-work1 ) {
4974 *AT.WorkPointer++ = 0;
4980 if ( work2 != work3 ) {
4981 work1 = PolyGCD2(BHEAD work1,work2);
4983 while ( *work2 ) work2 += *work2;
4987 while ( *work2 ) work2 += *work2;
4988 size = work2 - work1 + 1;
4990 NCOPY(t,work1,size);
4992 return(oldworkpointer);
4995 oldworkpointer[0] = 4;
4996 oldworkpointer[1] = 1;
4997 oldworkpointer[2] = 1;
4998 oldworkpointer[3] = 3;
4999 oldworkpointer[4] = 0;
5000 AT.WorkPointer = oldworkpointer+5;
5001 return(oldworkpointer);
5003 MLOCK(ErrorMessageLock);
5004 MesCall(
"EvaluateGcd");
5005 MUNLOCK(ErrorMessageLock);
5022int TreatPolyRatFun(PHEAD WORD *prf)
5024 WORD *t, *tstop, *r, *rstop, *m, *mstop;
5025 WORD exp1 = MAXPOWER, exp2 = MAXPOWER;
5028 if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
5029 if ( exp1 > 1 ) exp1 = 1;
5033 if ( exp1 > 0 ) exp1 = 0;
5040 while ( t < tstop ) {
5046 rstop = t - ABS(t[-1]);
5047 while ( r < rstop ) {
5048 if ( *r != SYMBOL ) { r += r[1];
continue; }
5052 while ( m < mstop ) {
5053 if ( *m == AR.PolyFunVar ) {
5054 if ( m[1] < exp1 ) exp1 = m[1];
5060 if ( exp1 > 0 ) exp1 = 0;
5065 if ( exp1 > 0 ) exp1 = 0;
5071 if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
5072 if ( exp2 > 1 ) exp2 = 1;
5075 if ( exp2 > 0 ) exp2 = 0;
5081 while ( t < tstop ) {
5087 rstop = t - ABS(t[-1]);
5088 while ( r < rstop ) {
5089 if ( *r != SYMBOL ) { r += r[1];
continue; }
5093 while ( m < mstop ) {
5094 if ( *m == AR.PolyFunVar ) {
5095 if ( m[1] < exp2 ) exp2 = m[1];
5101 if ( exp2 > 0 ) exp2 = 0;
5106 if ( exp2 > 0 ) exp2 = 0;
5119 *t++ = -SNUMBER; *t++ = 1;
5120 *t++ = -SNUMBER; *t++ = 1;
5122 else if ( exp1 > 0 ) {
5124 *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
5130 *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
5131 *t++ = exp1; *t++ = 1; *t++ = 1; *t++ = 3;
5133 *t++ = -SNUMBER; *t++ = 1;
5136 *t++ = -SNUMBER; *t++ = 1;
5138 *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
5144 *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
5145 *t++ = -exp1; *t++ = 1; *t++ = 1; *t++ = 3;
5158void DropCoefficient(PHEAD WORD *term)
5161 WORD *t = term + *term;
5163 n = t[-1]; na = ABS(n);
5165 if ( n == 3 && t[0] == 1 && t[1] == 1 )
return;
5167 t[0] = 1; t[1] = 1; t[2] = 3;
5176void DropSymbols(PHEAD WORD *term)
5179 WORD *tend = term + *term, *t1, *t2, *tstop;
5180 tstop = tend - ABS(tend[-1]);
5182 while ( t1 < tstop ) {
5183 if ( *t1 == SYMBOL ) {
5186 while ( t2 < tend ) *t1++ = *t2++;
5209 WORD *t, *b, *bb, *tt, *m, *tstop;
5212 WORD buffer[7*NORMSIZE];
5215 *b++ = SYMBOL; *b++ = 2;
5217 tstop = t - ABS(t[-1]);
5219 while ( t < tstop ) {
5220 if ( *t == SYMBOL && t < tstop ) {
5221 for ( i = 2; i < t[1]; i += 2 ) {
5222 const WORD sym = t[i];
5223 const WORD pow = t[i+1];
5226 if ( bb[0] == sym ) {
5228 if ( bb[1] > MAXPOWER || bb[1] < -MAXPOWER ) {
5229 MLOCK(ErrorMessageLock);
5230 MesPrint(
"Power in SymbolNormalize out of range");
5231 MUNLOCK(ErrorMessageLock);
5237 bb[0] = bb[2]; bb[1] = bb[3]; bb += 2;
5242 else if ( bb[0] > sym ) {
5244 while ( m > bb ) { m[1] = m[-1]; m[0] = m[-2]; m -= 2; }
5253 *b++ = sym; *b++ = pow;
5259 MLOCK(ErrorMessageLock);
5260 MesPrint(
"Illegal term in SymbolNormalize");
5261 MUNLOCK(ErrorMessageLock);
5266 buffer[1] = b - buffer;
5270 if ( AT.LeaveNegative == 0 ) {
5271 b = buffer; bb = b + b[1]; b += 3;
5274 MLOCK(ErrorMessageLock);
5275 MesPrint(
"Negative power in SymbolNormalize");
5276 MUNLOCK(ErrorMessageLock);
5288 b = buffer; tt = term + 1;
5289 if ( i > 2 ) { NCOPY(tt,b,i) }
5292 if ( i < 0 ) i = -i;
5293 *term -= (tstop-tt);
5307int TestFunFlag(PHEAD WORD *tfun)
5309 WORD *t, *tstop, *r, *rstop, *m, *mstop;
5310 if ( functions[*tfun-FUNCTION].spec <= 0 )
return(0);
5311 tstop = tfun + tfun[1];
5313 while ( t < tstop ) {
5314 if ( *t < 0 ) { NEXTARG(t);
continue; }
5316 if ( t[1] == 0 ) { t = rstop;
continue; }
5318 while ( r < rstop ) {
5319 m = r+1; mstop = r+*r; mstop -= ABS(mstop[-1]);
5320 while ( m < mstop ) {
5321 if ( *m == SUBEXPRESSION || *m == EXPRESSION || *m == DOLLAREXPRESSION )
return(1);
5322 if ( ( *m >= FUNCTION ) && ( ( m[2] & DIRTYFLAG ) == DIRTYFLAG )
5323 && ( *m != REPLACEMENT ) && TestFunFlag(BHEAD m) )
return(1);
5338int BracketNormalize(PHEAD WORD *term)
5340 WORD *stop = term+*term-3, *t, *tt, *tstart, *r;
5341 WORD *oldwork = AT.WorkPointer;
5344 termout = AT.WorkPointer = term+*term;
5348 tt = termout+1; t = term+1;
5349 while ( t < stop ) {
5350 if ( *t >= FUNCTION ) { i = t[1]; NCOPY(tt,t,i); }
5353 if ( tt > termout+1 && tt-termout-1 > termout[2] ) {
5354 r = termout+1; ii = tt-r;
5355 for ( i = 0; i < ii-FUNHEAD; i += FUNHEAD ) {
5356 for ( j = i+FUNHEAD; j > 0; j -= FUNHEAD ) {
5357 if ( functions[r[j-FUNHEAD]-FUNCTION].commute
5358 && functions[r[j]-FUNCTION].commute == 0 )
break;
5359 if ( r[j-FUNHEAD] > r[j] ) EXCH(r[j-FUNHEAD],r[j])
5365 tstart = tt; t = term + 1; *tt++ = DELTA; *tt++ = 2;
5366 while ( t < stop ) {
5367 if ( *t == DELTA ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5370 if ( tstart[1] > 2 ) {
5371 for ( r = tstart+2; r < tstart+tstart[1]; r += 2 ) {
5372 if ( r[0] > r[1] ) EXCH(r[0],r[1])
5375 if ( tstart[1] > 4 ) {
5376 r = tstart+2; ii = tstart[1]-2;
5377 for ( i = 0; i < ii-2; i += 2 ) {
5378 for ( j = i+2; j > 0; j -= 2 ) {
5379 if ( r[j-2] > r[j] ) {
5383 else if ( r[j-2] < r[j] )
break;
5385 if ( r[j-1] > r[j+1] ) EXCH(r[j-1],r[j+1])
5390 tt = tstart+tstart[1];
5392 else if ( tstart[1] == 2 ) { tt = tstart; }
5395 tstart = tt; t = term + 1; *tt++ = INDEX; *tt++ = 2;
5396 while ( t < stop ) {
5397 if ( *t == INDEX ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5400 if ( tstart[1] >= 4 ) {
5401 r = tstart+2; ii = tstart[1]-2;
5402 for ( i = 0; i < ii-1; i += 1 ) {
5403 for ( j = i+1; j > 0; j -= 1 ) {
5404 if ( r[j-1] > r[j] ) EXCH(r[j-1],r[j])
5408 tt = tstart+tstart[1];
5410 else if ( tstart[1] == 2 ) { tt = tstart; }
5413 tstart = tt; t = term + 1; *tt++ = DOTPRODUCT; *tt++ = 2;
5414 while ( t < stop ) {
5415 if ( *t == DOTPRODUCT ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5418 if ( tstart[1] > 5 ) {
5419 r = tstart+2; ii = tstart[1]-2;
5420 for ( i = 0; i < ii; i += 3 ) {
5421 if ( r[i] > r[i+1] ) EXCH(r[i],r[i+1])
5423 for ( i = 0; i < ii-3; i += 3 ) {
5424 for ( j = i+3; j > 0; j -= 3 ) {
5425 if ( r[j-3] < r[j] )
break;
5426 if ( r[j-3] > r[j] ) {
5431 if ( r[j-2] > r[j+1] ) EXCH(r[j-2],r[j+1])
5436 tt = tstart+tstart[1];
5438 else if ( tstart[1] == 2 ) { tt = tstart; }
5440 if ( tstart[2] > tstart[3] ) EXCH(tstart[2],tstart[3])
5444 tstart = tt; t = term + 1; *tt++ = SYMBOL; *tt++ = 2;
5445 while ( t < stop ) {
5446 if ( *t == SYMBOL ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5449 if ( tstart[1] > 4 ) {
5450 r = tstart+2; ii = tstart[1]-2;
5451 for ( i = 0; i < ii-2; i += 2 ) {
5452 for ( j = i+2; j > 0; j -= 2 ) {
5453 if ( r[j-2] > r[j] ) EXCH(r[j-2],r[j])
5457 tt = tstart+tstart[1];
5459 else if ( tstart[1] == 2 ) { tt = tstart; }
5462 tstart = tt; t = term + 1; *tt++ = SETSET; *tt++ = 2;
5463 while ( t < stop ) {
5464 if ( *t == SETSET ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5467 if ( tstart[1] > 4 ) {
5468 r = tstart+2; ii = tstart[1]-2;
5469 for ( i = 0; i < ii-2; i += 2 ) {
5470 for ( j = i+2; j > 0; j -= 2 ) {
5471 if ( r[j-2] > r[j] ) {
5478 tt = tstart+tstart[1];
5480 else if ( tstart[1] == 2 ) { tt = tstart; }
5482 *tt++ = 1; *tt++ = 1; *tt++ = 3;
5483 t = term; i = *termout = tt - termout; tt = termout;
5485 AT.WorkPointer = oldwork;
int GetFirstTerm(WORD *, int, int)
WORD CompCoef(WORD *, WORD *)
LONG EndSort(PHEAD WORD *, int)
void LowerSortLevel(void)
int StoreTerm(PHEAD WORD *)
WORD NextPrime(PHEAD WORD)
WORD Compare1(PHEAD WORD *, WORD *, WORD)
WORD CompareSymbols(PHEAD WORD *, WORD *, WORD)
int SymbolNormalize(WORD *term)