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 ) {
2512 MLOCK(ErrorMessageLock);
2513 MesPrint(
"!>Illegal code in Norm");
2517 AO.OutFill = AO.OutputLine = OutBuf;
2522 while ( --i >= 0 ) {
2523 TalToLine((UWORD)(*t++));
2524 TokenToLine((UBYTE *)
" ");
2530 MUNLOCK(ErrorMessageLock);
2534 if ( *t == REPLACEMENT ) {
2535 if ( AR.Eside != LHSIDE ) ReplaceVeto--;
2543 if ( *t == DUMMYFUN || *t == DUMMYTEN ) {}
2545 if ( *t < (FUNCTION + WILDOFFSET) ) {
2546 if ( ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2547 || ( functions[*t-FUNCTION].minnumargs > 0 ) )
2548 && ( ( t[2] & DIRTYFLAG ) != 0 ) ) {
2552 WORD *ta = t + FUNHEAD, *tb = t + t[1];
2554 while ( ta < tb ) { numarg++; NEXTARG(ta) }
2555 if ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2556 && ( numarg >= functions[*t-FUNCTION].maxnumargs ) )
2558 if ( ( functions[*t-FUNCTION].minnumargs > 0 )
2559 && ( numarg < functions[*t-FUNCTION].minnumargs ) )
2563 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION].tabl == 0 ) ) {
2565 t[2] |= DIRTYSYMFLAG;
2567 if ( functions[*t-FUNCTION].commute ) { pnco[nnco++] = t; }
2568 else { pcom[ncom++] = t; }
2571 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION-WILDOFFSET].tabl == 0 ) ) {
2573 t[2] |= DIRTYSYMFLAG;
2575 if ( functions[*t-FUNCTION-WILDOFFSET].commute ) {
2578 else { pcom[ncom++] = t; }
2584 if ( ( *t < (FUNCTION + WILDOFFSET)
2585 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) || (
2586 *t >= (FUNCTION + WILDOFFSET)
2587 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
2588 if ( *t >= GAMMA && *t <= GAMMASEVEN ) t++;
2591 if ( *t == AM.vectorzero )
goto NormZero;
2592 if ( *t >= AM.OffsetIndex && ( *t >= AM.DumInd
2593 || ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2596 else if ( *t == FUNNYWILD ) { t++; }
2611 else if ( *t <= -FUNCTION ) t++;
2612 else if ( *t == -INDEX ) {
2613 if ( t[1] >= AM.OffsetIndex &&
2614 ( t[1] >= AM.DumInd || ( t[1] < AM.WilInd
2615 && indices[t[1]-AM.OffsetIndex].dimension ) ) )
2619 else if ( *t == -SYMBOL ) {
2620 if ( t[1] >= MAXPOWER && t[1] < 2*MAXPOWER ) {
2624 else if ( t[1] < -MAXPOWER && t[1] > -2*MAXPOWER ) {
2640 r = t = ANsr; m = ANsm;
2641 ANsc = ANsm = ANsr = 0;
2654 for ( k = 0, i = 0; i < nden; i++ ) {
2656 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2657 r = t + t[1]; m = t + FUNHEAD;
2659 for ( j = i+1; j < nden; j++ ) pden[j-1] = pden[j];
2661 for ( j = 0; j < nnco; j++ )
if ( pnco[j] == t )
break;
2662 for ( j++; j < nnco; j++ ) pnco[j-1] = pnco[j];
2668 if ( m >= r )
continue;
2673 k = 1; to = termout; from = term;
2675 while ( from < t ) *to++ = *from++;
2679 *to++ = DENOMINATOR;
2680 for ( j = 1; j < FUNHEAD; j++ ) *to++ = 0;
2681 if ( *m < -FUNCTION ) *to++ = *m++;
2682 else if ( *m < 0 ) { *to++ = *m++; *to++ = *m++; }
2684 j = *m;
while ( --j >= 0 ) *to++ = *m++;
2686 stop[1] = WORDDIF(to,stop);
2689 if ( i == nden - 1 ) {
2690 stop = term + *term;
2691 while ( from < stop ) *to++ = *from++;
2692 i = *termout = WORDDIF(to,termout);
2693 to = term; from = termout;
2694 while ( --i >= 0 ) *to++ = *from++;
2699 for ( i = 0; i < nden; i++ ) {
2701 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2704 if ( ( t[FUNHEAD] < 0 || t[FUNHEAD+1] == 0 ) && ! TestFunFlag(BHEAD t) ) {
2707 if ( t[FUNHEAD] == -SYMBOL ) {
2710 change = ExtraSymbol(*t,-1,nsym,ppsym,&ncoef);
2712 ppsym += change * 2;
2715 else if ( t[FUNHEAD] == -SNUMBER ) {
2717 if ( *t == 0 )
goto NormInf;
2718 if ( *t < 0 ) { *AT.WorkPointer = -*t; j = -1; }
2719 else { *AT.WorkPointer = *t; j = 1; }
2720 ncoef = REDLENG(ncoef);
2721 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,j) )
2723 ncoef = INCLENG(ncoef);
2726 else if ( t[FUNHEAD] == ARGHEAD )
goto NormInf;
2727 else if ( t[FUNHEAD] > 0 && t[FUNHEAD+ARGHEAD] ==
2728 t[FUNHEAD]-ARGHEAD ) {
2731 t += FUNHEAD + ARGHEAD + 1;
2733 m = r - ABS(*r) + 1;
2734 if ( j != 3 || ( ( *m != 1 ) || ( m[1] != 1 ) ) ) {
2735 ncoef = REDLENG(ncoef);
2736 if ( DivRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,REDLENG(j),(UWORD *)n_coef,&ncoef) )
goto FromNorm;
2737 ncoef = INCLENG(ncoef);
2739 t[-FUNHEAD-ARGHEAD] -= j;
2747 if ( *t == SYMBOL || *t == DOTPRODUCT ) {
2750 pden[i][FUNHEAD] -= k;
2751 pden[i][FUNHEAD+ARGHEAD] -= k;
2756 if ( *t == SYMBOL ) {
2760 change = ExtraSymbol(*t,-t[1],nsym,ppsym,&ncoef);
2762 ppsym += change * 2;
2775 while ( to < stop ) *to++ = *from++;
2779 else if ( *t == FLOATFUN && TestFloat(t) ) {
2782 pden[i][FUNHEAD] -= k;
2783 pden[i][FUNHEAD+ARGHEAD] -= k;
2784 UnpackFloat(aux5,t);
2785 if ( withfloat == 0 ) {
2786 mpf_ui_div(aux4,1,aux5);
2790 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
2791 mpf_div(aux4,aux4,aux5);
2795 while ( r < m ) *to++ = *r++;
2796 *to++ = 1; *to++ = 1; *to++ = 3;
2797 if ( ncoef < 0 ) t[-1] = -t[-1];
2805 if ( pden[i][1] == 4+FUNHEAD+ARGHEAD ) {
2807 for ( j = 0; j < nnco; j++ ) {
2808 if ( pden[i] == pnco[j] ) {
2810 while ( j < nnco ) {
2811 pnco[j] = pnco[j+1];
2817 pden[i--] = pden[--nden];
2828 for ( i = 0; i < ndel; i += 2 ) {
2829 if ( t[0] == t[1] ) {
2830 if ( t[0] == EMPTYINDEX ) {}
2831 else if ( *t < AM.OffsetIndex ) {
2832 k = AC.FixIndices[*t];
2833 if ( k < 0 ) { j = -1; k = -k; }
2834 else if ( k > 0 ) j = 1;
2838 else if ( *t >= AM.DumInd ) {
2840 if ( k )
goto docontract;
2842 else if ( *t >= AM.WilInd ) {
2843 k = indices[*t-AM.OffsetIndex-WILDOFFSET].dimension;
2844 if ( k )
goto docontract;
2846 else if ( ( k = indices[*t-AM.OffsetIndex].dimension ) != 0 ) {
2850WithFix: shortnum = k;
2851 ncoef = REDLENG(ncoef);
2852 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),j) )
2854 ncoef = INCLENG(ncoef);
2858 change = ExtraSymbol((WORD)(-k),(WORD)1,nsym,ppsym,&ncoef);
2860 ppsym += change * 2;
2862 t[1] = pdel[ndel-1];
2863 t[0] = pdel[ndel-2];
2870 if ( *t < AM.OffsetIndex && t[1] < AM.OffsetIndex )
goto NormZero;
2871 j = *t - AM.OffsetIndex;
2872 if ( j >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
2873 || ( *t < AM.WilInd && indices[j].dimension ) ) ) {
2874 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2877 *m++ = pdel[ndel-2];
2881 else if ( *t == m[1] ) {
2883 *m++ = pdel[ndel-2];
2889 j = t[1]-AM.OffsetIndex;
2890 if ( j >= 0 && ( ( t[1] >= AM.DumInd && AC.lDefDim )
2891 || ( t[1] < AM.WilInd && indices[j].dimension ) ) ) {
2892 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2895 *m++ = pdel[ndel-2];
2899 else if ( t[1] == m[1] ) {
2901 *m++ = pdel[ndel-2];
2913 for ( i = 0; i < ndel; i++ ) {
2914 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2915 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2917 for ( j = 1; j < nvec; j += 2 ) {
2921 *t-- = pdel[--ndel];
2926 t[1] = pdel[--ndel];
2929 *t-- = pdel[--ndel];
2938 if ( ndel > 0 && ncon ) {
2940 for ( i = 0; i < ndel; i++ ) {
2941 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2942 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2943 for ( j = 0; j < ncon; j++ ) {
2944 if ( *pcon[j] == *t ) {
2947 *t-- = pdel[--ndel];
2952 t[1] = pdel[--ndel];
2955 *t-- = pdel[--ndel];
2958 for ( j = 0; j < nnco; j++ ) {
2960 if ( r > m && r < m+m[1] ) {
2961 m[2] |= DIRTYSYMFLAG;
2965 for ( j = 0; j < ncom; j++ ) {
2967 if ( r > m && r < m+m[1] ) {
2968 m[2] |= DIRTYSYMFLAG;
2972 for ( j = 0; j < neps; j++ ) {
2974 if ( r > m && r < m+m[1] ) {
2975 m[2] |= DIRTYSYMFLAG;
2990 for ( i = 3; i < nvec; i += 2 ) {
2991 k = *t - AM.OffsetIndex;
2992 if ( k >= 0 && ( ( *t > AM.DumInd && AC.lDefDim )
2993 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
2995 for ( j = i; j < nvec; j += 2 ) {
3001 *r-- = pvec[--nvec];
3003 *t-- = pvec[--nvec];
3004 *t-- = pvec[--nvec];
3013 if ( nvec > 0 && ncon ) {
3015 for ( i = 1; i < nvec; i += 2 ) {
3016 k = *t - AM.OffsetIndex;
3017 if ( k >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
3018 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
3019 for ( j = 0; j < ncon; j++ ) {
3020 if ( *pcon[j] == *t ) {
3022 *t-- = pvec[--nvec];
3023 *t-- = pvec[--nvec];
3025 pcon[j] = pcon[--ncon];
3027 for ( j = 0; j < nnco; j++ ) {
3029 if ( r > m && r < m+m[1] ) {
3030 m[2] |= DIRTYSYMFLAG;
3034 for ( j = 0; j < ncom; j++ ) {
3036 if ( r > m && r < m+m[1] ) {
3037 m[2] |= DIRTYSYMFLAG;
3041 for ( j = 0; j < neps; j++ ) {
3043 if ( r > m && r < m+m[1] ) {
3044 m[2] |= DIRTYSYMFLAG;
3062 for ( i = 0; i < nnco; i++ ) {
3064 if ( ( *t >= (FUNCTION+WILDOFFSET)
3065 && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
3066 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3067 && functions[*t-FUNCTION].spec <= 0 ) ) {
3073 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
3076 pnco[i][2] |= DIRTYSYMFLAG;
3088 for ( i = 0; i < nnco; i++ ) {
3090 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) && *t != DOLLAREXPRESSION ) {
3092 if ( ( *t >= (FUNCTION+WILDOFFSET)
3093 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
3094 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3095 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
3096 if ( *t >= (FUNCTION+WILDOFFSET) ) {
3098 j = FullSymmetrize(BHEAD t,l);
3101 else j = FullSymmetrize(BHEAD t,l);
3102 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3103 if ( ( j & 2 ) != 0 )
goto NormZero;
3104 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
3107 else t[2] &= ~DIRTYSYMFLAG;
3115 for ( i = 0; i < k; i++ ) {
3117 while ( Commute(pnco[j],pnco[j+1]) ) {
3118 t = pnco[j]; pnco[j] = pnco[j+1]; pnco[j+1] = t;
3120 while ( l >= 0 && Commute(pnco[l],pnco[l+1]) ) {
3121 t = pnco[l]; pnco[l] = pnco[l+1]; pnco[l+1] = t;
3124 if ( ++j >= k )
break;
3131 for ( i = 0; i < nnco; i++ ) {
3133 if ( *t == IDFUNCTION ) AN.idfunctionflag = 1;
3134 if ( *t >= GAMMA && *t <= GAMMASEVEN ) {
3140 *m++ = stype = t[FUNHEAD];
3145 if ( *t == GAMMAFIVE ) {
3146 gtype = GAMMA5; t += FUNHEAD;
goto onegammamatrix; }
3147 else if ( *t == GAMMASIX ) {
3148 gtype = GAMMA6; t += FUNHEAD;
goto onegammamatrix; }
3149 else if ( *t == GAMMASEVEN ) {
3150 gtype = GAMMA7; t += FUNHEAD;
goto onegammamatrix; }
3155 if ( gtype == GAMMA5 ) {
3156 if ( j == GAMMA1 ) j = GAMMA5;
3157 else if ( j == GAMMA5 ) j = GAMMA1;
3158 else if ( j == GAMMA7 ) ncoef = -ncoef;
3159 if ( nnum & 1 ) ncoef = -ncoef;
3161 else if ( gtype == GAMMA6 || gtype == GAMMA7 ) {
3163 if ( gtype == GAMMA6 ) gtype = GAMMA7;
3164 else gtype = GAMMA6;
3166 if ( j == GAMMA1 ) j = gtype;
3167 else if ( j == GAMMA5 ) {
3169 if ( j == GAMMA7 ) ncoef = -ncoef;
3171 else if ( j != gtype )
goto NormZero;
3174 ncoef = REDLENG(ncoef);
3175 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),1) )
goto FromNorm;
3176 ncoef = INCLENG(ncoef);
3180 *m++ = gtype; nnum++;
3185 }
while ( ( ++i < nnco ) && ( *(t = pnco[i]) >= GAMMA
3186 && *t <= GAMMASEVEN ) && ( t[FUNHEAD] == stype ) );
3189 k = WORDDIF(m,to) - FUNHEAD-1;
3192 while ( --k >= 0 ) *from-- = *--r;
3195 to[1] = WORDDIF(m,to);
3197 else if ( *t < 0 ) {
3198 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3202 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
3203 && *t != REPLACEMENT && *t != DOLLAREXPRESSION
3204 && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
3216 for ( i = 0; i < ncom; i++ ) {
3218 if ( ( *t >= (FUNCTION+WILDOFFSET)
3219 && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
3220 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3221 && functions[*t-FUNCTION].spec <= 0 ) ) {
3227 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
3230 pcom[i][2] |= DIRTYSYMFLAG;
3240 for ( i = 0; i < ncom; i++ ) {
3242 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) ) {
3244 if ( ( *t >= (FUNCTION+WILDOFFSET)
3245 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
3246 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3247 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
3248 if ( *t >= (FUNCTION+WILDOFFSET) ) {
3250 j = FullSymmetrize(BHEAD t,l);
3253 else j = FullSymmetrize(BHEAD t,l);
3254 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3255 if ( ( j & 2 ) != 0 )
goto NormZero;
3256 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
3259 else t[2] &= ~DIRTYSYMFLAG;
3268 for ( i = 1; i < ncom; i++ ) {
3269 for ( j = i; j > 0; j-- ) {
3275 if ( *r < 0 ) {
if ( *t >= *r )
goto NextI; }
3276 else {
if ( -*t <= *r )
goto NextI; }
3279 else if ( *r < 0 ) {
3280 if ( *t < -*r )
goto NextI;
3283 else if ( *t != *r ) {
3284 if ( *t < *r )
goto NextI;
3285jexch: t = pcom[j]; pcom[j] = pcom[jj]; pcom[jj] = t;
3288 if ( AC.properorderflag ) {
3289 if ( ( *t >= (FUNCTION+WILDOFFSET)
3290 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION )
3291 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3292 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) ) {}
3294 WORD *s1, *s2, *ss1, *ss2;
3295 s1 = t+FUNHEAD; s2 = r+FUNHEAD;
3296 ss1 = t + t[1]; ss2 = r + r[1];
3297 while ( s1 < ss1 && s2 < ss2 ) {
3299 if ( k > 0 )
goto jexch;
3300 if ( k < 0 )
goto NextI;
3304 if ( s1 < ss1 )
goto jexch;
3308 kk = r[1] - FUNHEAD;
3311 while ( k > 0 && kk > 0 ) {
3312 if ( *t < *r )
goto NextI;
3313 else if ( *t++ > *r++ )
goto jexch;
3316 if ( k > 0 )
goto jexch;
3322 kk = r[1] - FUNHEAD;
3325 while ( k > 0 && kk > 0 ) {
3326 if ( *t < *r )
goto NextI;
3327 else if ( *t++ > *r++ )
goto jexch;
3330 if ( k > 0 )
goto jexch;
3336 for ( i = 0; i < ncom; i++ ) {
3338 if ( *t == THETA || *t == THETA2 ) {
3339 if ( ( k = DoTheta(BHEAD t) ) == 0 )
goto NormZero;
3345 else if ( *t == DELTA2 || *t == DELTAP ) {
3346 if ( ( k = DoDelta(t) ) == 0 )
goto NormZero;
3352 else if ( *t == AR.PolyFunInv && AR.PolyFunType == 2 ) {
3357 WORD *mm, *tt = t, numt = 0;
3359 while ( tt < t+t[1] ) { numt++; NEXTARG(tt) }
3361 tt = t; mm = m; k = t[1];
3367 if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
3368 else { *tt++ = *mm++; *tt++ = *mm++; }
3371 k = *mm; NCOPY(tt,mm,k)
3375 if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
3376 else { *tt++ = *mm++; *tt++ = *mm++; }
3379 k = *mm; NCOPY(tt,mm,k)
3382 t[2] |= MUSTCLEANPRF;
3386 else if ( *t == AR.PolyFun ) {
3387 if ( AR.PolyFunType == 1 ) {
3388 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3389 t[1] == FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER )
goto NormZero;
3390 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) {
3391 if ( AN.PolyNormFlag == 0 ) {
3392 AN.PolyNormFlag = 1;
3399 else if ( AR.PolyFunType == 2 ) {
3410 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3411 t[1] > FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER ) {
3412 u = t + FUNHEAD + 2;
3414 if ( *u <= -FUNCTION ) {}
3415 else if ( t[1] == FUNHEAD+4 && t[FUNHEAD+2] == -SNUMBER
3416 && t[FUNHEAD+3] == 0 )
goto NormPRF;
3417 else if ( t[1] == FUNHEAD+4 )
goto NormZero;
3419 else if ( t[1] == *u+FUNHEAD+2 )
goto NormZero;
3422 u = t+FUNHEAD; NEXTARG(u);
3423 if ( *u == -SNUMBER && u[1] == 0 )
goto NormInf;
3425 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3426 else if ( i < ncom-1 && pcom[i+1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3428 if ( AN.PolyNormFlag ) {
3429 if ( AR.PolyFunExp == 0 ) {
3433 else if ( AR.PolyFunExp == 1 ) {
3434 if ( PolyFunMode == 0 ) {
3441 if ( TreatPolyRatFun(BHEAD mmm) != 0 )
3447 if ( PolyFunMode == 0 ) {
3454 if ( ExpandRat(BHEAD mmm) != 0 )
3461 if ( AR.PolyFunExp == 0 ) {
3465 else if ( AR.PolyFunExp == 1 ) {
3468 if ( TreatPolyRatFun(BHEAD mmm) != 0 )
3475 if ( ExpandRat(BHEAD mmm) != 0 )
3482 else if ( *t > 0 ) {
3483 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
3484 && *t != REPLACEMENT && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
3489 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3498 if ( ReplaceVeto < 0 ) {
3508 WORD *ma = fillsetexp, *mb, *mc;
3511 if ( *ma != REPLACEMENT ) {
3515 if ( *ma == REPLACEMENT && ReplaceType == -1 ) {
3518 if ( AN.RSsize < 2*ma[1]+SUBEXPSIZE ) {
3519 if ( AN.ReplaceScrat ) M_free(AN.ReplaceScrat,
"AN.ReplaceScrat");
3520 AN.RSsize = 2*ma[1]+SUBEXPSIZE+40;
3521 AN.ReplaceScrat = (WORD *)Malloc1((AN.RSsize+1)*
sizeof(WORD),
"AN.ReplaceScrat");
3524 ReplaceSub = AN.ReplaceScrat;
3525 ReplaceSub += SUBEXPSIZE;
3527 if ( *ma > 0 )
goto NoRep;
3528 if ( *ma <= -FUNCTION ) {
3529 *ReplaceSub++ = FUNTOFUN;
3531 *ReplaceSub++ = -*ma++;
3532 if ( *ma > -FUNCTION )
goto NoRep;
3533 *ReplaceSub++ = -*ma++;
3535 else if ( ma+4 > mb )
goto NoRep;
3537 if ( *ma == -SYMBOL ) {
3538 if ( ma[2] == -SYMBOL && ma+4 <= mb )
3539 *ReplaceSub++ = SYMTOSYM;
3540 else if ( ma[2] == -SNUMBER && ma+4 <= mb ) {
3541 *ReplaceSub++ = SYMTONUM;
3542 if ( ReplaceType == 0 ) {
3543 oldtoprhs = C->numrhs;
3548 else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
3549 *ReplaceSub++ = SYMTONUM;
3551 *ReplaceSub++ = ma[1];
3560 else if ( ma[2] > 0 ) {
3561 WORD *sstop, *ttstop, n;
3565 while ( ss < sstop ) {
3567 ttstop = tt - ABS(tt[-1]);
3569 while ( ss < ttstop ) {
3570 if ( *ss == INDEX )
goto NoRep;
3576 if ( ReplaceType == 0 ) {
3577 oldtoprhs = C->numrhs;
3581 ss =
AddRHS(AT.ebufnum,1);
3586 while ( --n >= 0 ) *ss++ = *tt++;
3588 C->
rhs[C->numrhs+1] = ss;
3590 *ReplaceSub++ = subtype;
3592 *ReplaceSub++ = ma[1];
3593 *ReplaceSub++ = C->numrhs;
3599 else if ( ( *ma == -VECTOR || *ma == -MINVECTOR ) && ma+4 <= mb ) {
3600 if ( ma[2] == -VECTOR ) {
3601 if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOVEC;
3602 else *ReplaceSub++ = VECTOMIN;
3604 else if ( ma[2] == -MINVECTOR ) {
3605 if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOMIN;
3606 else *ReplaceSub++ = VECTOVEC;
3612 else if ( ma[2] > 0 ) {
3613 WORD *sstop, *ttstop, *w, *mm, n, count;
3615 if ( *ma == -MINVECTOR ) {
3619 while ( ss < sstop ) {
3628 while ( ss < sstop ) {
3630 ttstop = tt - ABS(tt[-1]);
3633 while ( ss < ttstop ) {
3634 if ( *ss == INDEX ) {
3635 n = ss[1] - 2; ss += 2;
3636 while ( --n >= 0 ) {
3637 if ( *ss < MINSPEC ) count++;
3643 if ( count != 1 )
goto NoRep;
3647 if ( ReplaceType == 0 ) {
3648 oldtoprhs = C->numrhs;
3652 mm =
AddRHS(AT.ebufnum,1);
3653 *ReplaceSub++ = subtype;
3655 *ReplaceSub++ = ma[1];
3656 *ReplaceSub++ = C->numrhs;
3660 while ( (mm + n + 10) > C->
Top )
3662 while ( --n >= 0 ) *mm++ = *w++;
3664 C->
rhs[C->numrhs+1] = mm;
3666 mm =
AddRHS(AT.ebufnum,1);
3670 while ( (mm + n + 13) > C->
Top )
3673 while ( w < sstop ) {
3674 tt = w + *w; ttstop = tt - ABS(tt[-1]);
3676 while ( w < ttstop ) {
3677 if ( *w != INDEX ) {
3686 while ( --n >= 0 ) {
3687 if ( *w >= MINSPEC ) *mm++ = *w++;
3692 if ( n <= 2 ) mm -= 2;
3701 while ( w < tt ) *mm++ = *w++;
3702 *ss = WORDDIF(mm,ss);
3705 C->
rhs[C->numrhs+1] = mm;
3707 if ( mm > C->
Top ) {
3709 MLOCK(ErrorMessageLock);
3710 MesPrint(
"!>Internal error in Normalize with extra compiler buffer");
3711 MUNLOCK(ErrorMessageLock);
3720 else if ( *ma == -INDEX ) {
3721 if ( ( ma[2] == -INDEX || ma[2] == -VECTOR )
3723 *ReplaceSub++ = INDTOIND;
3724 else if ( ma[1] >= AM.OffsetIndex ) {
3725 if ( ma[2] == -SNUMBER && ma+4 <= mb
3726 && ma[3] >= 0 && ma[3] < AM.OffsetIndex )
3727 *ReplaceSub++ = INDTOIND;
3728 else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
3729 *ReplaceSub++ = INDTOIND;
3731 *ReplaceSub++ = ma[1];
3742 *ReplaceSub++ = ma[1];
3743 *ReplaceSub++ = ma[3];
3748 AN.ReplaceScrat[1] = ReplaceSub-AN.ReplaceScrat;
3753 while ( mb < m ) *mc++ = *mb++;
3757 if ( ReplaceType > 0 ) {
3758 C->numrhs = oldtoprhs;
3762 if ( ++ReplaceVeto >= 0 )
break;
3773 for ( i = 0; i < neps; i++ ) {
3775 if ( ( t[2] & DIRTYSYMFLAG ) != DIRTYSYMFLAG )
continue;
3776 t[2] &= ~DIRTYSYMFLAG;
3777 if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
3786 if ( *r != FUNNYWILD ) { r++;
continue; }
3787 k = r[1]; u = r + 2;
3790 if ( *u != FUNNYWILD ) ncoef = -ncoef;
3793 tt[-2] = FUNNYWILD; tt[-1] = k; m -= 2;
3797 for ( r = t + 1; r < m; r++ ) {
3798 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3799 else if ( *r == *t )
goto NormZero;
3804 for ( r = t + 2; r < tt; r += 2 ) {
3805 if ( r[1] < t[1] ) {
3806 k = r[1]; r[1] = t[1]; t[1] = k; ncoef = -ncoef; }
3807 else if ( r[1] == t[1] )
goto NormZero;
3816 for ( r = t + 1; r < m; r++ ) {
3817 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3818 else if ( *r == *t )
goto NormZero;
3827 for ( i = 0; i < (neps-1); i++ ) {
3829 for ( j = i+1; j < neps; j++ ) {
3831 if ( t[1] > r[1] ) {
3832 peps[i] = m = r; peps[j] = r = t; t = m;
3834 else if ( t[1] == r[1] ) {
3840 m = peps[j]; peps[j] = t; peps[i] = t = m;
3843 else if ( *r++ > *m++ )
break;
3844 }
while ( --k > 0 );
3849 for ( i = 0; i < neps; i++ ) {
3861 for ( i = 0; i < ndel; i += 2, r += 2 ) {
3862 if ( r[1] < r[0] ) { k = *r; *r = r[1]; r[1] = k; }
3864 for ( i = 2; i < ndel; i += 2, t += 2 ) {
3866 for ( j = i; j < ndel; j += 2 ) {
3867 if ( *r > *t ) { r += 2; }
3868 else if ( *r < *t ) {
3869 k = *r; *r++ = *t; *t++ = k;
3870 k = *r; *r++ = *t; *t-- = k;
3873 if ( *++r < t[1] ) {
3874 k = *r; *r = t[1]; t[1] = k;
3892 for ( i = 0; i < nind; i++ ) {
3894 for ( j = i+1; j < nind; j++ ) {
3896 k = *r; *r = *t; *t = k;
3914 for ( i = 2; i < nvec; i += 2 ) {
3916 for ( j = i; j < nvec; j += 2 ) {
3918 if ( *++r < t[1] ) {
3919 k = *r; *r = t[1]; t[1] = k;
3923 else if ( *r < *t ) {
3924 k = *r; *r++ = *t; *t++ = k;
3925 k = *r; *r++ = *t; *t-- = k;
3945 while ( --i >= 0 ) {
3946 if ( *t > t[1] ) { j = *t; *t = t[1]; t[1] = j; }
3952 while ( t < (m-3) ) {
3956 if ( *++r == *++t ) {
3958 if ( ( *r < MAXPOWER && t[1] < MAXPOWER )
3959 || ( *r > -MAXPOWER && t[1] > -MAXPOWER ) ) {
3962 if ( *t > MAXPOWER || *t < -MAXPOWER ) {
3963 MLOCK(ErrorMessageLock);
3964 MesPrint(
"Exponent of dotproduct out of range: %d",*t);
3965 MUNLOCK(ErrorMessageLock);
3981 else if ( *r < *++t ) {
3982 k = *r; *r++ = *t; *t = k;
3987 else if ( *r < *t ) {
3988 k = *r; *r++ = *t; *t++ = k;
3989 k = *r; *r++ = *t; *t = k;
3992 else { r += 2; t--; }
3994 else if ( *r < *t ) {
3995 k = *r; *r++ = *t; *t++ = k;
3996 k = *r; *r++ = *t; *t++ = k;
3997 k = *r; *r++ = *t; *t = k;
4006 if ( ( i = ndot ) > 0 ) {
4021 *m++ = ( i = nsym ) + 2;
4024 if ( t[1] < (2*MAXPOWER) ) {
4025 if ( t[1] & 1 ) { *m++ = 0; *m++ = 1; }
4027 if ( *++t & 2 ) ncoef = -ncoef;
4031 else if ( *t <= NumSymbols && *t > -2*MAXPOWER ) {
4032 if ( ( ( ( t[1] > symbols[*t].maxpower ) && ( symbols[*t].maxpower < MAXPOWER ) ) ||
4033 ( ( t[1] < symbols[*t].minpower ) && ( symbols[*t].minpower > -MAXPOWER ) ) ) &&
4034 ( t[1] < 2*MAXPOWER ) && ( t[1] > -2*MAXPOWER ) ) {
4035 if ( i <= 2 || t[2] != *t )
goto NormZero;
4037 if ( AN.ncmod == 1 && ( AC.modmode & ALSOPOWERS ) != 0 ) {
4038 if ( AC.cmod[0] == 1 ) t[1] = 0;
4039 else if ( t[1] >= 0 ) t[1] = 1 + (t[1]-1)%(AC.cmod[0]-1);
4041 t[1] = -1 - (-t[1]-1)%(AC.cmod[0]-1);
4042 if ( t[1] < 0 ) t[1] += (AC.cmod[0]-1);
4045 if ( ( t[1] < (2*MAXPOWER) && t[1] >= MAXPOWER )
4046 || ( t[1] > -(2*MAXPOWER) && t[1] <= -MAXPOWER ) ) {
4047 MLOCK(ErrorMessageLock);
4048 MesPrint(
"Exponent out of range: %d",t[1]);
4049 MUNLOCK(ErrorMessageLock);
4052 if ( AT.TrimPower && AR.PolyFunVar == *t && t[1] > AR.PolyFunPow ) {
4059 else { *r -= 2; t += 2; }
4062 *m++ = *t++; *m++ = *t++;
4064 }
while ( (i-=2) > 0 ); }
4065 if ( *r <= 2 ) m = r-1;
4081 if ( ABS(ncoef) == 3 && n_coef[0] == 1 && n_coef[1] == 1 ) {
4082 if ( withfloat == 1 ) {
4088 if ( t[FUNHEAD+3] < 0 ) {
4089 t[FUNHEAD+3] = -t[FUNHEAD+3];
4090 floatsign = -floatsign;
4092 if ( ncoef < 0 ) floatsign = -floatsign;
4096 AT.FloatPos = m-termout;
4097 i = t[1]; NCOPY(m,t,i)
4101 if ( m[FUNHEAD+3] < 0 ) {
4102 m[FUNHEAD+3] = -m[FUNHEAD+3];
4103 floatsign = -floatsign;
4105 if ( ncoef < 0 ) floatsign = -floatsign;
4106 AT.FloatPos = m-termout;
4111 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
4112 RatToFloat(aux5,(UWORD *)n_coef,ncoef);
4113 mpf_mul(aux4,aux4,aux5);
4115 AT.FloatPos = m-termout;
4116 if ( m[FUNHEAD+3] < 0 ) {
4117 m[FUNHEAD+3] = -m[FUNHEAD+3];
4118 floatsign = -floatsign;
4122 n_coef[0] = 1; n_coef[1] = 1; ncoef = floatsign;
4124 else AT.FloatPos = 0;
4131 stop = (WORD *)(((UBYTE *)(termout)) + AM.MaxTer);
4133 if ( ( m + i ) > stop ) {
4134 MLOCK(ErrorMessageLock);
4135 MesPrint(
"Term too complex during normalization");
4136 MUNLOCK(ErrorMessageLock);
4139 if ( AT.SS == AT.S0 ) {
4140 if ( ( m + i - termout ) > AT.SS->verbMaxTermSize ) {
4141 AT.SS->verbMaxTermSize = m+i-termout;
4144 if ( ReplaceType >= 0 ) {
4151 if ( ReplaceType == 0 ) {
4152 AT.WorkPointer = termout+*termout;
4153 WildFill(BHEAD term,termout,AN.ReplaceScrat);
4154 termout = term + *term;
4157 AT.WorkPointer = r = termout + *termout;
4158 WildFill(BHEAD r,termout,AN.ReplaceScrat);
4165 r += *term; r -= ABS(r[-1]);
4168 if ( *m >= FUNCTION && m[1] > FUNHEAD &&
4169 functions[*m-FUNCTION].spec != TENSORFUNCTION )
4183 TermFree(n_llnum,
"n_llnum");
4184 TermFree(n_coef,
"NormCoef");
4203 if ( termout < term + *term && termout >= term ) AT.WorkPointer = term + *term;
4204 else AT.WorkPointer = termout;
4211 TermFree(n_llnum,
"n_llnum");
4212 TermFree(n_coef,
"NormCoef");
4216 MLOCK(ErrorMessageLock);
4217 MesPrint(
"Division by zero during normalization");
4218 MUNLOCK(ErrorMessageLock);
4222 MLOCK(ErrorMessageLock);
4223 MesPrint(
"0^0 during normalization of term");
4224 MUNLOCK(ErrorMessageLock);
4228 MLOCK(ErrorMessageLock);
4229 MesPrint(
"0/0 in polyratfun during normalization of term");
4230 MUNLOCK(ErrorMessageLock);
4235 AT.WorkPointer = termout;
4237 TermFree(n_llnum,
"n_llnum");
4238 TermFree(n_coef,
"NormCoef");
4243 TermFree(n_llnum,
"n_llnum");
4244 TermFree(n_coef,
"NormCoef");
4248 MLOCK(ErrorMessageLock);
4250 MUNLOCK(ErrorMessageLock);
4252 TermFree(n_llnum,
"n_llnum");
4253 TermFree(n_coef,
"NormCoef");
4266int ExtraSymbol(WORD sym, WORD pow, WORD nsym, WORD *ppsym, WORD *ncoef)
4274 if ( pow > 2*MAXPOWER || pow < -2*MAXPOWER
4275 || *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
4276 MLOCK(ErrorMessageLock);
4277 MesPrint(
"Illegal wildcard power combination.");
4278 MUNLOCK(ErrorMessageLock);
4283 if ( ( sym <= NumSymbols && sym > -MAXPOWER )
4284 && ( symbols[sym].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
4285 *m %= symbols[sym].maxpower;
4286 if ( *m < 0 ) *m += symbols[sym].maxpower;
4287 if ( ( symbols[sym].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
4288 if ( ( ( symbols[sym].maxpower & 1 ) == 0 ) &&
4289 ( *m >= symbols[sym].maxpower/2 ) ) {
4290 *m -= symbols[sym].maxpower/2; *ncoef = -*ncoef;
4295 if ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
4296 MLOCK(ErrorMessageLock);
4297 MesPrint(
"Power overflow during normalization");
4298 MUNLOCK(ErrorMessageLock);
4304 { *m = m[2]; m++; *m = m[2]; m++; i++; }
4309 else if ( sym < *m ) {
4317 { m--; m[2] = *m; m--; m[2] = *m; i++; }
4328int DoTheta(PHEAD WORD *t)
4331 WORD k, *r1, *r2, *tstop, type;
4332 WORD ia, *ta, *tb, *stopa, *stopb;
4333 if ( AC.BracketNormalize )
return(-1);
4338 if ( k <= FUNHEAD )
return(1);
4341 if ( r1 == tstop ) {
4345 if ( *t == ARGHEAD ) {
4346 if ( type == THETA )
return(1);
4350 if ( *t == -SNUMBER ) {
4351 if ( t[1] < 0 )
return(0);
4353 if ( type == THETA2 && t[1] == 0 )
return(0);
4360 if ( *t == ABS(k)+1+ARGHEAD ) {
4361 if ( k > 0 )
return(1);
4371 if ( r2 < tstop )
return(-1);
4376 if ( *t == -SNUMBER && *r1 == -SNUMBER ) {
4377 if ( t[1] > r1[1] )
return(0);
4378 else if ( t[1] < r1[1] ) {
4381 else if ( type == THETA )
return(1);
4384 else if ( t[1] == 0 && *t == -SNUMBER ) {
4386 else if ( *t < *r1 )
return(1);
4387 else if ( *t > *r1 )
return(0);
4389 else if ( r1[1] == 0 && *r1 == -SNUMBER ) {
4391 else if ( *t < *r1 )
return(1);
4392 else if ( *t > *r1 )
return(0);
4394 r2 = AT.WorkPointer;
4408 ta += ARGHEAD; tb += ARGHEAD;
4409 while ( ta < stopa ) {
4410 if ( tb >= stopb )
return(0);
4411 if ( ( ia = CompareTerms(BHEAD ta,tb,(WORD)1) ) < 0 )
return(0);
4412 if ( ia > 0 )
return(1);
4416 if ( type == THETA )
return(1);
4427 WORD k, *r1, *r2, *tstop, isnum, isnum2, type = *t;
4428 if ( AC.BracketNormalize )
return(-1);
4430 if ( k <= FUNHEAD )
goto argzero;
4431 if ( k == FUNHEAD+ARGHEAD && t[FUNHEAD] == ARGHEAD )
goto argzero;
4438 if ( *t == -SNUMBER ) { isnum = 1; k = t[1]; }
4444 if ( k == *t-ARGHEAD-1 ) isnum = 1;
4448 if ( r1 >= tstop ) {
4449 if ( !isnum )
return(-1);
4450 if ( k == 0 )
goto argzero;
4455 if ( r2 < tstop )
return(-1);
4457 if ( *r1 == -SNUMBER ) { isnum2 = 1; }
4463 if ( k == *r1-ARGHEAD-1 ) isnum2 = 1;
4466 if ( isnum != isnum2 )
return(-1);
4468 while ( t < tstop && r1 < r2 ) {
4470 if ( !isnum )
return(-1);
4475 if ( t != tstop || r1 != r2 ) {
4476 if ( !isnum )
return(-1);
4480 if ( type == DELTA2 )
return(1);
4483 if ( type == DELTA2 )
return(0);
4492void DoRevert(WORD *fun, WORD *tmp)
4494 WORD *t, *r, *m, *to, *tt, *mm, i, j;
4499 if ( *r == -REVERSEFUNCTION ) {
4501 while ( mm < to ) *m++ = *mm++;
4504 fun[2] |= DIRTYSYMFLAG;
4506 else if ( *r <= -FUNCTION ) r++;
4508 if ( *r == -INDEX && r[1] < MINSPEC ) *r = -VECTOR;
4513 if ( ( *r > ARGHEAD )
4514 && ( r[ARGHEAD+1] == REVERSEFUNCTION )
4515 && ( *r == (r[ARGHEAD]+ARGHEAD) )
4516 && ( r[ARGHEAD] == (r[ARGHEAD+2]+4) )
4517 && ( *(r+*r-3) == 1 )
4518 && ( *(r+*r-2) == 1 )
4519 && ( *(r+*r-1) == 3 ) ) {
4531 while ( --j >= 0 ) {
4534 while ( --i >= 0 ) {
4541 else if ( *t <= -FUNCTION ) *m++ = *t++;
4542 else { *m++ = *t++; *m++ = *t++; }
4553 fun[1] = WORDDIF(t,fun);
4555 fun[2] |= DIRTYSYMFLAG;
4578#define MAXNUMBEROFNONCOMTERMS 2
4580WORD DetCommu(WORD *terms)
4582 WORD *t, *tnext, *tstop;
4584 if ( *terms == 0 )
return(0);
4585 if ( terms[*terms] == 0 )
return(0);
4589 tstop = tnext - ABS(tnext[-1]);
4591 while ( t < tstop ) {
4592 if ( *t >= FUNCTION ) {
4593 if ( functions[*t-FUNCTION].commute ) {
4595 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4599 else if ( *t == SUBEXPRESSION ) {
4600 if ( cbuf[t[4]].CanCommu[t[2]] ) {
4602 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4606 else if ( *t == EXPRESSION ) {
4608 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4611 else if ( *t == DOLLAREXPRESSION ) {
4618 if ( cbuf[AM.dbufnum].CanCommu[t[2]] ) {
4620 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4639WORD DoesCommu(WORD *term)
4643 if ( *term == 0 )
return(0);
4644 tstop = term + *term;
4645 tstop = tstop - ABS(tstop[-1]);
4647 while ( term < tstop ) {
4648 if ( ( *term >= FUNCTION ) && ( functions[*term-FUNCTION].commute ) ) {
4650 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4665WORD *PolyNormPoly (PHEAD WORD *Poly) {
4668 WORD *buffer = AT.WorkPointer;
4670 if (
NewSort(BHEAD0) ) { Terminate(-1); }
4676 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4682 if (
EndSort(BHEAD buffer,1) < 0 ) {
4683 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4687 while ( *p ) p += *p;
4688 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4689 AT.WorkPointer = p + 1;
4716WORD *EvaluateGcd(PHEAD WORD *subterm)
4719 WORD *oldworkpointer = AT.WorkPointer, *work1, *work2, *work3;
4720 WORD *t, *tt, *ttt, *t1, *t2, *t3, *t4, *tstop;
4723 WORD *lnum=n_llnum+1;
4724 WORD *num1, *num2, *num3, *den1, *den2, *den3;
4725 WORD sizenum1, sizenum2, sizenum3, sizeden1, sizeden2, sizeden3;
4726 int i, isnumeric = 0, numarg = 0 ;
4732 tt = subterm + subterm[1]; t = subterm + FUNHEAD;
4736 if ( *t == -SNUMBER ) {
4739 MLOCK(ErrorMessageLock);
4740 MesPrint(
"Trying to take the GCD involving a zero term.");
4741 MUNLOCK(ErrorMessageLock);
4745 t1 = subterm + FUNHEAD;
4746 while ( gcdnum > 1 && t1 < tt ) {
4747 if ( *t1 == -SNUMBER ) {
4749 if ( stor == 0 )
goto gcdzero;
4750 if ( GcdLong(BHEAD (UWORD *)&stor,1,(UWORD *)&gcdnum,1,
4751 (UWORD *)lnum,&nnum) )
goto FromGCD;
4756 else if ( *t1 == -SYMBOL )
goto gcdisone;
4757 else if ( *t1 < 0 )
goto gcdillegal;
4763 ct = *ttt; *ttt = 0;
4765 t1 = PolyNormPoly(BHEAD t1+ARGHEAD);
4774 while ( t3 > t2 && *t3 == 0 ) { t3--; i--; }
4775 if ( GcdLong(BHEAD (UWORD *)t2,(WORD)i,(UWORD *)&gcdnum,1,
4776 (UWORD *)lnum,&nnum) ) {
4781 if ( gcdnum == 1 ) {
4788 AT.WorkPointer = oldworkpointer;
4790 if ( gcdnum == 1 )
goto gcdisone;
4791 oldworkpointer[0] = 4;
4792 oldworkpointer[1] = gcdnum;
4793 oldworkpointer[2] = 1;
4794 oldworkpointer[3] = 3;
4795 oldworkpointer[4] = 0;
4796 AT.WorkPointer = oldworkpointer + 5;
4797 return(oldworkpointer);
4799 else if ( *t == -SYMBOL ) {
4800 t1 = subterm + FUNHEAD;
4803 if ( *t1 == -SNUMBER )
goto gcdisone;
4804 if ( *t1 == -SYMBOL ) {
4805 if ( t1[1] != i )
goto gcdisone;
4808 if ( *t1 < 0 )
goto gcdillegal;
4810 ct = *ttt; *ttt = 0;
4812 t2 = PolyNormPoly(BHEAD t1+ARGHEAD);
4814 else t2 = t1 + ARGHEAD;
4818 tstop = t2 - ABS(t2[-1]);
4819 while ( t3 < tstop ) {
4820 if ( *t3 != SYMBOL ) {
4827 if ( *t4 == i && t4[1] > 0 )
goto nextterminarg;
4837 AT.WorkPointer = oldworkpointer;
4839 oldworkpointer[0] = 8;
4840 oldworkpointer[1] = SYMBOL;
4841 oldworkpointer[2] = 4;
4842 oldworkpointer[3] = t[1];
4843 oldworkpointer[4] = 1;
4844 oldworkpointer[5] = 1;
4845 oldworkpointer[6] = 1;
4846 oldworkpointer[7] = 3;
4847 oldworkpointer[8] = 0;
4848 AT.WorkPointer = oldworkpointer+9;
4849 return(oldworkpointer);
4851 else if ( *t < 0 ) {
4853 MLOCK(ErrorMessageLock);
4854 MesPrint(
"Illegal object in gcd_ function. Object not a number or a symbol.");
4855 MUNLOCK(ErrorMessageLock);
4858 else if ( ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4859 else if ( t[1] != 0 ) {
4860 ttt = t + *t; ct = *ttt; *ttt = 0;
4861 t = PolyNormPoly(BHEAD t+ARGHEAD);
4863 if ( t[*t] == 0 && ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4864 AT.WorkPointer = oldworkpointer;
4879 AT.WorkPointer = oldworkpointer;
4881 t = subterm + FUNHEAD;
4882 for ( i = 1; i < isnumeric; i++ ) {
4886 ttt = t + *t; ct = *ttt; *ttt = 0;
4887 t = PolyNormPoly(BHEAD t+ARGHEAD);
4891 i = (ABS(t[-1])-1)/2;
4894 sizenum1 = sizeden1 = i;
4895 while ( sizenum1 > 1 && num1[sizenum1-1] == 0 ) sizenum1--;
4896 while ( sizeden1 > 1 && den1[sizeden1-1] == 0 ) sizeden1--;
4897 work1 = AT.WorkPointer+1; work2 = work1+sizenum1;
4898 for ( i = 0; i < sizenum1; i++ ) work1[i] = num1[i];
4899 for ( i = 0; i < sizeden1; i++ ) work2[i] = den1[i];
4900 num1 = work1; den1 = work2;
4901 AT.WorkPointer = work2 = work2 + sizeden1;
4902 t = subterm + FUNHEAD;
4904 ttt = t + *t; ct = *ttt; *ttt = 0;
4906 t = PolyNormPoly(BHEAD t+ARGHEAD);
4911 i = (ABS(t[-1])-1)/2;
4914 sizenum2 = sizeden2 = i;
4915 while ( sizenum2 > 1 && num2[sizenum2-1] == 0 ) sizenum2--;
4916 while ( sizeden2 > 1 && den2[sizeden2-1] == 0 ) sizeden2--;
4917 num3 = AT.WorkPointer;
4918 if ( GcdLong(BHEAD (UWORD *)num2,sizenum2,(UWORD *)num1,sizenum1,
4919 (UWORD *)num3,&sizenum3) )
goto FromGCD;
4920 sizenum1 = sizenum3;
4921 for ( i = 0; i < sizenum1; i++ ) num1[i] = num3[i];
4922 den3 = AT.WorkPointer;
4923 if ( GcdLong(BHEAD (UWORD *)den2,sizeden2,(UWORD *)den1,sizeden1,
4924 (UWORD *)den3,&sizeden3) )
goto FromGCD;
4925 sizeden1 = sizeden3;
4926 for ( i = 0; i < sizeden1; i++ ) den1[i] = den3[i];
4927 if ( sizenum1 == 1 && num1[0] == 1 && sizeden1 == 1 && den1[1] == 1 )
4932 AT.WorkPointer = work2;
4934 AT.WorkPointer = oldworkpointer;
4938 if ( sizenum1 > sizeden1 ) {
4939 while ( sizenum1 > sizeden1 ) den1[sizeden1++] = 0;
4941 else if ( sizenum1 < sizeden1 ) {
4942 while ( sizenum1 < sizeden1 ) num1[sizenum1++] = 0;
4947 if ( num1 != t ) { NCOPY(t,num1,sizenum1); }
4949 if ( den1 != t ) { NCOPY(t,den1,sizeden1); }
4954 return(oldworkpointer);
4961 t = subterm + FUNHEAD;
4962 AT.WorkPointer += AM.MaxTer/
sizeof(WORD);
4963 work2 = AT.WorkPointer;
4970 work1 = AT.WorkPointer;
4971 ttt = t + *t; ct = *ttt; *ttt = 0;
4972 t = PolyNormPoly(BHEAD t+ARGHEAD);
4973 if ( *work1 < AT.WorkPointer-work1 ) {
4982 *AT.WorkPointer++ = 0;
4988 if ( work2 != work3 ) {
4989 work1 = PolyGCD2(BHEAD work1,work2);
4991 while ( *work2 ) work2 += *work2;
4995 while ( *work2 ) work2 += *work2;
4996 size = work2 - work1 + 1;
4998 NCOPY(t,work1,size);
5000 return(oldworkpointer);
5003 oldworkpointer[0] = 4;
5004 oldworkpointer[1] = 1;
5005 oldworkpointer[2] = 1;
5006 oldworkpointer[3] = 3;
5007 oldworkpointer[4] = 0;
5008 AT.WorkPointer = oldworkpointer+5;
5009 return(oldworkpointer);
5011 MLOCK(ErrorMessageLock);
5012 MesCall(
"EvaluateGcd");
5013 MUNLOCK(ErrorMessageLock);
5030int TreatPolyRatFun(PHEAD WORD *prf)
5032 WORD *t, *tstop, *r, *rstop, *m, *mstop;
5033 WORD exp1 = MAXPOWER, exp2 = MAXPOWER;
5036 if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
5037 if ( exp1 > 1 ) exp1 = 1;
5041 if ( exp1 > 0 ) exp1 = 0;
5048 while ( t < tstop ) {
5054 rstop = t - ABS(t[-1]);
5055 while ( r < rstop ) {
5056 if ( *r != SYMBOL ) { r += r[1];
continue; }
5060 while ( m < mstop ) {
5061 if ( *m == AR.PolyFunVar ) {
5062 if ( m[1] < exp1 ) exp1 = m[1];
5068 if ( exp1 > 0 ) exp1 = 0;
5073 if ( exp1 > 0 ) exp1 = 0;
5079 if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
5080 if ( exp2 > 1 ) exp2 = 1;
5083 if ( exp2 > 0 ) exp2 = 0;
5089 while ( t < tstop ) {
5095 rstop = t - ABS(t[-1]);
5096 while ( r < rstop ) {
5097 if ( *r != SYMBOL ) { r += r[1];
continue; }
5101 while ( m < mstop ) {
5102 if ( *m == AR.PolyFunVar ) {
5103 if ( m[1] < exp2 ) exp2 = m[1];
5109 if ( exp2 > 0 ) exp2 = 0;
5114 if ( exp2 > 0 ) exp2 = 0;
5127 *t++ = -SNUMBER; *t++ = 1;
5128 *t++ = -SNUMBER; *t++ = 1;
5130 else if ( exp1 > 0 ) {
5132 *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
5138 *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
5139 *t++ = exp1; *t++ = 1; *t++ = 1; *t++ = 3;
5141 *t++ = -SNUMBER; *t++ = 1;
5144 *t++ = -SNUMBER; *t++ = 1;
5146 *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
5152 *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
5153 *t++ = -exp1; *t++ = 1; *t++ = 1; *t++ = 3;
5166void DropCoefficient(PHEAD WORD *term)
5169 WORD *t = term + *term;
5171 n = t[-1]; na = ABS(n);
5173 if ( n == 3 && t[0] == 1 && t[1] == 1 )
return;
5175 t[0] = 1; t[1] = 1; t[2] = 3;
5184void DropSymbols(PHEAD WORD *term)
5187 WORD *tend = term + *term, *t1, *t2, *tstop;
5188 tstop = tend - ABS(tend[-1]);
5190 while ( t1 < tstop ) {
5191 if ( *t1 == SYMBOL ) {
5194 while ( t2 < tend ) *t1++ = *t2++;
5217 WORD *t, *b, *bb, *tt, *m, *tstop;
5220 WORD buffer[7*NORMSIZE];
5223 *b++ = SYMBOL; *b++ = 2;
5225 tstop = t - ABS(t[-1]);
5227 while ( t < tstop ) {
5228 if ( *t == SYMBOL && t < tstop ) {
5229 for ( i = 2; i < t[1]; i += 2 ) {
5230 const WORD sym = t[i];
5231 const WORD pow = t[i+1];
5234 if ( bb[0] == sym ) {
5236 if ( bb[1] > MAXPOWER || bb[1] < -MAXPOWER ) {
5237 MLOCK(ErrorMessageLock);
5238 MesPrint(
"Power in SymbolNormalize out of range");
5239 MUNLOCK(ErrorMessageLock);
5245 bb[0] = bb[2]; bb[1] = bb[3]; bb += 2;
5250 else if ( bb[0] > sym ) {
5252 while ( m > bb ) { m[1] = m[-1]; m[0] = m[-2]; m -= 2; }
5261 *b++ = sym; *b++ = pow;
5267 MLOCK(ErrorMessageLock);
5268 MesPrint(
"Illegal term in SymbolNormalize");
5269 MUNLOCK(ErrorMessageLock);
5274 buffer[1] = b - buffer;
5278 if ( AT.LeaveNegative == 0 ) {
5279 b = buffer; bb = b + b[1]; b += 3;
5282 MLOCK(ErrorMessageLock);
5283 MesPrint(
"Negative power in SymbolNormalize");
5284 MUNLOCK(ErrorMessageLock);
5296 b = buffer; tt = term + 1;
5297 if ( i > 2 ) { NCOPY(tt,b,i) }
5300 if ( i < 0 ) i = -i;
5301 *term -= (tstop-tt);
5315int TestFunFlag(PHEAD WORD *tfun)
5317 WORD *t, *tstop, *r, *rstop, *m, *mstop;
5320 if ( *tfun != DENOMINATOR && *tfun != EXPONENT
5321 && functions[*tfun-FUNCTION].spec <= 0 ) {
5325 tstop = tfun + tfun[1];
5327 while ( t < tstop ) {
5328 if ( *t < 0 ) { NEXTARG(t);
continue; }
5330 if ( t[1] == 0 ) { t = rstop;
continue; }
5332 while ( r < rstop ) {
5333 m = r+1; mstop = r+*r; mstop -= ABS(mstop[-1]);
5334 while ( m < mstop ) {
5335 if ( *m == SUBEXPRESSION || *m == EXPRESSION || *m == DOLLAREXPRESSION )
return(1);
5336 if ( ( *m >= FUNCTION ) && ( ( m[2] & DIRTYFLAG ) == DIRTYFLAG )
5337 && ( *m != REPLACEMENT ) && TestFunFlag(BHEAD m) )
return(1);
5352int BracketNormalize(PHEAD WORD *term)
5354 WORD *stop = term+*term-3, *t, *tt, *tstart, *r;
5355 WORD *oldwork = AT.WorkPointer;
5358 termout = AT.WorkPointer = term+*term;
5362 tt = termout+1; t = term+1;
5363 while ( t < stop ) {
5364 if ( *t >= FUNCTION ) { i = t[1]; NCOPY(tt,t,i); }
5367 if ( tt > termout+1 && tt-termout-1 > termout[2] ) {
5368 r = termout+1; ii = tt-r;
5369 for ( i = 0; i < ii-FUNHEAD; i += FUNHEAD ) {
5370 for ( j = i+FUNHEAD; j > 0; j -= FUNHEAD ) {
5371 if ( functions[r[j-FUNHEAD]-FUNCTION].commute
5372 && functions[r[j]-FUNCTION].commute == 0 )
break;
5373 if ( r[j-FUNHEAD] > r[j] ) EXCH(r[j-FUNHEAD],r[j])
5379 tstart = tt; t = term + 1; *tt++ = DELTA; *tt++ = 2;
5380 while ( t < stop ) {
5381 if ( *t == DELTA ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5384 if ( tstart[1] > 2 ) {
5385 for ( r = tstart+2; r < tstart+tstart[1]; r += 2 ) {
5386 if ( r[0] > r[1] ) EXCH(r[0],r[1])
5389 if ( tstart[1] > 4 ) {
5390 r = tstart+2; ii = tstart[1]-2;
5391 for ( i = 0; i < ii-2; i += 2 ) {
5392 for ( j = i+2; j > 0; j -= 2 ) {
5393 if ( r[j-2] > r[j] ) {
5397 else if ( r[j-2] < r[j] )
break;
5399 if ( r[j-1] > r[j+1] ) EXCH(r[j-1],r[j+1])
5404 tt = tstart+tstart[1];
5406 else if ( tstart[1] == 2 ) { tt = tstart; }
5409 tstart = tt; t = term + 1; *tt++ = INDEX; *tt++ = 2;
5410 while ( t < stop ) {
5411 if ( *t == INDEX ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5414 if ( tstart[1] >= 4 ) {
5415 r = tstart+2; ii = tstart[1]-2;
5416 for ( i = 0; i < ii-1; i += 1 ) {
5417 for ( j = i+1; j > 0; j -= 1 ) {
5418 if ( r[j-1] > r[j] ) EXCH(r[j-1],r[j])
5422 tt = tstart+tstart[1];
5424 else if ( tstart[1] == 2 ) { tt = tstart; }
5427 tstart = tt; t = term + 1; *tt++ = DOTPRODUCT; *tt++ = 2;
5428 while ( t < stop ) {
5429 if ( *t == DOTPRODUCT ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5432 if ( tstart[1] > 5 ) {
5433 r = tstart+2; ii = tstart[1]-2;
5434 for ( i = 0; i < ii; i += 3 ) {
5435 if ( r[i] > r[i+1] ) EXCH(r[i],r[i+1])
5437 for ( i = 0; i < ii-3; i += 3 ) {
5438 for ( j = i+3; j > 0; j -= 3 ) {
5439 if ( r[j-3] < r[j] )
break;
5440 if ( r[j-3] > r[j] ) {
5445 if ( r[j-2] > r[j+1] ) EXCH(r[j-2],r[j+1])
5450 tt = tstart+tstart[1];
5452 else if ( tstart[1] == 2 ) { tt = tstart; }
5454 if ( tstart[2] > tstart[3] ) EXCH(tstart[2],tstart[3])
5458 tstart = tt; t = term + 1; *tt++ = SYMBOL; *tt++ = 2;
5459 while ( t < stop ) {
5460 if ( *t == SYMBOL ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5463 if ( tstart[1] > 4 ) {
5464 r = tstart+2; ii = tstart[1]-2;
5465 for ( i = 0; i < ii-2; i += 2 ) {
5466 for ( j = i+2; j > 0; j -= 2 ) {
5467 if ( r[j-2] > r[j] ) EXCH(r[j-2],r[j])
5471 tt = tstart+tstart[1];
5473 else if ( tstart[1] == 2 ) { tt = tstart; }
5476 tstart = tt; t = term + 1; *tt++ = SETSET; *tt++ = 2;
5477 while ( t < stop ) {
5478 if ( *t == SETSET ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5481 if ( tstart[1] > 4 ) {
5482 r = tstart+2; ii = tstart[1]-2;
5483 for ( i = 0; i < ii-2; i += 2 ) {
5484 for ( j = i+2; j > 0; j -= 2 ) {
5485 if ( r[j-2] > r[j] ) {
5492 tt = tstart+tstart[1];
5494 else if ( tstart[1] == 2 ) { tt = tstart; }
5496 *tt++ = 1; *tt++ = 1; *tt++ = 3;
5497 t = term; i = *termout = tt - termout; tt = termout;
5499 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)