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");
269 TermFree(n_coef,
"NormCoef");
270 TermFree(n_llnum,
"n_llnum");
280 termout = AT.WorkPointer;
281 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
282 fillsetexp = termout+1;
283 AN.PolyNormFlag = 0; PolyFunMode = AN.PolyFunTodo;
291 nsym = nvec = ndot = ndel = neps = nden =
292 nind = ncom = nnco = ncon = 0;
311 if ( *t <= DENOMINATORSYMBOL && *t >= COEFFSYMBOL ) {
317 if ( AN.cTerm ) m = AN.cTerm;
320 ncoef = REDLENG(ncoef);
321 if ( *t == COEFFSYMBOL ) {
323 nnum = REDLENG(m[-1]);
327 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
328 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
334 if ( DivRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
335 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
343 if ( *t == NUMERATORSYMBOL ) { m -= nnum + 1; }
345 while ( *m == 0 && nnum > 1 ) { m--; nnum--; }
347 if ( i < 0 && *t == NUMERATORSYMBOL ) nnum = -nnum;
351 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)m,nnum) )
358 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)m,nnum) )
364 ncoef = INCLENG(ncoef);
368 else if ( *t == DIMENSIONSYMBOL ) {
369 if ( AN.cTerm ) m = AN.cTerm;
371 k = DimensionTerm(m);
372 if ( k == 0 )
goto NormZero;
373 if ( k == MAXPOSITIVE ) {
374 MLOCK(ErrorMessageLock);
375 MesPrint(
"Dimension_ is undefined in term %t");
376 MUNLOCK(ErrorMessageLock);
379 if ( k == -MAXPOSITIVE ) {
380 MLOCK(ErrorMessageLock);
381 MesPrint(
"Dimension_ out of range in term %t");
382 MUNLOCK(ErrorMessageLock);
385 if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
386 else { *((UWORD *)lnum) = -k; nnum = -1; }
387 ncoef = REDLENG(ncoef);
388 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
389 ncoef = INCLENG(ncoef);
393 if ( ( *t >= MAXPOWER && *t < 2*MAXPOWER )
394 || ( *t < -MAXPOWER && *t > -2*MAXPOWER ) ) {
401 if ( t[1] & 1 ) ncoef = -ncoef;
403 else if ( *t == MAXPOWER ) {
404 if ( t[1] > 0 )
goto NormZero;
412 if ( t[1] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[1]))) )
414 ncoef = REDLENG(ncoef);
416 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
419 else if ( t[1] > 0 ) {
420 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
423 ncoef = INCLENG(ncoef);
430 if ( ( *t <= NumSymbols && *t > -MAXPOWER )
431 && ( symbols[*t].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
432 if ( t[1] <= 2*MAXPOWER && t[1] >= -2*MAXPOWER ) {
433 t[1] %= symbols[*t].maxpower;
434 if ( t[1] < 0 ) t[1] += symbols[*t].maxpower;
435 if ( ( symbols[*t].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
436 if ( ( ( symbols[*t].maxpower & 1 ) == 0 ) &&
437 ( t[1] >= symbols[*t].maxpower/2 ) ) {
438 t[1] -= symbols[*t].maxpower/2; ncoef = -ncoef;
441 if ( t[1] == 0 ) { t += 2;
goto NextSymbol; }
450 if ( *t > 2*MAXPOWER || *t < -2*MAXPOWER
451 || *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
452 MLOCK(ErrorMessageLock);
453 MesPrint(
"Illegal wildcard power combination.");
454 MUNLOCK(ErrorMessageLock);
458 if ( ( t[-1] <= NumSymbols && t[-1] > -MAXPOWER )
459 && ( symbols[t[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
460 *m %= symbols[t[-1]].maxpower;
461 if ( *m < 0 ) *m += symbols[t[-1]].maxpower;
462 if ( ( symbols[t[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
463 if ( ( ( symbols[t[-1]].maxpower & 1 ) == 0 ) &&
464 ( *m >= symbols[t[-1]].maxpower/2 ) ) {
465 *m -= symbols[t[-1]].maxpower/2; ncoef = -ncoef;
469 if ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
470 MLOCK(ErrorMessageLock);
471 MesPrint(
"Power overflow during normalization");
472 MUNLOCK(ErrorMessageLock);
478 { *m = m[2]; m++; *m = m[2]; m++; i++; }
485 }
while ( *t < *m && --i > 0 );
488 { m--; m[2] = *m; m--; m[2] = *m; i++; }
500 if ( t[0] == AM.vectorzero )
goto NormZero;
501 if ( t[1] == FUNNYVEC ) {
505 else if ( t[1] < 0 ) {
506 if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
508 if ( t[1] == AM.vectorzero )
goto NormZero;
509 *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++;
512 else { *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2; }
518 if ( t[2] == 0 ) t += 3;
519 else if ( ndot > 0 && t[0] == ppdot[-3]
520 && t[1] == ppdot[-2] ) {
523 if ( ppdot[-1] == 0 ) { ppdot -= 3; ndot--; }
525 else if ( t[0] == AM.vectorzero || t[1] == AM.vectorzero ) {
526 if ( t[2] > 0 )
goto NormZero;
530 *ppdot++ = *t++; *ppdot++ = *t++;
531 *ppdot++ = *t++; ndot++;
538 if ( WildFill(BHEAD termout,term,AT.dummysubexp) < 0 )
goto FromNorm;
540 t = termout; m = term;
543 case DOLLAREXPRESSION :
550 if ( AR.Eside != LHSIDE ) {
553 int nummodopt, ptype = -1;
554 if ( AS.MultiThreaded ) {
555 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
556 if ( t[2] == ModOptdollars[nummodopt].number )
break;
558 if ( nummodopt < NumModOptdollars ) {
559 ptype = ModOptdollars[nummodopt].type;
560 if ( ptype == MODLOCAL ) {
561 d = ModOptdollars[nummodopt].dstruct+AT.identity;
564 LOCK(d->pthreadslock);
569 if ( d->type == DOLZERO ) {
571 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
573 if ( t[3] == 0 )
goto NormZZ;
574 if ( t[3] < 0 )
goto NormInf;
577 else if ( d->type == DOLNUMBER ) {
580 nnum = d->where[nnum-1];
581 if ( nnum < 0 ) { ncoef = -ncoef; nnum = -nnum; }
583 for ( i = 1; i <= nnum; i++ ) lnum[i-1] = d->where[i];
585 if ( nnum == 0 || ( nnum == 1 && lnum[0] == 0 ) ) {
587 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
589 if ( t[3] < 0 )
goto NormInf;
590 else if ( t[3] == 0 )
goto NormZZ;
593 if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) )
goto FromNorm;
594 ncoef = REDLENG(ncoef);
596 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
598 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
603 else if ( t[3] > 0 ) {
604 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
606 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
611 ncoef = INCLENG(ncoef);
613 else if ( d->type == DOLINDEX ) {
614 if ( d->index == 0 ) {
616 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
620 if ( d->index != NOINDEX ) pind[nind++] = d->index;
622 else if ( d->type == DOLTERMS ) {
623 if ( t[3] >= MAXPOWER || t[3] <= -MAXPOWER ) {
624 if ( d->where[0] == 0 )
goto NormZero;
625 if ( d->where[d->where[0]] != 0 ) {
627 MLOCK(ErrorMessageLock);
628 MesPrint(
"!!!Illegal $ expansion with wildcard power!!!");
629 MUNLOCK(ErrorMessageLock);
636 { WORD *td, *tdstop, dj;
638 tdstop = d->where+d->where[0];
639 if ( tdstop[-1] != 3 || tdstop[-2] != 1
640 || tdstop[-3] != 1 )
goto IllDollarExp;
642 if ( td >= tdstop )
goto IllDollarExp;
643 while ( td < tdstop ) {
644 if ( *td == SYMBOL ) {
645 for ( dj = 2; dj < td[1]; dj += 2 ) {
646 if ( td[dj+1] == 1 ) {
651 else if ( td[dj+1] == -1 ) {
656 else goto IllDollarExp;
659 else if ( *td == DOTPRODUCT ) {
660 for ( dj = 2; dj < td[1]; dj += 3 ) {
661 if ( td[dj+2] == 1 ) {
667 else if ( td[dj+2] == -1 ) {
673 else goto IllDollarExp;
676 else goto IllDollarExp;
683 t[0] = SUBEXPRESSION;
687 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
694 if ( *t == DOLLAREXPRESSION ) {
696 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
700 if ( AS.MultiThreaded ) {
701 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
702 if ( t[2] == ModOptdollars[nummodopt].number )
break;
704 if ( nummodopt < NumModOptdollars ) {
705 ptype = ModOptdollars[nummodopt].type;
706 if ( ptype == MODLOCAL ) {
707 d = ModOptdollars[nummodopt].dstruct+AT.identity;
710 LOCK(d->pthreadslock);
715 if ( d->type == DOLTERMS ) {
716 t[0] = SUBEXPRESSION;
723 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
729 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
731 MLOCK(ErrorMessageLock);
732 MesPrint(
"!!!This $ variation has not been implemented yet!!!");
733 MUNLOCK(ErrorMessageLock);
737 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslock); }
753 if ( *t == SUMMEDIND ) {
754 if ( t[1] < -NMIN4SHIFT ) {
755 k = -t[1]-NMIN4SHIFT;
756 k = ExtraSymbol(k,1,nsym,ppsym,&ncoef);
760 else if ( t[1] == 0 )
goto NormZero;
770 ncoef = REDLENG(ncoef);
771 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
773 ncoef = INCLENG(ncoef);
777 else if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
778 else if ( *t == EMPTYINDEX && t[1] == EMPTYINDEX ) {
779 *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2;
783 *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++;
786 *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2;
791 *ppvec++ = t[1]; *ppvec++ = *t; t+=2; nvec += 2;
793 else { *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2; }
801 if ( t[FUNHEAD] == -SNUMBER && t[1] == FUNHEAD+2
802 && t[FUNHEAD+1] >= 0 ) {
803 if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
806 ncoef = REDLENG(ncoef);
807 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
808 ncoef = INCLENG(ncoef);
810 else pcom[ncom++] = t;
812 case BERNOULLIFUNCTION :
816 if ( ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 )
817 && ( t[1] == FUNHEAD+2 || ( t[1] == FUNHEAD+4 &&
818 t[FUNHEAD+2] == -SNUMBER && ABS(t[FUNHEAD+3]) == 1 ) ) ) {
820 if ( Bernoulli(t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
822 if ( nnum == 0 )
goto NormZero;
823 inum = nnum;
if ( inum < 0 ) inum = -inum;
826 while ( lnum[mnum-1] == 0 ) mnum--;
827 if ( nnum < 0 ) mnum = -mnum;
828 ncoef = REDLENG(ncoef);
829 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,mnum) )
goto FromNorm;
831 while ( lnum[inum+mnum-1] == 0 ) mnum--;
832 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(lnum+inum),mnum) )
goto FromNorm;
833 ncoef = INCLENG(ncoef);
834 if ( t[1] == FUNHEAD+4 && t[FUNHEAD+1] == 1
835 && t[FUNHEAD+3] == -1 ) ncoef = -ncoef;
837 else pcom[ncom++] = t;
849 if ( k == 0 )
goto NormZero;
850 *((UWORD *)lnum) = k;
858 if ( *t == -EXPRESSION ) {
859 k = AS.OldNumFactors[t[1]];
861 else if ( *t == -DOLLAREXPRESSION ) {
862 k = Dollars[t[1]].nfactors;
868 if ( k == 0 )
goto NormZero;
869 *((UWORD *)lnum) = k;
876 if ( t[FUNHEAD] < 0 ) {
877 if ( t[FUNHEAD] <= -FUNCTION && t[1] == FUNHEAD+1 )
break;
878 if ( t[FUNHEAD] > -FUNCTION && t[1] == FUNHEAD+2 ) {
879 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 )
goto NormZero;
885 if ( t[FUNHEAD] > 0 && t[FUNHEAD] == t[1]-FUNHEAD ) {
887 t += FUNHEAD+ARGHEAD;
892 if ( k == 0 )
goto NormZero;
893 *((UWORD *)lnum) = k;
897 else pcom[ncom++] = t;
901 k = CountFun(AN.cTerm,t);
904 k = CountFun(term,t);
906 if ( k == 0 )
goto NormZero;
907 if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
908 else { *((UWORD *)lnum) = -k; nnum = -1; }
912 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] == -SNUMBER
913 && t[1] == FUNHEAD+4 && t[FUNHEAD+3] > 1 ) {
915 if ( t[FUNHEAD+1] == 0 )
goto NormZero;
916 if ( t[FUNHEAD+1] < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; sgn = -1; }
918 if ( MakeRational(t[FUNHEAD+1],t[FUNHEAD+3],x1,x1+1) ) {
919 static int warnflag = 1;
921 MesPrint(
"%w Warning: fraction could not be reconstructed in MakeRational_");
924 x1[0] = t[FUNHEAD+1]; x1[1] = 1;
926 if ( sgn < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; x1[0] = -x1[0]; }
927 if ( x1[0] < 0 ) { sgn = -1; x1[0] = -x1[0]; }
929 ncoef = REDLENG(ncoef);
930 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)x1,sgn,
931 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
932 ncoef = INCLENG(ncoef);
935 WORD narg = 0, *tt, *ttstop, *arg1 = 0, *arg2 = 0;
938 ttstop = t + t[1]; tt = t+FUNHEAD;
939 while ( tt < ttstop ) {
941 if ( narg == 1 ) arg1 = tt;
945 if ( narg != 2 )
goto defaultcase;
946 if ( *arg2 == -SNUMBER && arg2[1] <= 1 )
goto defaultcase;
947 else if ( *arg2 > 0 && ttstop[-1] < 0 )
goto defaultcase;
948 x1 = NumberMalloc(
"Norm-MakeRational");
949 if ( *arg1 == -SNUMBER ) {
950 if ( arg1[1] == 0 ) {
951 NumberFree(x1,
"Norm-MakeRational");
954 if ( arg1[1] < 0 ) { x1[0] = -arg1[1]; nx1 = -1; }
955 else { x1[0] = arg1[1]; nx1 = 1; }
957 else if ( *arg1 > 0 ) {
959 nx1 = (ABS(arg2[-1])-1)/2;
960 tc = arg1+ARGHEAD+1+nx1;
962 NumberFree(x1,
"Norm-MakeRational");
965 for ( i = 1; i < nx1; i++ )
if ( tc[i] != 0 ) {
966 NumberFree(x1,
"Norm-MakeRational");
970 for ( i = 0; i < nx1; i++ ) x1[i] = tc[i];
971 if ( arg2[-1] < 0 ) nx1 = -nx1;
974 NumberFree(x1,
"Norm-MakeRational");
977 x2 = NumberMalloc(
"Norm-MakeRational");
978 if ( *arg2 == -SNUMBER ) {
979 if ( arg2[1] <= 1 ) {
980 NumberFree(x2,
"Norm-MakeRational");
981 NumberFree(x1,
"Norm-MakeRational");
984 else { x2[0] = arg2[1]; nx2 = 1; }
986 else if ( *arg2 > 0 ) {
988 nx2 = (ttstop[-1]-1)/2;
989 tc = arg2+ARGHEAD+1+nx2;
991 NumberFree(x2,
"Norm-MakeRational");
992 NumberFree(x1,
"Norm-MakeRational");
995 for ( i = 1; i < nx2; i++ )
if ( tc[i] != 0 ) {
996 NumberFree(x2,
"Norm-MakeRational");
997 NumberFree(x1,
"Norm-MakeRational");
1000 tc = arg2+ARGHEAD+1;
1001 for ( i = 0; i < nx2; i++ ) x2[i] = tc[i];
1004 NumberFree(x2,
"Norm-MakeRational");
1005 NumberFree(x1,
"Norm-MakeRational");
1008 if ( BigLong(x1,ABS(nx1),x2,nx2) >= 0 ) {
1009 UWORD *x3 = NumberMalloc(
"Norm-MakeRational");
1010 UWORD *x4 = NumberMalloc(
"Norm-MakeRational");
1012 DivLong(x1,nx1,x2,nx2,x3,&nx3,x4,&nx4);
1013 for ( i = 0; i < ABS(nx4); i++ ) x1[i] = x4[i];
1015 NumberFree(x4,
"Norm-MakeRational");
1016 NumberFree(x3,
"Norm-MakeRational");
1018 xx = (UWORD *)(TermMalloc(
"Norm-MakeRational"));
1019 if ( MakeLongRational(BHEAD x1,nx1,x2,nx2,xx,&nxx) ) {
1020 static int warnflag = 1;
1022 MesPrint(
"%w Warning: fraction could not be reconstructed in MakeRational_");
1025 ncoef = REDLENG(ncoef);
1026 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,x1,nx1) )
1030 ncoef = REDLENG(ncoef);
1031 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,xx,nxx,
1032 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1034 ncoef = INCLENG(ncoef);
1035 TermFree(xx,
"Norm-MakeRational");
1036 NumberFree(x2,
"Norm-MakeRational");
1037 NumberFree(x1,
"Norm-MakeRational");
1041 if ( t[1] == FUNHEAD && AN.cTerm ) {
1042 ANsr = r; ANsm = m; ANsc = AN.cTerm;
1046 ncoef = REDLENG(ncoef);
1047 nnum = REDLENG(m[-1]);
1049 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,nnum,
1050 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1051 ncoef = INCLENG(ncoef);
1056 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1057 if ( GetFirstBracket(termout,t[FUNHEAD+1]) < 0 )
goto FromNorm;
1058 if ( *termout == 0 )
goto NormZero;
1059 if ( *termout > 4 ) {
1061 while ( r < m ) *t++ = *r++;
1063 r2 = termout + *termout; r2 -= ABS(r2[-1]);
1064 while ( r < r1 ) *r2++ = *r++;
1066 while ( r3 < r2 ) *t++ = *r3++;
1068 if ( AT.WorkPointer > term && AT.WorkPointer < t )
1076 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1079 POSITION oldondisk = AS.OldOnFile[t[FUNHEAD+1]];
1080 if ( e->replace == NEWLYDEFINEDEXPRESSION ) {
1081 AS.OldOnFile[t[FUNHEAD+1]] = e->onfile;
1083 if ( *t == FIRSTTERM ) {
1084 if (
GetFirstTerm(termout,t[FUNHEAD+1],0) < 0 )
goto FromNorm;
1086 else if ( *t == CONTENTTERM ) {
1087 if ( GetContent(termout,t[FUNHEAD+1]) < 0 )
goto FromNorm;
1089 AS.OldOnFile[t[FUNHEAD+1]] = oldondisk;
1090 if ( *termout == 0 )
goto NormZero;
1094 WORD *r1, *r2, *r3, *r4, *r5, nr1, *rterm;
1095 r2 = termout + *termout; lnum = r2 - ABS(r2[-1]);
1096 nnum = REDLENG(r2[-1]);
1098 r1 = term + *term; r3 = r1 - ABS(r1[-1]);
1099 nr1 = REDLENG(r1[-1]);
1100 if ( Mully(BHEAD (UWORD *)lnum,&nnum,(UWORD *)r3,nr1) )
goto FromNorm;
1101 nnum = INCLENG(nnum); nr1 = ABS(nnum); lnum[nr1-1] = nnum;
1102 rterm = TermMalloc(
"FirstTerm/ContentTerm");
1103 r4 = rterm+1; r5 = term+1;
while ( r5 < t ) *r4++ = *r5++;
1104 r5 = termout+1;
while ( r5 < lnum ) *r4++ = *r5++;
1105 r5 = r;
while ( r5 < r3 ) *r4++ = *r5++;
1106 r5 = lnum; NCOPY(r4,r5,nr1);
1108 nr1 = *rterm; r1 = term; r2 = rterm; NCOPY(r1,r2,nr1);
1109 TermFree(rterm,
"FirstTerm/ContentTerm");
1110 if ( AT.WorkPointer > term && AT.WorkPointer < r1 )
1111 AT.WorkPointer = r1;
1115 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
1116 DOLLARS d = Dollars + t[FUNHEAD+1], newd = 0;
1119 int nummodopt, dtype = -1;
1120 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
1121 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
1122 if ( t[FUNHEAD+1] == ModOptdollars[nummodopt].number )
break;
1124 if ( nummodopt < NumModOptdollars ) {
1125 dtype = ModOptdollars[nummodopt].type;
1126 if ( dtype == MODLOCAL ) {
1127 d = ModOptdollars[nummodopt].dstruct+AT.identity;
1132 if ( d->where && ( d->type == DOLTERMS || d->type == DOLNUMBER ) ) {
1136 if ( ( newd = DolToTerms(BHEAD t[FUNHEAD+1]) ) == 0 )
1139 if ( newd->where[0] == 0 ) {
1140 M_free(newd,
"Copy of dollar variable");
1143 if ( *t == FIRSTTERM ) {
1144 idol = newd->where[0];
1145 for ( ido = 0; ido < idol; ido++ ) termout[ido] = newd->where[ido];
1147 else if ( *t == CONTENTTERM ) {
1149 tterm = newd->where;
1151 for ( ido = 0; ido < idol; ido++ ) termout[ido] = tterm[ido];
1154 if ( ContentMerge(BHEAD termout,tterm) < 0 )
goto FromNorm;
1159 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
1160 M_free(newd,
"Copy of dollar variable");
1168 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1169 x = TermsInExpression(t[FUNHEAD+1]);
1170multermnum:
if ( x == 0 )
goto NormZero;
1173 if ( x > (LONG)WORDMASK ) { lnum[0] = x & WORDMASK;
1174 lnum[1] = x >> BITSINWORD; nnum = -2;
1176 else { lnum[0] = x; nnum = -1; }
1178 else if ( x > (LONG)WORDMASK ) {
1179 lnum[0] = x & WORDMASK;
1180 lnum[1] = x >> BITSINWORD;
1183 else { lnum[0] = x; nnum = 1; }
1184 ncoef = REDLENG(ncoef);
1185 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
1187 ncoef = INCLENG(ncoef);
1189 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
1190 x = TermsInDollar(t[FUNHEAD+1]);
1193 else { pcom[ncom++] = t; }
1196 case SIZEOFFUNCTION:
1198 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
1199 x = SizeOfExpression(t[FUNHEAD+1]);
1202 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
1203 x = SizeOfDollar(t[FUNHEAD+1]);
1206 else { pcom[ncom++] = t; }
1210 case PATTERNFUNCTION:
1217 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1218 && t[FUNHEAD+1] >= 0 && t[FUNHEAD+2] == -SNUMBER
1219 && t[FUNHEAD+3] >= 0 && t[FUNHEAD+1] >= t[FUNHEAD+3] ) {
1220 if ( t[FUNHEAD+1] > t[FUNHEAD+3] ) {
1221 if ( GetBinom((UWORD *)lnum,&nnum,
1222 t[FUNHEAD+1],t[FUNHEAD+3]) )
goto FromNorm;
1223 if ( nnum == 0 )
goto NormZero;
1227 else pcom[ncom++] = t;
1233 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1234 if ( ( t[FUNHEAD+1] & 1 ) != 0 ) ncoef = -ncoef;
1236 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
1237 && ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) ) {
1238 UWORD *numer1,*denom1;
1239 WORD nsize = abs(t[t[1]-1]), nnsize, isize;
1240 nnsize = (nsize-1)/2;
1241 numer1 = (UWORD *)(t + FUNHEAD+ARGHEAD+1);
1242 denom1 = numer1 + nnsize;
1243 for ( isize = 1; isize < nnsize; isize++ ) {
1244 if ( denom1[isize] )
break;
1246 if ( ( denom1[0] != 1 ) || isize < nnsize ) {
1250 if ( ( numer1[0] & 1 ) != 0 ) ncoef = -ncoef;
1264 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1265 if ( t[FUNHEAD+1] < 0 ) ncoef = -ncoef;
1267 else if ( ( t[1] == FUNHEAD+2 ) && ( t[FUNHEAD] == -SYMBOL )
1268 && ( ( t[FUNHEAD+1] <= NumSymbols && t[FUNHEAD+1] > -MAXPOWER )
1269 && ( symbols[t[FUNHEAD+1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) ) {
1279 *m %= symbols[k].maxpower;
1280 if ( ( symbols[k].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
1281 if ( ( ( symbols[k].maxpower & 1 ) == 0 ) &&
1282 ( *m >= symbols[k].maxpower/2 ) ) {
1283 *m -= symbols[k].maxpower/2; ncoef = -ncoef;
1289 { *m = m[2]; m++; *m = m[2]; m++; i++; }
1295 }
while ( k < *m && --i > 0 );
1298 { m--; m[2] = *m; m--; m[2] = *m; i++; }
1306 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] ) ) {
1307 if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
1308 if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
1313 else if ( ( t[FUNHEAD+ARGHEAD]+FUNHEAD+ARGHEAD == t[1] )
1314 && ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) ) {
1315 WORD *ts = t + FUNHEAD+ARGHEAD+3;
1316 WORD its = ts[-1]-2;
1318 if ( ( *ts != 0 ) && ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
1319 || ( symbols[*ts].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY ) ) {
1328 if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
1329 ts = t + FUNHEAD+ARGHEAD+3;
1340 if ( ( ts[-1] <= NumSymbols && ts[-1] > -MAXPOWER ) &&
1341 ( symbols[ts[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
1342 *m %= symbols[ts[-1]].maxpower;
1343 if ( *m < 0 ) *m += symbols[ts[-1]].maxpower;
1344 if ( ( symbols[ts[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
1345 if ( ( ( symbols[ts[-1]].maxpower & 1 ) == 0 ) &&
1346 ( *m >= symbols[ts[-1]].maxpower/2 ) ) {
1347 *m -= symbols[ts[-1]].maxpower/2; ncoef = -ncoef;
1354 { *m = m[2]; m++; *m = m[2]; m++; i++; }
1361 }
while ( *ts < *m && --i > 0 );
1364 { m--; m[2] = *m; m--; m[2] = *m; i++; }
1374signogood: pcom[ncom++] = t;
1377 else pcom[ncom++] = t;
1384 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1386 if ( k < 0 ) k = -k;
1387 if ( k == 0 )
goto NormZero;
1388 *((UWORD *)lnum) = k; nnum = 1;
1392 else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SYMBOL ) {
1394 if ( ( k > NumSymbols || k <= -MAXPOWER )
1395 || ( symbols[k].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
1398 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
1399 && ( t[1] == FUNHEAD+ARGHEAD+t[FUNHEAD+ARGHEAD] ) ) {
1400 if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
1402absnosymbols: ts = t + t[1] -1;
1403 ncoef = REDLENG(ncoef);
1404 nnum = REDLENG(*ts);
1405 if ( nnum < 0 ) nnum = -nnum;
1406 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,
1407 (UWORD *)(ts-ABS(*ts)+1),nnum,
1408 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1409 ncoef = INCLENG(ncoef);
1414 else if ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) {
1415 WORD *ts = t+FUNHEAD+ARGHEAD+1;
1416 WORD its = ts[1] - 2;
1420 else if ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
1421 || ( symbols[*ts].complex & VARTYPEROOTOFUNITY )
1422 != VARTYPEROOTOFUNITY )
goto absnogood;
1428absnogood: pcom[ncom++] = t;
1431 else pcom[ncom++] = t;
1439 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1440 && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+3] > 1 ) {
1442 tmod = (t[FUNHEAD+1]%t[FUNHEAD+3]);
1443 if ( tmod < 0 ) tmod += t[FUNHEAD+3];
1444 if ( *t == MOD2FUNCTION && tmod > t[FUNHEAD+3]/2 )
1445 tmod -= t[FUNHEAD+3];
1447 *((UWORD *)lnum) = -tmod;
1450 else if ( tmod > 0 ) {
1451 *((UWORD *)lnum) = tmod;
1457 else if ( t[1] > t[FUNHEAD+2] && t[FUNHEAD] > 0
1458 && t[FUNHEAD+t[FUNHEAD]] == -SNUMBER
1459 && t[FUNHEAD+t[FUNHEAD]+1] > 1
1460 && t[1] == FUNHEAD+2+t[FUNHEAD] ) {
1461 WORD *ttt = t+FUNHEAD, iii;
1463 if ( *ttt == ttt[ARGHEAD]+ARGHEAD &&
1464 ttt[ARGHEAD] == ABS(iii)+1 ) {
1466 WORD cmod = ttt[*ttt+1];
1468 if ( *t == MODFUNCTION ) {
1469 if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
1470 ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|NOINVERSES) )
1474 if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
1475 ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|POSNEG|NOINVERSES) )
1478 if ( *t == MOD2FUNCTION && ttt[ARGHEAD+1] > cmod/2 && iii > 0 ) {
1479 ttt[ARGHEAD+1] -= cmod;
1481 if ( ttt[ARGHEAD+1] < 0 ) {
1482 *((UWORD *)lnum) = -ttt[ARGHEAD+1];
1485 else if ( ttt[ARGHEAD+1] > 0 ) {
1486 *((UWORD *)lnum) = ttt[ARGHEAD+1];
1493 else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1494 *((UWORD *)lnum) = t[FUNHEAD+1];
1495 if ( *lnum == 0 )
goto NormZero;
1499 else if ( ( ( t[FUNHEAD] < 0 ) && ( t[FUNHEAD] == -SNUMBER )
1500 && ( t[1] >= ( FUNHEAD+6+ARGHEAD ) )
1501 && ( t[FUNHEAD+2] >= 4+ARGHEAD )
1502 && ( t[t[1]-1] == t[FUNHEAD+2+ARGHEAD]-1 ) ) ||
1503 ( ( t[FUNHEAD] > 0 )
1504 && ( t[FUNHEAD]-ARGHEAD-1 == ABS(t[FUNHEAD+t[FUNHEAD]-1]) )
1505 && ( t[FUNHEAD+t[FUNHEAD]]-ARGHEAD-1 == t[t[1]-1] ) ) ) {
1509 WORD *ttt = t + t[1], iii, iii1;
1510 UWORD coefbuf[2], *coef2, ncoef2;
1511 iii = (ttt[-1]-1)/2;
1513 if ( ttt[-1] != 1 ) {
1519 for ( iii1 = 0; iii1 < iii; iii1++ ) {
1520 if ( ttt[iii1] != 0 )
goto exitfromhere;
1531 nnum = -1; lnum[0] = -ttt[1]; lnum[1] = 1;
1534 nnum = 1; lnum[0] = ttt[1]; lnum[1] = 1;
1538 nnum = ABS(ttt[ttt[0]-1] - 1);
1539 for ( iii = 0; iii < nnum; iii++ ) {
1540 lnum[iii] = ttt[ARGHEAD+1+iii];
1543 if ( ttt[ttt[0]-1] < 0 ) nnum = -nnum;
1548 ncoef2 = 3; *coef2 = (UWORD)(ttt[1]);
1552 coef2 = (UWORD *)(ttt+ARGHEAD+1);
1553 ncoef2 = (ttt[ttt[0]-1]-1)/2;
1555 if ( TakeModulus((UWORD *)lnum,&nnum,(UWORD *)coef2,ncoef2,
1556 UNPACK|NOINVERSES|FROMFUNCTION) ) {
1559 if ( *t == MOD2FUNCTION && nnum > 0 ) {
1560 UWORD *coef3 = NumberMalloc(
"Mod2Function"), two = 2;
1562 if ( MulLong((UWORD *)lnum,nnum,&two,1,coef3,&ncoef3) )
1564 if ( BigLong(coef3,ncoef3,(UWORD *)coef2,ncoef2) > 0 ) {
1566 AddLong((UWORD *)lnum,nnum,(UWORD *)coef2,ncoef2
1567 ,(UWORD *)lnum,&nnum);
1570 NumberFree(coef3,
"Mod2Function");
1575 ncoef = REDLENG(ncoef);
1576 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
1578 ncoef = INCLENG(ncoef);
1580 else pcom[ncom++] = t;
1584 WORD argcount = 0, *tc, *ts, xc, xs, *tcc;
1585 UWORD *Num1, *Num2, *Num3, *Num4;
1586 WORD size1, size2, size3, size4, space;
1587 tc = t+FUNHEAD; ts = t + t[1];
1588 while ( argcount < 3 && tc < ts ) { NEXTARG(tc); argcount++; }
1589 if ( argcount != 2 )
goto defaultcase;
1590 if ( t[FUNHEAD] == -SNUMBER ) {
1591 if ( t[FUNHEAD+1] <= 1 )
goto defaultcase;
1592 if ( t[FUNHEAD+2] == -SNUMBER ) {
1593 if ( t[FUNHEAD+3] <= 1 )
goto defaultcase;
1594 Num2 = NumberMalloc(
"modinverses");
1595 *Num2 = t[FUNHEAD+3]; size2 = 1;
1598 if ( ts[-1] < 0 )
goto defaultcase;
1599 if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 )
goto defaultcase;
1602 if ( *tcc != 1 )
goto defaultcase;
1603 for ( i = 1; i < xs; i++ ) {
1604 if ( tcc[i] != 0 )
goto defaultcase;
1606 Num2 = NumberMalloc(
"modinverses");
1608 for ( i = 0; i < xs; i++ ) Num2[i] = t[FUNHEAD+ARGHEAD+3+i];
1610 Num1 = NumberMalloc(
"modinverses");
1611 *Num1 = t[FUNHEAD+1]; size1 = 1;
1614 tc = t + FUNHEAD + t[FUNHEAD];
1615 if ( tc[-1] < 0 )
goto defaultcase;
1616 if ( tc[-1] != t[FUNHEAD]-ARGHEAD-1 )
goto defaultcase;
1619 if ( *tcc != 1 )
goto defaultcase;
1620 for ( i = 1; i < xc; i++ ) {
1621 if ( tcc[i] != 0 )
goto defaultcase;
1623 if ( *tc == -SNUMBER ) {
1624 if ( tc[1] <= 1 )
goto defaultcase;
1625 Num2 = NumberMalloc(
"modinverses");
1626 *Num2 = tc[1]; size2 = 1;
1629 if ( ts[-1] < 0 )
goto defaultcase;
1630 if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 )
goto defaultcase;
1633 if ( *tcc != 1 )
goto defaultcase;
1634 for ( i = 1; i < xs; i++ ) {
1635 if ( tcc[i] != 0 )
goto defaultcase;
1637 Num2 = NumberMalloc(
"modinverses");
1639 for ( i = 0; i < xs; i++ ) Num2[i] = tc[ARGHEAD+1+i];
1641 Num1 = NumberMalloc(
"modinverses");
1643 for ( i = 0; i < xc; i++ ) Num1[i] = t[FUNHEAD+ARGHEAD+1+i];
1645 Num3 = NumberMalloc(
"modinverses");
1646 Num4 = NumberMalloc(
"modinverses");
1647 GetLongModInverses(BHEAD Num1,size1,Num2,size2
1648 ,Num3,&size3,Num4,&size4);
1657 if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) space += 2;
1658 else space += ARGHEAD + 2*ABS(size3) + 2;
1659 if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) space += 2;
1660 else space += ARGHEAD + 2*ABS(size4) + 2;
1661 tt = term + *term; u = tt + space;
1662 while ( tt >= ts ) *--u = *--tt;
1663 m += space; r += space;
1666 if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) {
1667 *ts++ = -SNUMBER; *ts = (WORD)(*Num3);
1668 if ( size3 < 0 ) *ts = -*ts;
1672 *ts++ = 2*ABS(size3)+ARGHEAD+2;
1673 *ts++ = 0; FILLARG(ts)
1674 *ts++ = 2*ABS(size3)+1;
1675 for ( i = 0; i < ABS(size3); i++ ) *ts++ = Num3[i];
1677 for ( i = 1; i < ABS(size3); i++ ) *ts++ = 0;
1678 if ( size3 < 0 ) *ts++ = 2*size3-1;
1679 else *ts++ = 2*size3+1;
1681 if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) {
1682 *ts++ = -SNUMBER; *ts = *Num4;
1683 if ( size4 < 0 ) *ts = -*ts;
1687 *ts++ = 2*ABS(size4)+ARGHEAD+2;
1688 *ts++ = 0; FILLARG(ts)
1689 *ts++ = 2*ABS(size4)+2;
1690 for ( i = 0; i < ABS(size4); i++ ) *ts++ = Num4[i];
1692 for ( i = 1; i < ABS(size4); i++ ) *ts++ = 0;
1693 if ( size4 < 0 ) *ts++ = 2*size4-1;
1694 else *ts++ = 2*size4+1;
1696 NumberFree(Num4,
"modinverses");
1697 NumberFree(Num3,
"modinverses");
1698 NumberFree(Num1,
"modinverses");
1699 NumberFree(Num2,
"modinverses");
1706#ifdef NEWGCDFUNCTION
1712 WORD *num1, *num2, size1, size2, stor1, stor2, *ttt, ti;
1713 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1714 && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+1] != 0
1715 && t[FUNHEAD+3] != 0 ) {
1716 stor1 = t[FUNHEAD+1];
1717 stor2 = t[FUNHEAD+3];
1718 if ( stor1 < 0 ) stor1 = -stor1;
1719 if ( stor2 < 0 ) stor2 = -stor2;
1720 num1 = &stor1; num2 = &stor2;
1724 else if ( t[1] > FUNHEAD+4 ) {
1725 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] != 0
1726 && t[FUNHEAD+2] == t[1]-FUNHEAD-2 &&
1727 ABS(t[t[1]-1]) == t[FUNHEAD+2]-1-ARGHEAD ) {
1729 size2 = ABS(num2[-1]);
1732 size2 = (size2-1)/2;
1734 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1735 if ( ti == 1 && ttt[-1] == 1 ) {
1736 stor1 = t[FUNHEAD+1];
1737 if ( stor1 < 0 ) stor1 = -stor1;
1742 else pcom[ncom++] = t;
1744 else if ( t[FUNHEAD] > 0 &&
1745 t[FUNHEAD]-1-ARGHEAD == ABS(t[t[FUNHEAD]+FUNHEAD-1]) ) {
1746 num1 = t + FUNHEAD + t[FUNHEAD];
1747 size1 = ABS(num1[-1]);
1750 size1 = (size1-1)/2;
1752 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1753 if ( ti == 1 && ttt[-1] == 1 ) {
1754 if ( t[1]-FUNHEAD == t[FUNHEAD]+2 && t[t[1]-2] == -SNUMBER
1755 && t[t[1]-1] != 0 ) {
1757 if ( stor2 < 0 ) stor2 = -stor2;
1762 else if ( t[1]-FUNHEAD == t[FUNHEAD]+t[FUNHEAD+t[FUNHEAD]]
1763 && ABS(t[t[1]-1]) == t[FUNHEAD+t[FUNHEAD]] - ARGHEAD-1 ) {
1765 size2 = ABS(num2[-1]);
1768 size2 = (size2-1)/2;
1770 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1771 if ( ti == 1 && ttt[-1] == 1 ) {
1772gcdcalc:
if ( GcdLong(BHEAD (UWORD *)num1,size1,(UWORD *)num2,size2
1773 ,(UWORD *)lnum,&nnum) )
goto FromNorm;
1776 else pcom[ncom++] = t;
1778 else pcom[ncom++] = t;
1780 else pcom[ncom++] = t;
1782 else pcom[ncom++] = t;
1784 else pcom[ncom++] = t;
1788 WORD *gcd = AT.WorkPointer;
1789 if ( ( gcd = EvaluateGcd(BHEAD t) ) == 0 )
goto FromNorm;
1790 if ( *gcd == 4 && gcd[1] == 1 && gcd[2] == 1 && gcd[4] == 0 ) {
1791 AT.WorkPointer = gcd;
1793 else if ( gcd[*gcd] == 0 ) {
1794 WORD *t1, iii, change, *num, *den, numsize, densize;
1795 if ( gcd[*gcd-1] < *gcd-1 ) {
1797 for ( iii = 2; iii < t1[1]; iii += 2 ) {
1798 change = ExtraSymbol(t1[iii],t1[iii+1],nsym,ppsym,&ncoef);
1800 ppsym += change * 2;
1804 iii = t1[-1]; num = t1-iii; numsize = (iii-1)/2;
1805 den = num + numsize; densize = numsize;
1806 while ( numsize > 1 && num[numsize-1] == 0 ) numsize--;
1807 while ( densize > 1 && den[densize-1] == 0 ) densize--;
1808 if ( numsize > 1 || num[0] != 1 ) {
1809 ncoef = REDLENG(ncoef);
1810 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)num,numsize) )
goto FromNorm;
1811 ncoef = INCLENG(ncoef);
1813 if ( densize > 1 || den[0] != 1 ) {
1814 ncoef = REDLENG(ncoef);
1815 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)den,densize) )
goto FromNorm;
1816 ncoef = INCLENG(ncoef);
1818 AT.WorkPointer = gcd;
1832 LONG size = AT.WorkPointer - gcd;
1834 ss =
AddRHS(AT.ebufnum,1);
1838 C->
rhs[C->numrhs+1] = ss;
1841 t[0] = SUBEXPRESSION;
1848 while ( r < tt ) *t++ = *r++;
1857 MesPrint(
" Unexpected call to EvaluateGCD");
1863 if ( t[1] == FUNHEAD )
break;
1865 WORD *ttt = t + FUNHEAD;
1866 WORD *tttstop = t + t[1];
1868 while ( ttt < tttstop ) {
1870 if ( ttt[ARGHEAD]-1 > ABS(ttt[*ttt-1]) )
goto nospec;
1874 if ( *ttt != -SNUMBER )
goto nospec;
1885 for ( iii = 0; iii < ttt[ARGHEAD]; iii++ )
1886 n_llnum[iii] = ttt[ARGHEAD+iii];
1891 if ( ttt[1] == 0 ) {
1892 n_llnum[0] = n_llnum[1] = n_llnum[2] = n_llnum[3] = 0;
1896 if ( ttt[1] > 0 ) { n_llnum[1] = ttt[1]; n_llnum[3] = 3; }
1897 else { n_llnum[1] = -ttt[1]; n_llnum[3] = -3; }
1905 while ( ttt < tttstop ) {
1907 if ( n_llnum[0] == 0 ) {
1908 if ( ( *t == MINFUNCTION && ttt[*ttt-1] < 0 )
1909 || ( *t == MAXFUNCTION && ttt[*ttt-1] > 0 ) )
1915 if ( ( iii > 0 && *t == MINFUNCTION )
1916 || ( iii < 0 && *t == MAXFUNCTION ) ) {
1917 for ( iii = 0; iii < ttt[0]; iii++ )
1918 n_llnum[iii] = ttt[iii];
1924 if ( n_llnum[0] == 0 ) {
1925 if ( ( *t == MINFUNCTION && ttt[1] < 0 )
1926 || ( *t == MAXFUNCTION && ttt[1] > 0 ) )
1929 else if ( ttt[1] == 0 ) {
1930 if ( ( *t == MINFUNCTION && n_llnum[*n_llnum-1] > 0 )
1931 || ( *t == MAXFUNCTION && n_llnum[*n_llnum-1] < 0 ) ) {
1936 tterm[0] = 4; tterm[2] = 1;
1937 if ( ttt[1] < 0 ) { tterm[1] = -ttt[1]; tterm[3] = -3; }
1938 else { tterm[1] = ttt[1]; tterm[3] = 3; }
1940 if ( ( iii > 0 && *t == MINFUNCTION )
1941 || ( iii < 0 && *t == MAXFUNCTION ) ) {
1942 for ( iii = 0; iii < 4; iii++ )
1943 n_llnum[iii] = tterm[iii];
1949 if ( n_llnum[0] == 0 )
goto NormZero;
1950 ncoef = REDLENG(ncoef);
1951 nnum = REDLENG(n_llnum[*n_llnum-1]);
1952 if ( MulRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)lnum,nnum,
1953 (UWORD *)n_coef,&ncoef) )
goto FromNorm;
1954 ncoef = INCLENG(ncoef);
1957 case INVERSEFACTORIAL:
1958 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 ) {
1959 if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
1961 ncoef = REDLENG(ncoef);
1962 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
1963 ncoef = INCLENG(ncoef);
1966nospec: pcom[ncom++] = t;
1970 if ( ( t[FUNHEAD] == -SYMBOL )
1971 && ( t[FUNHEAD+1] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
1972 *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].maxpower;
1976 else { pcom[ncom++] = t; }
1979 if ( ( t[FUNHEAD] == -SYMBOL )
1980 && ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
1981 *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].minpower;
1985 else { pcom[ncom++] = t; }
1988 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER
1989 && t[FUNHEAD+1] > 0 ) {
1990 UWORD xp = (UWORD)(
NextPrime(BHEAD t[FUNHEAD+1]));
1991 ncoef = REDLENG(ncoef);
1992 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,&xp,1) )
goto FromNorm;
1993 ncoef = INCLENG(ncoef);
1995 else goto defaultcase;
2001 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER
2002 && t[FUNHEAD+1] > 0 ) {
2003 WORD val = Moebius(BHEAD t[FUNHEAD+1]);
2004 if ( val == 0 )
goto NormZero;
2005 if ( val < 0 ) ncoef = -ncoef;
2012 ncoef = REDLENG(ncoef);
2013 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(t+3),t[2]) )
goto FromNorm;
2014 ncoef = INCLENG(ncoef);
2019 if ( t[3] & 1 ) ncoef = -ncoef;
2021 else if ( t[2] == 0 ) {
2022 if ( t[3] < 0 )
goto NormInf;
2027 if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) )
goto FromNorm;
2028 ncoef = REDLENG(ncoef);
2030 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
2033 else if ( t[3] > 0 ) {
2034 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
2037 ncoef = INCLENG(ncoef);
2044 if ( t[1] == FUNHEAD ) {
2045 MLOCK(ErrorMessageLock);
2046 MesPrint(
"Gamma matrix without spin line encountered.");
2047 MUNLOCK(ErrorMessageLock);
2055 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) {
2057 t[2] |= DIRTYSYMFLAG;
2060ScanCont:
while ( t < r ) {
2061 if ( *t >= AM.OffsetIndex &&
2062 ( *t >= AM.DumInd || ( *t < AM.WilInd &&
2063 indices[*t-AM.OffsetIndex].dimension ) ) )
2073 if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) )
2075 if ( *rr == -SNUMBER && rr[1] == 1 )
break;
2076 if ( *rr <= -FUNCTION ) k = *rr;
2078 if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) ) {
2079 if ( k == 0 )
goto NormZZ;
2082 if ( *rr == -SNUMBER && rr[1] > 0 && rr[1] < MAXPOWER && k < 0 ) {
2084 if ( functions[k-FUNCTION].commute ) {
2085 for ( i = 0; i < rr[1]; i++ ) pnco[nnco++] = rr-1;
2088 for ( i = 0; i < rr[1]; i++ ) pcom[ncom++] = rr-1;
2092 if ( k == 0 )
goto NormZero;
2093 if ( t[FUNHEAD] == -SYMBOL && *rr == -SNUMBER && t[1] == FUNHEAD+4 ) {
2094 if ( rr[1] < MAXPOWER ) {
2095 t[FUNHEAD+2] = t[FUNHEAD+1]; t += FUNHEAD+2;
2105 t[2] &= ~DIRTYSYMFLAG;
2111 t[2] &= ~DIRTYSYMFLAG;
2118 if ( *t == 0 || *t == AM.vectorzero )
goto NormZero;
2119 if ( *t > 0 && *t < AM.OffsetIndex ) {
2122 ncoef = REDLENG(ncoef);
2123 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)lnum,nnum) )
2125 ncoef = INCLENG(ncoef);
2127 else if ( *t == NOINDEX ) t++;
2128 else pind[nind++] = *t++;
2131 case SUBEXPRESSION :
2132 if ( t[3] == 0 )
break;
2144 if ( t[2] == 0 )
goto defaultcase;
2145 if ( t[FUNHEAD] != -SNUMBER || t[FUNHEAD+1] < 0 )
goto defaultcase;
2146 if ( t[FUNHEAD+2] == -SNUMBER ) {
2147 if ( t[FUNHEAD+1] == 0 && t[FUNHEAD+3] == 0 )
goto NormZZ;
2148 if ( t[FUNHEAD+1] == 0 )
break;
2149 if ( t[FUNHEAD+3] < 0 ) {
2150 AT.WorkPointer[0] = -t[FUNHEAD+3];
2154 AT.WorkPointer[0] = t[FUNHEAD+3];
2157 AT.WorkPointer[1] = 1;
2159 else if ( t[FUNHEAD+2] == t[1]-FUNHEAD-2
2160 && t[FUNHEAD+2] == t[FUNHEAD+2+ARGHEAD]+ARGHEAD
2161 && ABS(t[t[1]-1]) == t[FUNHEAD+2+ARGHEAD] - 1 ) {
2163 if ( t[FUNHEAD+1] == 0 )
break;
2164 i = t[t[1]-1]; r1 = t + FUNHEAD+ARGHEAD+3;
2167 r2 = AT.WorkPointer;
2168 while ( --i >= 0 ) *r2++ = *r1++;
2170 else goto defaultcase;
2171 if ( TakeRatRoot((UWORD *)AT.WorkPointer,&nc,t[FUNHEAD+1]) ) {
2175 ncoef = REDLENG(ncoef);
2176 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,nc) )
2178 if ( nc < 0 ) nc = -nc;
2179 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(AT.WorkPointer+nc),nc) )
2181 ncoef = INCLENG(ncoef);
2184 case RANDOMFUNCTION :
2186 WORD nnc, nc, nca, nr;
2197 if ( t[1] == FUNHEAD )
goto defaultcase;
2198 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER &&
2199 t[FUNHEAD+1] > 0 ) {
2200 if ( t[FUNHEAD+1] == 1 )
break;
2202 ((UWORD *)AT.WorkPointer)[0] = wranf(BHEAD0);
2203 ((UWORD *)AT.WorkPointer)[1] = wranf(BHEAD0);
2205 if ( ((UWORD *)AT.WorkPointer)[1] == 0 ) {
2207 if ( ((UWORD *)AT.WorkPointer)[0] == 0 ) {
2211 xx = (UWORD)(t[FUNHEAD+1]);
2213 DivLong((UWORD *)AT.WorkPointer,nr
2215 ,((UWORD *)AT.WorkPointer)+4,&nnc
2216 ,((UWORD *)AT.WorkPointer)+2,&nc);
2217 ((UWORD *)AT.WorkPointer)[4] = 0;
2218 ((UWORD *)AT.WorkPointer)[5] = 0;
2219 ((UWORD *)AT.WorkPointer)[6] = 1;
2220 DivLong((UWORD *)AT.WorkPointer+4,3
2222 ,((UWORD *)AT.WorkPointer)+9,&nnc
2223 ,((UWORD *)AT.WorkPointer)+7,&nca);
2224 AddLong((UWORD *)AT.WorkPointer+4,3
2225 ,((UWORD *)AT.WorkPointer)+7,-nca
2226 ,((UWORD *)AT.WorkPointer)+9,&nnc);
2227 if ( BigLong((UWORD *)AT.WorkPointer,nr
2228 ,((UWORD *)AT.WorkPointer)+9,nnc) >= 0 )
goto redoshort;
2232 AT.WorkPointer[2] = (WORD)xx;
2235 ncoef = REDLENG(ncoef);
2236 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+2,nc) )
2238 ncoef = INCLENG(ncoef);
2240 else if ( t[FUNHEAD] > 0 && t[1] == t[FUNHEAD]+FUNHEAD
2241 && ABS(t[t[1]-1]) == t[FUNHEAD]-1-ARGHEAD && t[t[1]-1] > 0 ) {
2242 WORD nna, nnb, nni, nnb2, nnb2a;
2247 nnt = (UWORD *)(t+t[1]-1-nnb);
2248 if ( *nnt != 1 )
goto defaultcase;
2249 for ( nni = 1; nni < nnb; nni++ ) {
2250 if ( nnt[nni] != 0 )
goto defaultcase;
2252 nnt = (UWORD *)(t + FUNHEAD + ARGHEAD + 1);
2254 for ( nni = 0; nni < nnb2; nni++ ) {
2255 ((UWORD *)AT.WorkPointer)[nni] = wranf(BHEAD0);
2258 while ( nnb2a > 0 && ((UWORD *)AT.WorkPointer)[nnb2a-1] == 0 ) nnb2a--;
2260 DivLong((UWORD *)AT.WorkPointer,nnb2a
2262 ,((UWORD *)AT.WorkPointer)+2*nnb2,&nnc
2263 ,((UWORD *)AT.WorkPointer)+nnb2,&nc);
2264 for ( nni = 0; nni < nnb2; nni++ ) {
2265 ((UWORD *)AT.WorkPointer)[nni+2*nnb2] = 0;
2267 ((UWORD *)AT.WorkPointer)[3*nnb2] = 1;
2268 DivLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
2270 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc
2271 ,((UWORD *)AT.WorkPointer)+3*nnb2+1,&nca);
2272 AddLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
2273 ,((UWORD *)AT.WorkPointer)+3*nnb2+1,-nca
2274 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc);
2275 if ( BigLong((UWORD *)AT.WorkPointer,nnb2a
2276 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,nnc) >= 0 )
goto redoshort;
2280 for ( nni = 0; nni < nnb; nni++ ) {
2281 ((UWORD *)AT.WorkPointer)[nnb2+nni] = nnt[nni];
2285 ncoef = REDLENG(ncoef);
2286 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+nnb2,nc) )
2288 ncoef = INCLENG(ncoef);
2290 else goto defaultcase;
2294 if ( *t == RANPERM && t[1] > FUNHEAD && t[FUNHEAD] <= -FUNCTION ) {
2296 WORD *mm, *ww, *ow = AT.WorkPointer;
2297 WORD *Array, *targ, *argstop, narg = 0, itot;
2301 while ( targ < argstop ) {
2302 narg++; NEXTARG(targ);
2304 WantAddPointers(narg);
2305 pwork = AT.pWorkSpace + AT.pWorkPointer;
2306 targ = t+FUNHEAD+1; narg = 0;
2307 while ( targ < argstop ) {
2308 pwork[narg++] = targ;
2315 ow = AT.WorkPointer;
2316 Array = AT.WorkPointer;
2317 AT.WorkPointer += narg;
2318 for ( i = 0; i < narg; i++ ) Array[i] = i;
2319 for ( i = 2; i <= narg; i++ ) {
2320 itot = (WORD)(iranf(BHEAD i));
2321 for ( j = 0; j < itot; j++ ) CYCLE1(WORD,Array,i)
2323 mm = AT.WorkPointer;
2324 *mm++ = -t[FUNHEAD];
2326 for ( ie = 2; ie < FUNHEAD; ie++ ) *mm++ = t[ie];
2327 for ( i = 0; i < narg; i++ ) {
2328 ww = pwork[Array[i]];
2331 mm = AT.WorkPointer; t++; ww = t;
2332 i = mm[1]; NCOPY(ww,mm,i)
2333 AT.WorkPointer = ow;
2339 if ( ( t[2] & DIRTYFLAG ) != 0 && t[FUNHEAD] <= -FUNCTION
2340 && t[FUNHEAD+1] == -SNUMBER && t[FUNHEAD+2] > 0 ) {
2341 WORD *rr = t+t[1], *mm = t+FUNHEAD+3, *tt, *tt1, *tt2, num = 0;
2345 while ( mm < rr ) { num++; NEXTARG(mm); }
2346 if ( num < t[FUNHEAD+2] ) { pnco[nnco++] = t;
break; }
2348 *t = -t[FUNHEAD]; mm = t+FUNHEAD+3;
2351 while ( --i > 0 ) { NEXTARG(mm); }
2355 tt = TermMalloc(
"Select_");
2359 for ( i = 0; i < *mm; i++ ) *tt1++ = mm[i];
2362 else if ( *mm <= -FUNCTION ) { *tt1++ = *mm; }
2364 else { *tt1++ = mm[0]; *tt1++ = mm[1]; }
2368 while ( tt2 < mm ) *tt1++ = *tt2++;
2371 i = tt1-tt; tt1 = tt; tt2 = t+FUNHEAD;
2375 TermFree(tt,
"Select_");
2378 while ( argTail < rr ) *tt2++ = *argTail++;
2383 while ( argTail < rr ) *tt2++ = *argTail++;
2385 if ( functions[*t-FUNCTION].spec == TENSORFUNCTION ) {
2389 WORD *dst = t + FUNHEAD;
2390 WORD *src = dst + 1;
2392 while ( src < t + t[1] ) {
2394 dst++; src++; src++;
2399 while ( src < term + *term ) {
2406 else pnco[nnco++] = t;
2414 if ( withfloat == 0 ) {
2415 if ( TestFloat(t) == 0 )
goto defaultcase;
2420 if ( TestFloat(t) == 0 )
goto defaultcase;
2421 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
2423 UnpackFloat(aux5,t);
2424 mpf_mul(aux4,aux4,aux5);
2437 if ( t[1] <= FUNHEAD )
break;
2442 if ( *to == ARGHEAD )
goto NormZero;
2446 if ( to[ARGHEAD] != j+1 )
goto NoInteg;
2447 if ( rr >= r ) k = -1;
2448 else if ( *rr == ARGHEAD ) { k = 0; rr += ARGHEAD; }
2449 else if ( *rr == -SNUMBER ) { k = rr[1]; rr += 2; }
2451 if ( rr != r )
goto NoInteg;
2452 if ( k > 1 || k < -1 )
goto NoInteg;
2455 i = ( i < 0 ) ? -j: j;
2456 UnPack((UWORD *)to,i,&den,&num);
2464 if ( AN.NoScrat2 == 0 ) {
2465 AN.NoScrat2 = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"Normalize");
2467 if ( DivLong((UWORD *)to,num,(UWORD *)(to+j),den
2468 ,(UWORD *)AT.WorkPointer,&num,AN.NoScrat2,&den) )
goto FromNorm;
2469 if ( k < 0 && den < 0 ) {
2472 if ( AddLong((UWORD *)AT.WorkPointer,num
2473 ,AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
2476 else if ( k > 0 && den > 0 ) {
2479 if ( AddLong((UWORD *)AT.WorkPointer,num,
2480 AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
2485 else if ( *to == -SNUMBER ) {
2486 if ( to[1] < 0 ) { *AT.WorkPointer = -to[1]; num = -1; }
2487 else if ( to[1] == 0 )
goto NormZero;
2488 else { *AT.WorkPointer = to[1]; num = 1; }
2491 if ( num == 0 )
goto NormZero;
2492 ncoef = REDLENG(ncoef);
2493 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,num) )
2495 ncoef = INCLENG(ncoef);
2504 if ( *t < FUNCTION ) {
2505 MLOCK(ErrorMessageLock);
2506 MesPrint(
"Illegal code in Norm");
2510 AO.OutFill = AO.OutputLine = OutBuf;
2515 while ( --i >= 0 ) {
2516 TalToLine((UWORD)(*t++));
2517 TokenToLine((UBYTE *)
" ");
2523 MUNLOCK(ErrorMessageLock);
2526 if ( *t == REPLACEMENT ) {
2527 if ( AR.Eside != LHSIDE ) ReplaceVeto--;
2535 if ( *t == DUMMYFUN || *t == DUMMYTEN ) {}
2537 if ( *t < (FUNCTION + WILDOFFSET) ) {
2538 if ( ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2539 || ( functions[*t-FUNCTION].minnumargs > 0 ) )
2540 && ( ( t[2] & DIRTYFLAG ) != 0 ) ) {
2544 WORD *ta = t + FUNHEAD, *tb = t + t[1];
2546 while ( ta < tb ) { numarg++; NEXTARG(ta) }
2547 if ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2548 && ( numarg >= functions[*t-FUNCTION].maxnumargs ) )
2550 if ( ( functions[*t-FUNCTION].minnumargs > 0 )
2551 && ( numarg < functions[*t-FUNCTION].minnumargs ) )
2555 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION].tabl == 0 ) ) {
2557 t[2] |= DIRTYSYMFLAG;
2559 if ( functions[*t-FUNCTION].commute ) { pnco[nnco++] = t; }
2560 else { pcom[ncom++] = t; }
2563 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION-WILDOFFSET].tabl == 0 ) ) {
2565 t[2] |= DIRTYSYMFLAG;
2567 if ( functions[*t-FUNCTION-WILDOFFSET].commute ) {
2570 else { pcom[ncom++] = t; }
2576 if ( ( *t < (FUNCTION + WILDOFFSET)
2577 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) || (
2578 *t >= (FUNCTION + WILDOFFSET)
2579 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
2580 if ( *t >= GAMMA && *t <= GAMMASEVEN ) t++;
2583 if ( *t == AM.vectorzero )
goto NormZero;
2584 if ( *t >= AM.OffsetIndex && ( *t >= AM.DumInd
2585 || ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2588 else if ( *t == FUNNYWILD ) { t++; }
2603 else if ( *t <= -FUNCTION ) t++;
2604 else if ( *t == -INDEX ) {
2605 if ( t[1] >= AM.OffsetIndex &&
2606 ( t[1] >= AM.DumInd || ( t[1] < AM.WilInd
2607 && indices[t[1]-AM.OffsetIndex].dimension ) ) )
2611 else if ( *t == -SYMBOL ) {
2612 if ( t[1] >= MAXPOWER && t[1] < 2*MAXPOWER ) {
2616 else if ( t[1] < -MAXPOWER && t[1] > -2*MAXPOWER ) {
2632 r = t = ANsr; m = ANsm;
2633 ANsc = ANsm = ANsr = 0;
2646 for ( k = 0, i = 0; i < nden; i++ ) {
2648 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2649 r = t + t[1]; m = t + FUNHEAD;
2651 for ( j = i+1; j < nden; j++ ) pden[j-1] = pden[j];
2653 for ( j = 0; j < nnco; j++ )
if ( pnco[j] == t )
break;
2654 for ( j++; j < nnco; j++ ) pnco[j-1] = pnco[j];
2660 if ( m >= r )
continue;
2665 k = 1; to = termout; from = term;
2667 while ( from < t ) *to++ = *from++;
2671 *to++ = DENOMINATOR;
2672 for ( j = 1; j < FUNHEAD; j++ ) *to++ = 0;
2673 if ( *m < -FUNCTION ) *to++ = *m++;
2674 else if ( *m < 0 ) { *to++ = *m++; *to++ = *m++; }
2676 j = *m;
while ( --j >= 0 ) *to++ = *m++;
2678 stop[1] = WORDDIF(to,stop);
2681 if ( i == nden - 1 ) {
2682 stop = term + *term;
2683 while ( from < stop ) *to++ = *from++;
2684 i = *termout = WORDDIF(to,termout);
2685 to = term; from = termout;
2686 while ( --i >= 0 ) *to++ = *from++;
2691 for ( i = 0; i < nden; i++ ) {
2693 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2695 if ( t[FUNHEAD] == -SYMBOL ) {
2698 change = ExtraSymbol(*t,-1,nsym,ppsym,&ncoef);
2700 ppsym += change * 2;
2703 else if ( t[FUNHEAD] == -SNUMBER ) {
2705 if ( *t == 0 )
goto NormInf;
2706 if ( *t < 0 ) { *AT.WorkPointer = -*t; j = -1; }
2707 else { *AT.WorkPointer = *t; j = 1; }
2708 ncoef = REDLENG(ncoef);
2709 if ( Divvy(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)AT.WorkPointer,j) )
2711 ncoef = INCLENG(ncoef);
2714 else if ( t[FUNHEAD] == ARGHEAD )
goto NormInf;
2715 else if ( t[FUNHEAD] > 0 && t[FUNHEAD+ARGHEAD] ==
2716 t[FUNHEAD]-ARGHEAD ) {
2719 t += FUNHEAD + ARGHEAD + 1;
2721 m = r - ABS(*r) + 1;
2722 if ( j != 3 || ( ( *m != 1 ) || ( m[1] != 1 ) ) ) {
2723 ncoef = REDLENG(ncoef);
2724 if ( DivRat(BHEAD (UWORD *)n_coef,ncoef,(UWORD *)m,REDLENG(j),(UWORD *)n_coef,&ncoef) )
goto FromNorm;
2725 ncoef = INCLENG(ncoef);
2727 t[-FUNHEAD-ARGHEAD] -= j;
2735 if ( *t == SYMBOL || *t == DOTPRODUCT ) {
2738 pden[i][FUNHEAD] -= k;
2739 pden[i][FUNHEAD+ARGHEAD] -= k;
2744 if ( *t == SYMBOL ) {
2748 change = ExtraSymbol(*t,-t[1],nsym,ppsym,&ncoef);
2750 ppsym += change * 2;
2763 while ( to < stop ) *to++ = *from++;
2767 else if ( *t == FLOATFUN && TestFloat(t) ) {
2770 pden[i][FUNHEAD] -= k;
2771 pden[i][FUNHEAD+ARGHEAD] -= k;
2772 UnpackFloat(aux5,t);
2773 if ( withfloat == 0 ) {
2774 mpf_ui_div(aux4,1,aux5);
2778 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
2779 mpf_div(aux4,aux4,aux5);
2783 while ( r < m ) *to++ = *r++;
2784 *to++ = 1; *to++ = 1; *to++ = 3;
2785 if ( ncoef < 0 ) t[-1] = -t[-1];
2793 if ( pden[i][1] == 4+FUNHEAD+ARGHEAD ) {
2795 for ( j = 0; j < nnco; j++ ) {
2796 if ( pden[i] == pnco[j] ) {
2798 while ( j < nnco ) {
2799 pnco[j] = pnco[j+1];
2805 pden[i--] = pden[--nden];
2816 for ( i = 0; i < ndel; i += 2 ) {
2817 if ( t[0] == t[1] ) {
2818 if ( t[0] == EMPTYINDEX ) {}
2819 else if ( *t < AM.OffsetIndex ) {
2820 k = AC.FixIndices[*t];
2821 if ( k < 0 ) { j = -1; k = -k; }
2822 else if ( k > 0 ) j = 1;
2826 else if ( *t >= AM.DumInd ) {
2828 if ( k )
goto docontract;
2830 else if ( *t >= AM.WilInd ) {
2831 k = indices[*t-AM.OffsetIndex-WILDOFFSET].dimension;
2832 if ( k )
goto docontract;
2834 else if ( ( k = indices[*t-AM.OffsetIndex].dimension ) != 0 ) {
2838WithFix: shortnum = k;
2839 ncoef = REDLENG(ncoef);
2840 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),j) )
2842 ncoef = INCLENG(ncoef);
2846 change = ExtraSymbol((WORD)(-k),(WORD)1,nsym,ppsym,&ncoef);
2848 ppsym += change * 2;
2850 t[1] = pdel[ndel-1];
2851 t[0] = pdel[ndel-2];
2858 if ( *t < AM.OffsetIndex && t[1] < AM.OffsetIndex )
goto NormZero;
2859 j = *t - AM.OffsetIndex;
2860 if ( j >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
2861 || ( *t < AM.WilInd && indices[j].dimension ) ) ) {
2862 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2865 *m++ = pdel[ndel-2];
2869 else if ( *t == m[1] ) {
2871 *m++ = pdel[ndel-2];
2877 j = t[1]-AM.OffsetIndex;
2878 if ( j >= 0 && ( ( t[1] >= AM.DumInd && AC.lDefDim )
2879 || ( t[1] < AM.WilInd && indices[j].dimension ) ) ) {
2880 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2883 *m++ = pdel[ndel-2];
2887 else if ( t[1] == m[1] ) {
2889 *m++ = pdel[ndel-2];
2901 for ( i = 0; i < ndel; i++ ) {
2902 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2903 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2905 for ( j = 1; j < nvec; j += 2 ) {
2909 *t-- = pdel[--ndel];
2914 t[1] = pdel[--ndel];
2917 *t-- = pdel[--ndel];
2926 if ( ndel > 0 && ncon ) {
2928 for ( i = 0; i < ndel; i++ ) {
2929 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2930 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2931 for ( j = 0; j < ncon; j++ ) {
2932 if ( *pcon[j] == *t ) {
2935 *t-- = pdel[--ndel];
2940 t[1] = pdel[--ndel];
2943 *t-- = pdel[--ndel];
2946 for ( j = 0; j < nnco; j++ ) {
2948 if ( r > m && r < m+m[1] ) {
2949 m[2] |= DIRTYSYMFLAG;
2953 for ( j = 0; j < ncom; j++ ) {
2955 if ( r > m && r < m+m[1] ) {
2956 m[2] |= DIRTYSYMFLAG;
2960 for ( j = 0; j < neps; j++ ) {
2962 if ( r > m && r < m+m[1] ) {
2963 m[2] |= DIRTYSYMFLAG;
2978 for ( i = 3; i < nvec; i += 2 ) {
2979 k = *t - AM.OffsetIndex;
2980 if ( k >= 0 && ( ( *t > AM.DumInd && AC.lDefDim )
2981 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
2983 for ( j = i; j < nvec; j += 2 ) {
2989 *r-- = pvec[--nvec];
2991 *t-- = pvec[--nvec];
2992 *t-- = pvec[--nvec];
3001 if ( nvec > 0 && ncon ) {
3003 for ( i = 1; i < nvec; i += 2 ) {
3004 k = *t - AM.OffsetIndex;
3005 if ( k >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
3006 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
3007 for ( j = 0; j < ncon; j++ ) {
3008 if ( *pcon[j] == *t ) {
3010 *t-- = pvec[--nvec];
3011 *t-- = pvec[--nvec];
3013 pcon[j] = pcon[--ncon];
3015 for ( j = 0; j < nnco; j++ ) {
3017 if ( r > m && r < m+m[1] ) {
3018 m[2] |= DIRTYSYMFLAG;
3022 for ( j = 0; j < ncom; j++ ) {
3024 if ( r > m && r < m+m[1] ) {
3025 m[2] |= DIRTYSYMFLAG;
3029 for ( j = 0; j < neps; j++ ) {
3031 if ( r > m && r < m+m[1] ) {
3032 m[2] |= DIRTYSYMFLAG;
3050 for ( i = 0; i < nnco; i++ ) {
3052 if ( ( *t >= (FUNCTION+WILDOFFSET)
3053 && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
3054 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3055 && functions[*t-FUNCTION].spec <= 0 ) ) {
3061 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
3064 pnco[i][2] |= DIRTYSYMFLAG;
3076 for ( i = 0; i < nnco; i++ ) {
3078 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) && *t != DOLLAREXPRESSION ) {
3080 if ( ( *t >= (FUNCTION+WILDOFFSET)
3081 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
3082 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3083 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
3084 if ( *t >= (FUNCTION+WILDOFFSET) ) {
3086 j = FullSymmetrize(BHEAD t,l);
3089 else j = FullSymmetrize(BHEAD t,l);
3090 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3091 if ( ( j & 2 ) != 0 )
goto NormZero;
3092 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
3095 else t[2] &= ~DIRTYSYMFLAG;
3103 for ( i = 0; i < k; i++ ) {
3105 while ( Commute(pnco[j],pnco[j+1]) ) {
3106 t = pnco[j]; pnco[j] = pnco[j+1]; pnco[j+1] = t;
3108 while ( l >= 0 && Commute(pnco[l],pnco[l+1]) ) {
3109 t = pnco[l]; pnco[l] = pnco[l+1]; pnco[l+1] = t;
3112 if ( ++j >= k )
break;
3119 for ( i = 0; i < nnco; i++ ) {
3121 if ( *t == IDFUNCTION ) AN.idfunctionflag = 1;
3122 if ( *t >= GAMMA && *t <= GAMMASEVEN ) {
3128 *m++ = stype = t[FUNHEAD];
3133 if ( *t == GAMMAFIVE ) {
3134 gtype = GAMMA5; t += FUNHEAD;
goto onegammamatrix; }
3135 else if ( *t == GAMMASIX ) {
3136 gtype = GAMMA6; t += FUNHEAD;
goto onegammamatrix; }
3137 else if ( *t == GAMMASEVEN ) {
3138 gtype = GAMMA7; t += FUNHEAD;
goto onegammamatrix; }
3143 if ( gtype == GAMMA5 ) {
3144 if ( j == GAMMA1 ) j = GAMMA5;
3145 else if ( j == GAMMA5 ) j = GAMMA1;
3146 else if ( j == GAMMA7 ) ncoef = -ncoef;
3147 if ( nnum & 1 ) ncoef = -ncoef;
3149 else if ( gtype == GAMMA6 || gtype == GAMMA7 ) {
3151 if ( gtype == GAMMA6 ) gtype = GAMMA7;
3152 else gtype = GAMMA6;
3154 if ( j == GAMMA1 ) j = gtype;
3155 else if ( j == GAMMA5 ) {
3157 if ( j == GAMMA7 ) ncoef = -ncoef;
3159 else if ( j != gtype )
goto NormZero;
3162 ncoef = REDLENG(ncoef);
3163 if ( Mully(BHEAD (UWORD *)n_coef,&ncoef,(UWORD *)(&shortnum),1) )
goto FromNorm;
3164 ncoef = INCLENG(ncoef);
3168 *m++ = gtype; nnum++;
3173 }
while ( ( ++i < nnco ) && ( *(t = pnco[i]) >= GAMMA
3174 && *t <= GAMMASEVEN ) && ( t[FUNHEAD] == stype ) );
3177 k = WORDDIF(m,to) - FUNHEAD-1;
3180 while ( --k >= 0 ) *from-- = *--r;
3183 to[1] = WORDDIF(m,to);
3185 else if ( *t < 0 ) {
3186 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3190 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
3191 && *t != REPLACEMENT && *t != DOLLAREXPRESSION
3192 && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
3204 for ( i = 0; i < ncom; i++ ) {
3206 if ( ( *t >= (FUNCTION+WILDOFFSET)
3207 && functions[*t-FUNCTION-WILDOFFSET].spec <= 0 )
3208 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3209 && functions[*t-FUNCTION].spec <= 0 ) ) {
3215 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
3218 pcom[i][2] |= DIRTYSYMFLAG;
3228 for ( i = 0; i < ncom; i++ ) {
3230 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) ) {
3232 if ( ( *t >= (FUNCTION+WILDOFFSET)
3233 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
3234 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3235 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
3236 if ( *t >= (FUNCTION+WILDOFFSET) ) {
3238 j = FullSymmetrize(BHEAD t,l);
3241 else j = FullSymmetrize(BHEAD t,l);
3242 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3243 if ( ( j & 2 ) != 0 )
goto NormZero;
3244 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
3247 else t[2] &= ~DIRTYSYMFLAG;
3256 for ( i = 1; i < ncom; i++ ) {
3257 for ( j = i; j > 0; j-- ) {
3263 if ( *r < 0 ) {
if ( *t >= *r )
goto NextI; }
3264 else {
if ( -*t <= *r )
goto NextI; }
3267 else if ( *r < 0 ) {
3268 if ( *t < -*r )
goto NextI;
3271 else if ( *t != *r ) {
3272 if ( *t < *r )
goto NextI;
3273jexch: t = pcom[j]; pcom[j] = pcom[jj]; pcom[jj] = t;
3276 if ( AC.properorderflag ) {
3277 if ( ( *t >= (FUNCTION+WILDOFFSET)
3278 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION )
3279 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3280 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) ) {}
3282 WORD *s1, *s2, *ss1, *ss2;
3283 s1 = t+FUNHEAD; s2 = r+FUNHEAD;
3284 ss1 = t + t[1]; ss2 = r + r[1];
3285 while ( s1 < ss1 && s2 < ss2 ) {
3287 if ( k > 0 )
goto jexch;
3288 if ( k < 0 )
goto NextI;
3292 if ( s1 < ss1 )
goto jexch;
3296 kk = r[1] - FUNHEAD;
3299 while ( k > 0 && kk > 0 ) {
3300 if ( *t < *r )
goto NextI;
3301 else if ( *t++ > *r++ )
goto jexch;
3304 if ( k > 0 )
goto jexch;
3310 kk = r[1] - FUNHEAD;
3313 while ( k > 0 && kk > 0 ) {
3314 if ( *t < *r )
goto NextI;
3315 else if ( *t++ > *r++ )
goto jexch;
3318 if ( k > 0 )
goto jexch;
3324 for ( i = 0; i < ncom; i++ ) {
3326 if ( *t == THETA || *t == THETA2 ) {
3327 if ( ( k = DoTheta(BHEAD t) ) == 0 )
goto NormZero;
3333 else if ( *t == DELTA2 || *t == DELTAP ) {
3334 if ( ( k = DoDelta(t) ) == 0 )
goto NormZero;
3340 else if ( *t == AR.PolyFunInv && AR.PolyFunType == 2 ) {
3345 WORD *mm, *tt = t, numt = 0;
3347 while ( tt < t+t[1] ) { numt++; NEXTARG(tt) }
3349 tt = t; mm = m; k = t[1];
3355 if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
3356 else { *tt++ = *mm++; *tt++ = *mm++; }
3359 k = *mm; NCOPY(tt,mm,k)
3363 if ( *mm <= -FUNCTION ) { *tt++ = *mm++; }
3364 else { *tt++ = *mm++; *tt++ = *mm++; }
3367 k = *mm; NCOPY(tt,mm,k)
3370 t[2] |= MUSTCLEANPRF;
3374 else if ( *t == AR.PolyFun ) {
3375 if ( AR.PolyFunType == 1 ) {
3376 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3377 t[1] == FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER )
goto NormZero;
3378 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) {
3379 if ( AN.PolyNormFlag == 0 ) {
3380 AN.PolyNormFlag = 1;
3387 else if ( AR.PolyFunType == 2 ) {
3398 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3399 t[1] > FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER ) {
3400 u = t + FUNHEAD + 2;
3402 if ( *u <= -FUNCTION ) {}
3403 else if ( t[1] == FUNHEAD+4 && t[FUNHEAD+2] == -SNUMBER
3404 && t[FUNHEAD+3] == 0 )
goto NormPRF;
3405 else if ( t[1] == FUNHEAD+4 )
goto NormZero;
3407 else if ( t[1] == *u+FUNHEAD+2 )
goto NormZero;
3410 u = t+FUNHEAD; NEXTARG(u);
3411 if ( *u == -SNUMBER && u[1] == 0 )
goto NormInf;
3413 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3414 else if ( i < ncom-1 && pcom[i+1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3416 if ( AN.PolyNormFlag ) {
3417 if ( AR.PolyFunExp == 0 ) {
3421 else if ( AR.PolyFunExp == 1 ) {
3422 if ( PolyFunMode == 0 ) {
3429 if ( TreatPolyRatFun(BHEAD mmm) != 0 )
3435 if ( PolyFunMode == 0 ) {
3442 if ( ExpandRat(BHEAD mmm) != 0 )
3449 if ( AR.PolyFunExp == 0 ) {
3453 else if ( AR.PolyFunExp == 1 ) {
3456 if ( TreatPolyRatFun(BHEAD mmm) != 0 )
3463 if ( ExpandRat(BHEAD mmm) != 0 )
3470 else if ( *t > 0 ) {
3471 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG
3472 && *t != REPLACEMENT && TestFunFlag(BHEAD t) ) ReplaceVeto = 1;
3477 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3486 if ( ReplaceVeto < 0 ) {
3496 WORD *ma = fillsetexp, *mb, *mc;
3499 if ( *ma != REPLACEMENT ) {
3503 if ( *ma == REPLACEMENT && ReplaceType == -1 ) {
3506 if ( AN.RSsize < 2*ma[1]+SUBEXPSIZE ) {
3507 if ( AN.ReplaceScrat ) M_free(AN.ReplaceScrat,
"AN.ReplaceScrat");
3508 AN.RSsize = 2*ma[1]+SUBEXPSIZE+40;
3509 AN.ReplaceScrat = (WORD *)Malloc1((AN.RSsize+1)*
sizeof(WORD),
"AN.ReplaceScrat");
3512 ReplaceSub = AN.ReplaceScrat;
3513 ReplaceSub += SUBEXPSIZE;
3515 if ( *ma > 0 )
goto NoRep;
3516 if ( *ma <= -FUNCTION ) {
3517 *ReplaceSub++ = FUNTOFUN;
3519 *ReplaceSub++ = -*ma++;
3520 if ( *ma > -FUNCTION )
goto NoRep;
3521 *ReplaceSub++ = -*ma++;
3523 else if ( ma+4 > mb )
goto NoRep;
3525 if ( *ma == -SYMBOL ) {
3526 if ( ma[2] == -SYMBOL && ma+4 <= mb )
3527 *ReplaceSub++ = SYMTOSYM;
3528 else if ( ma[2] == -SNUMBER && ma+4 <= mb ) {
3529 *ReplaceSub++ = SYMTONUM;
3530 if ( ReplaceType == 0 ) {
3531 oldtoprhs = C->numrhs;
3536 else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
3537 *ReplaceSub++ = SYMTONUM;
3539 *ReplaceSub++ = ma[1];
3548 else if ( ma[2] > 0 ) {
3549 WORD *sstop, *ttstop, n;
3553 while ( ss < sstop ) {
3555 ttstop = tt - ABS(tt[-1]);
3557 while ( ss < ttstop ) {
3558 if ( *ss == INDEX )
goto NoRep;
3564 if ( ReplaceType == 0 ) {
3565 oldtoprhs = C->numrhs;
3569 ss =
AddRHS(AT.ebufnum,1);
3574 while ( --n >= 0 ) *ss++ = *tt++;
3576 C->
rhs[C->numrhs+1] = ss;
3578 *ReplaceSub++ = subtype;
3580 *ReplaceSub++ = ma[1];
3581 *ReplaceSub++ = C->numrhs;
3587 else if ( ( *ma == -VECTOR || *ma == -MINVECTOR ) && ma+4 <= mb ) {
3588 if ( ma[2] == -VECTOR ) {
3589 if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOVEC;
3590 else *ReplaceSub++ = VECTOMIN;
3592 else if ( ma[2] == -MINVECTOR ) {
3593 if ( *ma == -VECTOR ) *ReplaceSub++ = VECTOMIN;
3594 else *ReplaceSub++ = VECTOVEC;
3600 else if ( ma[2] > 0 ) {
3601 WORD *sstop, *ttstop, *w, *mm, n, count;
3603 if ( *ma == -MINVECTOR ) {
3607 while ( ss < sstop ) {
3616 while ( ss < sstop ) {
3618 ttstop = tt - ABS(tt[-1]);
3621 while ( ss < ttstop ) {
3622 if ( *ss == INDEX ) {
3623 n = ss[1] - 2; ss += 2;
3624 while ( --n >= 0 ) {
3625 if ( *ss < MINSPEC ) count++;
3631 if ( count != 1 )
goto NoRep;
3635 if ( ReplaceType == 0 ) {
3636 oldtoprhs = C->numrhs;
3640 mm =
AddRHS(AT.ebufnum,1);
3641 *ReplaceSub++ = subtype;
3643 *ReplaceSub++ = ma[1];
3644 *ReplaceSub++ = C->numrhs;
3648 while ( (mm + n + 10) > C->
Top )
3650 while ( --n >= 0 ) *mm++ = *w++;
3652 C->
rhs[C->numrhs+1] = mm;
3654 mm =
AddRHS(AT.ebufnum,1);
3658 while ( (mm + n + 13) > C->
Top )
3661 while ( w < sstop ) {
3662 tt = w + *w; ttstop = tt - ABS(tt[-1]);
3664 while ( w < ttstop ) {
3665 if ( *w != INDEX ) {
3674 while ( --n >= 0 ) {
3675 if ( *w >= MINSPEC ) *mm++ = *w++;
3680 if ( n <= 2 ) mm -= 2;
3689 while ( w < tt ) *mm++ = *w++;
3690 *ss = WORDDIF(mm,ss);
3693 C->
rhs[C->numrhs+1] = mm;
3695 if ( mm > C->
Top ) {
3696 MLOCK(ErrorMessageLock);
3697 MesPrint(
"Internal error in Normalize with extra compiler buffer");
3698 MUNLOCK(ErrorMessageLock);
3706 else if ( *ma == -INDEX ) {
3707 if ( ( ma[2] == -INDEX || ma[2] == -VECTOR )
3709 *ReplaceSub++ = INDTOIND;
3710 else if ( ma[1] >= AM.OffsetIndex ) {
3711 if ( ma[2] == -SNUMBER && ma+4 <= mb
3712 && ma[3] >= 0 && ma[3] < AM.OffsetIndex )
3713 *ReplaceSub++ = INDTOIND;
3714 else if ( ma[2] == ARGHEAD && ma+2+ARGHEAD <= mb ) {
3715 *ReplaceSub++ = INDTOIND;
3717 *ReplaceSub++ = ma[1];
3728 *ReplaceSub++ = ma[1];
3729 *ReplaceSub++ = ma[3];
3734 AN.ReplaceScrat[1] = ReplaceSub-AN.ReplaceScrat;
3739 while ( mb < m ) *mc++ = *mb++;
3743 if ( ReplaceType > 0 ) {
3744 C->numrhs = oldtoprhs;
3748 if ( ++ReplaceVeto >= 0 )
break;
3759 for ( i = 0; i < neps; i++ ) {
3761 if ( ( t[2] & DIRTYSYMFLAG ) != DIRTYSYMFLAG )
continue;
3762 t[2] &= ~DIRTYSYMFLAG;
3763 if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
3772 if ( *r != FUNNYWILD ) { r++;
continue; }
3773 k = r[1]; u = r + 2;
3776 if ( *u != FUNNYWILD ) ncoef = -ncoef;
3779 tt[-2] = FUNNYWILD; tt[-1] = k; m -= 2;
3783 for ( r = t + 1; r < m; r++ ) {
3784 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3785 else if ( *r == *t )
goto NormZero;
3790 for ( r = t + 2; r < tt; r += 2 ) {
3791 if ( r[1] < t[1] ) {
3792 k = r[1]; r[1] = t[1]; t[1] = k; ncoef = -ncoef; }
3793 else if ( r[1] == t[1] )
goto NormZero;
3802 for ( r = t + 1; r < m; r++ ) {
3803 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3804 else if ( *r == *t )
goto NormZero;
3813 for ( i = 0; i < (neps-1); i++ ) {
3815 for ( j = i+1; j < neps; j++ ) {
3817 if ( t[1] > r[1] ) {
3818 peps[i] = m = r; peps[j] = r = t; t = m;
3820 else if ( t[1] == r[1] ) {
3826 m = peps[j]; peps[j] = t; peps[i] = t = m;
3829 else if ( *r++ > *m++ )
break;
3830 }
while ( --k > 0 );
3835 for ( i = 0; i < neps; i++ ) {
3847 for ( i = 0; i < ndel; i += 2, r += 2 ) {
3848 if ( r[1] < r[0] ) { k = *r; *r = r[1]; r[1] = k; }
3850 for ( i = 2; i < ndel; i += 2, t += 2 ) {
3852 for ( j = i; j < ndel; j += 2 ) {
3853 if ( *r > *t ) { r += 2; }
3854 else if ( *r < *t ) {
3855 k = *r; *r++ = *t; *t++ = k;
3856 k = *r; *r++ = *t; *t-- = k;
3859 if ( *++r < t[1] ) {
3860 k = *r; *r = t[1]; t[1] = k;
3878 for ( i = 0; i < nind; i++ ) {
3880 for ( j = i+1; j < nind; j++ ) {
3882 k = *r; *r = *t; *t = k;
3900 for ( i = 2; i < nvec; i += 2 ) {
3902 for ( j = i; j < nvec; j += 2 ) {
3904 if ( *++r < t[1] ) {
3905 k = *r; *r = t[1]; t[1] = k;
3909 else if ( *r < *t ) {
3910 k = *r; *r++ = *t; *t++ = k;
3911 k = *r; *r++ = *t; *t-- = k;
3931 while ( --i >= 0 ) {
3932 if ( *t > t[1] ) { j = *t; *t = t[1]; t[1] = j; }
3938 while ( t < (m-3) ) {
3942 if ( *++r == *++t ) {
3944 if ( ( *r < MAXPOWER && t[1] < MAXPOWER )
3945 || ( *r > -MAXPOWER && t[1] > -MAXPOWER ) ) {
3948 if ( *t > MAXPOWER || *t < -MAXPOWER ) {
3949 MLOCK(ErrorMessageLock);
3950 MesPrint(
"Exponent of dotproduct out of range: %d",*t);
3951 MUNLOCK(ErrorMessageLock);
3967 else if ( *r < *++t ) {
3968 k = *r; *r++ = *t; *t = k;
3973 else if ( *r < *t ) {
3974 k = *r; *r++ = *t; *t++ = k;
3975 k = *r; *r++ = *t; *t = k;
3978 else { r += 2; t--; }
3980 else if ( *r < *t ) {
3981 k = *r; *r++ = *t; *t++ = k;
3982 k = *r; *r++ = *t; *t++ = k;
3983 k = *r; *r++ = *t; *t = k;
3992 if ( ( i = ndot ) > 0 ) {
4007 *m++ = ( i = nsym ) + 2;
4010 if ( t[1] < (2*MAXPOWER) ) {
4011 if ( t[1] & 1 ) { *m++ = 0; *m++ = 1; }
4013 if ( *++t & 2 ) ncoef = -ncoef;
4017 else if ( *t <= NumSymbols && *t > -2*MAXPOWER ) {
4018 if ( ( ( ( t[1] > symbols[*t].maxpower ) && ( symbols[*t].maxpower < MAXPOWER ) ) ||
4019 ( ( t[1] < symbols[*t].minpower ) && ( symbols[*t].minpower > -MAXPOWER ) ) ) &&
4020 ( t[1] < 2*MAXPOWER ) && ( t[1] > -2*MAXPOWER ) ) {
4021 if ( i <= 2 || t[2] != *t )
goto NormZero;
4023 if ( AN.ncmod == 1 && ( AC.modmode & ALSOPOWERS ) != 0 ) {
4024 if ( AC.cmod[0] == 1 ) t[1] = 0;
4025 else if ( t[1] >= 0 ) t[1] = 1 + (t[1]-1)%(AC.cmod[0]-1);
4027 t[1] = -1 - (-t[1]-1)%(AC.cmod[0]-1);
4028 if ( t[1] < 0 ) t[1] += (AC.cmod[0]-1);
4031 if ( ( t[1] < (2*MAXPOWER) && t[1] >= MAXPOWER )
4032 || ( t[1] > -(2*MAXPOWER) && t[1] <= -MAXPOWER ) ) {
4033 MLOCK(ErrorMessageLock);
4034 MesPrint(
"Exponent out of range: %d",t[1]);
4035 MUNLOCK(ErrorMessageLock);
4038 if ( AT.TrimPower && AR.PolyFunVar == *t && t[1] > AR.PolyFunPow ) {
4045 else { *r -= 2; t += 2; }
4048 *m++ = *t++; *m++ = *t++;
4050 }
while ( (i-=2) > 0 ); }
4051 if ( *r <= 2 ) m = r-1;
4067 if ( ABS(ncoef) == 3 && n_coef[0] == 1 && n_coef[1] == 1 ) {
4068 if ( withfloat == 1 ) {
4074 if ( t[FUNHEAD+3] < 0 ) {
4075 t[FUNHEAD+3] = -t[FUNHEAD+3];
4076 floatsign = -floatsign;
4078 if ( ncoef < 0 ) floatsign = -floatsign;
4082 AT.FloatPos = m-termout;
4083 i = t[1]; NCOPY(m,t,i)
4087 if ( m[FUNHEAD+3] < 0 ) {
4088 m[FUNHEAD+3] = -m[FUNHEAD+3];
4089 floatsign = -floatsign;
4091 if ( ncoef < 0 ) floatsign = -floatsign;
4092 AT.FloatPos = m-termout;
4097 if ( withfloat == 1 ) UnpackFloat(aux4,firstfloat);
4098 RatToFloat(aux5,(UWORD *)n_coef,ncoef);
4099 mpf_mul(aux4,aux4,aux5);
4101 AT.FloatPos = m-termout;
4102 if ( m[FUNHEAD+3] < 0 ) {
4103 m[FUNHEAD+3] = -m[FUNHEAD+3];
4104 floatsign = -floatsign;
4108 n_coef[0] = 1; n_coef[1] = 1; ncoef = floatsign;
4110 else AT.FloatPos = 0;
4117 stop = (WORD *)(((UBYTE *)(termout)) + AM.MaxTer);
4119 if ( ( m + i ) > stop ) {
4120 MLOCK(ErrorMessageLock);
4121 MesPrint(
"Term too complex during normalization");
4122 MUNLOCK(ErrorMessageLock);
4125 if ( ReplaceType >= 0 ) {
4132 if ( ReplaceType == 0 ) {
4133 AT.WorkPointer = termout+*termout;
4134 WildFill(BHEAD term,termout,AN.ReplaceScrat);
4135 termout = term + *term;
4138 AT.WorkPointer = r = termout + *termout;
4139 WildFill(BHEAD r,termout,AN.ReplaceScrat);
4146 r += *term; r -= ABS(r[-1]);
4149 if ( *m >= FUNCTION && m[1] > FUNHEAD &&
4150 functions[*m-FUNCTION].spec != TENSORFUNCTION )
4164 TermFree(n_llnum,
"n_llnum");
4165 TermFree(n_coef,
"NormCoef");
4184 if ( termout < term + *term && termout >= term ) AT.WorkPointer = term + *term;
4185 else AT.WorkPointer = termout;
4192 TermFree(n_llnum,
"n_llnum");
4193 TermFree(n_coef,
"NormCoef");
4197 MLOCK(ErrorMessageLock);
4198 MesPrint(
"Division by zero during normalization");
4199 MUNLOCK(ErrorMessageLock);
4203 MLOCK(ErrorMessageLock);
4204 MesPrint(
"0^0 during normalization of term");
4205 MUNLOCK(ErrorMessageLock);
4209 MLOCK(ErrorMessageLock);
4210 MesPrint(
"0/0 in polyratfun during normalization of term");
4211 MUNLOCK(ErrorMessageLock);
4216 AT.WorkPointer = termout;
4218 TermFree(n_llnum,
"n_llnum");
4219 TermFree(n_coef,
"NormCoef");
4224 TermFree(n_llnum,
"n_llnum");
4225 TermFree(n_coef,
"NormCoef");
4229 MLOCK(ErrorMessageLock);
4231 MUNLOCK(ErrorMessageLock);
4233 TermFree(n_llnum,
"n_llnum");
4234 TermFree(n_coef,
"NormCoef");
4247int ExtraSymbol(WORD sym, WORD pow, WORD nsym, WORD *ppsym, WORD *ncoef)
4255 if ( pow > 2*MAXPOWER || pow < -2*MAXPOWER
4256 || *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
4257 MLOCK(ErrorMessageLock);
4258 MesPrint(
"Illegal wildcard power combination.");
4259 MUNLOCK(ErrorMessageLock);
4264 if ( ( sym <= NumSymbols && sym > -MAXPOWER )
4265 && ( symbols[sym].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
4266 *m %= symbols[sym].maxpower;
4267 if ( *m < 0 ) *m += symbols[sym].maxpower;
4268 if ( ( symbols[sym].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
4269 if ( ( ( symbols[sym].maxpower & 1 ) == 0 ) &&
4270 ( *m >= symbols[sym].maxpower/2 ) ) {
4271 *m -= symbols[sym].maxpower/2; *ncoef = -*ncoef;
4276 if ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
4277 MLOCK(ErrorMessageLock);
4278 MesPrint(
"Power overflow during normalization");
4279 MUNLOCK(ErrorMessageLock);
4285 { *m = m[2]; m++; *m = m[2]; m++; i++; }
4290 else if ( sym < *m ) {
4298 { m--; m[2] = *m; m--; m[2] = *m; i++; }
4309int DoTheta(PHEAD WORD *t)
4312 WORD k, *r1, *r2, *tstop, type;
4313 WORD ia, *ta, *tb, *stopa, *stopb;
4314 if ( AC.BracketNormalize )
return(-1);
4319 if ( k <= FUNHEAD )
return(1);
4322 if ( r1 == tstop ) {
4326 if ( *t == ARGHEAD ) {
4327 if ( type == THETA )
return(1);
4331 if ( *t == -SNUMBER ) {
4332 if ( t[1] < 0 )
return(0);
4334 if ( type == THETA2 && t[1] == 0 )
return(0);
4341 if ( *t == ABS(k)+1+ARGHEAD ) {
4342 if ( k > 0 )
return(1);
4352 if ( r2 < tstop )
return(-1);
4357 if ( *t == -SNUMBER && *r1 == -SNUMBER ) {
4358 if ( t[1] > r1[1] )
return(0);
4359 else if ( t[1] < r1[1] ) {
4362 else if ( type == THETA )
return(1);
4365 else if ( t[1] == 0 && *t == -SNUMBER ) {
4367 else if ( *t < *r1 )
return(1);
4368 else if ( *t > *r1 )
return(0);
4370 else if ( r1[1] == 0 && *r1 == -SNUMBER ) {
4372 else if ( *t < *r1 )
return(1);
4373 else if ( *t > *r1 )
return(0);
4375 r2 = AT.WorkPointer;
4389 ta += ARGHEAD; tb += ARGHEAD;
4390 while ( ta < stopa ) {
4391 if ( tb >= stopb )
return(0);
4392 if ( ( ia = CompareTerms(BHEAD ta,tb,(WORD)1) ) < 0 )
return(0);
4393 if ( ia > 0 )
return(1);
4397 if ( type == THETA )
return(1);
4408 WORD k, *r1, *r2, *tstop, isnum, isnum2, type = *t;
4409 if ( AC.BracketNormalize )
return(-1);
4411 if ( k <= FUNHEAD )
goto argzero;
4412 if ( k == FUNHEAD+ARGHEAD && t[FUNHEAD] == ARGHEAD )
goto argzero;
4419 if ( *t == -SNUMBER ) { isnum = 1; k = t[1]; }
4425 if ( k == *t-ARGHEAD-1 ) isnum = 1;
4429 if ( r1 >= tstop ) {
4430 if ( !isnum )
return(-1);
4431 if ( k == 0 )
goto argzero;
4436 if ( r2 < tstop )
return(-1);
4438 if ( *r1 == -SNUMBER ) { isnum2 = 1; }
4444 if ( k == *r1-ARGHEAD-1 ) isnum2 = 1;
4447 if ( isnum != isnum2 )
return(-1);
4449 while ( t < tstop && r1 < r2 ) {
4451 if ( !isnum )
return(-1);
4456 if ( t != tstop || r1 != r2 ) {
4457 if ( !isnum )
return(-1);
4461 if ( type == DELTA2 )
return(1);
4464 if ( type == DELTA2 )
return(0);
4473void DoRevert(WORD *fun, WORD *tmp)
4475 WORD *t, *r, *m, *to, *tt, *mm, i, j;
4480 if ( *r == -REVERSEFUNCTION ) {
4482 while ( mm < to ) *m++ = *mm++;
4485 fun[2] |= DIRTYSYMFLAG;
4487 else if ( *r <= -FUNCTION ) r++;
4489 if ( *r == -INDEX && r[1] < MINSPEC ) *r = -VECTOR;
4494 if ( ( *r > ARGHEAD )
4495 && ( r[ARGHEAD+1] == REVERSEFUNCTION )
4496 && ( *r == (r[ARGHEAD]+ARGHEAD) )
4497 && ( r[ARGHEAD] == (r[ARGHEAD+2]+4) )
4498 && ( *(r+*r-3) == 1 )
4499 && ( *(r+*r-2) == 1 )
4500 && ( *(r+*r-1) == 3 ) ) {
4512 while ( --j >= 0 ) {
4515 while ( --i >= 0 ) {
4522 else if ( *t <= -FUNCTION ) *m++ = *t++;
4523 else { *m++ = *t++; *m++ = *t++; }
4534 fun[1] = WORDDIF(t,fun);
4536 fun[2] |= DIRTYSYMFLAG;
4559#define MAXNUMBEROFNONCOMTERMS 2
4561WORD DetCommu(WORD *terms)
4563 WORD *t, *tnext, *tstop;
4565 if ( *terms == 0 )
return(0);
4566 if ( terms[*terms] == 0 )
return(0);
4570 tstop = tnext - ABS(tnext[-1]);
4572 while ( t < tstop ) {
4573 if ( *t >= FUNCTION ) {
4574 if ( functions[*t-FUNCTION].commute ) {
4576 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4580 else if ( *t == SUBEXPRESSION ) {
4581 if ( cbuf[t[4]].CanCommu[t[2]] ) {
4583 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4587 else if ( *t == EXPRESSION ) {
4589 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4592 else if ( *t == DOLLAREXPRESSION ) {
4599 if ( cbuf[AM.dbufnum].CanCommu[t[2]] ) {
4601 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4620WORD DoesCommu(WORD *term)
4624 if ( *term == 0 )
return(0);
4625 tstop = term + *term;
4626 tstop = tstop - ABS(tstop[-1]);
4628 while ( term < tstop ) {
4629 if ( ( *term >= FUNCTION ) && ( functions[*term-FUNCTION].commute ) ) {
4631 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4646WORD *PolyNormPoly (PHEAD WORD *Poly) {
4649 WORD *buffer = AT.WorkPointer;
4651 if (
NewSort(BHEAD0) ) { Terminate(-1); }
4657 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4663 if (
EndSort(BHEAD buffer,1) < 0 ) {
4664 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4668 while ( *p ) p += *p;
4669 AR.CompareRoutine = (COMPAREDUMMY)(&
Compare1);
4670 AT.WorkPointer = p + 1;
4697WORD *EvaluateGcd(PHEAD WORD *subterm)
4700 WORD *oldworkpointer = AT.WorkPointer, *work1, *work2, *work3;
4701 WORD *t, *tt, *ttt, *t1, *t2, *t3, *t4, *tstop;
4704 WORD *lnum=n_llnum+1;
4705 WORD *num1, *num2, *num3, *den1, *den2, *den3;
4706 WORD sizenum1, sizenum2, sizenum3, sizeden1, sizeden2, sizeden3;
4707 int i, isnumeric = 0, numarg = 0 ;
4713 tt = subterm + subterm[1]; t = subterm + FUNHEAD;
4717 if ( *t == -SNUMBER ) {
4720 MLOCK(ErrorMessageLock);
4721 MesPrint(
"Trying to take the GCD involving a zero term.");
4722 MUNLOCK(ErrorMessageLock);
4726 t1 = subterm + FUNHEAD;
4727 while ( gcdnum > 1 && t1 < tt ) {
4728 if ( *t1 == -SNUMBER ) {
4730 if ( stor == 0 )
goto gcdzero;
4731 if ( GcdLong(BHEAD (UWORD *)&stor,1,(UWORD *)&gcdnum,1,
4732 (UWORD *)lnum,&nnum) )
goto FromGCD;
4737 else if ( *t1 == -SYMBOL )
goto gcdisone;
4738 else if ( *t1 < 0 )
goto gcdillegal;
4744 ct = *ttt; *ttt = 0;
4746 t1 = PolyNormPoly(BHEAD t1+ARGHEAD);
4755 while ( t3 > t2 && *t3 == 0 ) { t3--; i--; }
4756 if ( GcdLong(BHEAD (UWORD *)t2,(WORD)i,(UWORD *)&gcdnum,1,
4757 (UWORD *)lnum,&nnum) ) {
4762 if ( gcdnum == 1 ) {
4769 AT.WorkPointer = oldworkpointer;
4771 if ( gcdnum == 1 )
goto gcdisone;
4772 oldworkpointer[0] = 4;
4773 oldworkpointer[1] = gcdnum;
4774 oldworkpointer[2] = 1;
4775 oldworkpointer[3] = 3;
4776 oldworkpointer[4] = 0;
4777 AT.WorkPointer = oldworkpointer + 5;
4778 return(oldworkpointer);
4780 else if ( *t == -SYMBOL ) {
4781 t1 = subterm + FUNHEAD;
4784 if ( *t1 == -SNUMBER )
goto gcdisone;
4785 if ( *t1 == -SYMBOL ) {
4786 if ( t1[1] != i )
goto gcdisone;
4789 if ( *t1 < 0 )
goto gcdillegal;
4791 ct = *ttt; *ttt = 0;
4793 t2 = PolyNormPoly(BHEAD t1+ARGHEAD);
4795 else t2 = t1 + ARGHEAD;
4799 tstop = t2 - ABS(t2[-1]);
4800 while ( t3 < tstop ) {
4801 if ( *t3 != SYMBOL ) {
4808 if ( *t4 == i && t4[1] > 0 )
goto nextterminarg;
4818 AT.WorkPointer = oldworkpointer;
4820 oldworkpointer[0] = 8;
4821 oldworkpointer[1] = SYMBOL;
4822 oldworkpointer[2] = 4;
4823 oldworkpointer[3] = t[1];
4824 oldworkpointer[4] = 1;
4825 oldworkpointer[5] = 1;
4826 oldworkpointer[6] = 1;
4827 oldworkpointer[7] = 3;
4828 oldworkpointer[8] = 0;
4829 AT.WorkPointer = oldworkpointer+9;
4830 return(oldworkpointer);
4832 else if ( *t < 0 ) {
4834 MLOCK(ErrorMessageLock);
4835 MesPrint(
"Illegal object in gcd_ function. Object not a number or a symbol.");
4836 MUNLOCK(ErrorMessageLock);
4839 else if ( ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4840 else if ( t[1] != 0 ) {
4841 ttt = t + *t; ct = *ttt; *ttt = 0;
4842 t = PolyNormPoly(BHEAD t+ARGHEAD);
4844 if ( t[*t] == 0 && ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4845 AT.WorkPointer = oldworkpointer;
4860 AT.WorkPointer = oldworkpointer;
4862 t = subterm + FUNHEAD;
4863 for ( i = 1; i < isnumeric; i++ ) {
4867 ttt = t + *t; ct = *ttt; *ttt = 0;
4868 t = PolyNormPoly(BHEAD t+ARGHEAD);
4872 i = (ABS(t[-1])-1)/2;
4875 sizenum1 = sizeden1 = i;
4876 while ( sizenum1 > 1 && num1[sizenum1-1] == 0 ) sizenum1--;
4877 while ( sizeden1 > 1 && den1[sizeden1-1] == 0 ) sizeden1--;
4878 work1 = AT.WorkPointer+1; work2 = work1+sizenum1;
4879 for ( i = 0; i < sizenum1; i++ ) work1[i] = num1[i];
4880 for ( i = 0; i < sizeden1; i++ ) work2[i] = den1[i];
4881 num1 = work1; den1 = work2;
4882 AT.WorkPointer = work2 = work2 + sizeden1;
4883 t = subterm + FUNHEAD;
4885 ttt = t + *t; ct = *ttt; *ttt = 0;
4887 t = PolyNormPoly(BHEAD t+ARGHEAD);
4892 i = (ABS(t[-1])-1)/2;
4895 sizenum2 = sizeden2 = i;
4896 while ( sizenum2 > 1 && num2[sizenum2-1] == 0 ) sizenum2--;
4897 while ( sizeden2 > 1 && den2[sizeden2-1] == 0 ) sizeden2--;
4898 num3 = AT.WorkPointer;
4899 if ( GcdLong(BHEAD (UWORD *)num2,sizenum2,(UWORD *)num1,sizenum1,
4900 (UWORD *)num3,&sizenum3) )
goto FromGCD;
4901 sizenum1 = sizenum3;
4902 for ( i = 0; i < sizenum1; i++ ) num1[i] = num3[i];
4903 den3 = AT.WorkPointer;
4904 if ( GcdLong(BHEAD (UWORD *)den2,sizeden2,(UWORD *)den1,sizeden1,
4905 (UWORD *)den3,&sizeden3) )
goto FromGCD;
4906 sizeden1 = sizeden3;
4907 for ( i = 0; i < sizeden1; i++ ) den1[i] = den3[i];
4908 if ( sizenum1 == 1 && num1[0] == 1 && sizeden1 == 1 && den1[1] == 1 )
4913 AT.WorkPointer = work2;
4915 AT.WorkPointer = oldworkpointer;
4919 if ( sizenum1 > sizeden1 ) {
4920 while ( sizenum1 > sizeden1 ) den1[sizeden1++] = 0;
4922 else if ( sizenum1 < sizeden1 ) {
4923 while ( sizenum1 < sizeden1 ) num1[sizenum1++] = 0;
4928 if ( num1 != t ) { NCOPY(t,num1,sizenum1); }
4930 if ( den1 != t ) { NCOPY(t,den1,sizeden1); }
4935 return(oldworkpointer);
4942 t = subterm + FUNHEAD;
4943 AT.WorkPointer += AM.MaxTer/
sizeof(WORD);
4944 work2 = AT.WorkPointer;
4951 work1 = AT.WorkPointer;
4952 ttt = t + *t; ct = *ttt; *ttt = 0;
4953 t = PolyNormPoly(BHEAD t+ARGHEAD);
4954 if ( *work1 < AT.WorkPointer-work1 ) {
4963 *AT.WorkPointer++ = 0;
4969 if ( work2 != work3 ) {
4970 work1 = PolyGCD2(BHEAD work1,work2);
4972 while ( *work2 ) work2 += *work2;
4976 while ( *work2 ) work2 += *work2;
4977 size = work2 - work1 + 1;
4979 NCOPY(t,work1,size);
4981 return(oldworkpointer);
4984 oldworkpointer[0] = 4;
4985 oldworkpointer[1] = 1;
4986 oldworkpointer[2] = 1;
4987 oldworkpointer[3] = 3;
4988 oldworkpointer[4] = 0;
4989 AT.WorkPointer = oldworkpointer+5;
4990 return(oldworkpointer);
4992 MLOCK(ErrorMessageLock);
4993 MesCall(
"EvaluateGcd");
4994 MUNLOCK(ErrorMessageLock);
5011int TreatPolyRatFun(PHEAD WORD *prf)
5013 WORD *t, *tstop, *r, *rstop, *m, *mstop;
5014 WORD exp1 = MAXPOWER, exp2 = MAXPOWER;
5017 if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
5018 if ( exp1 > 1 ) exp1 = 1;
5022 if ( exp1 > 0 ) exp1 = 0;
5029 while ( t < tstop ) {
5035 rstop = t - ABS(t[-1]);
5036 while ( r < rstop ) {
5037 if ( *r != SYMBOL ) { r += r[1];
continue; }
5041 while ( m < mstop ) {
5042 if ( *m == AR.PolyFunVar ) {
5043 if ( m[1] < exp1 ) exp1 = m[1];
5049 if ( exp1 > 0 ) exp1 = 0;
5054 if ( exp1 > 0 ) exp1 = 0;
5060 if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) {
5061 if ( exp2 > 1 ) exp2 = 1;
5064 if ( exp2 > 0 ) exp2 = 0;
5070 while ( t < tstop ) {
5076 rstop = t - ABS(t[-1]);
5077 while ( r < rstop ) {
5078 if ( *r != SYMBOL ) { r += r[1];
continue; }
5082 while ( m < mstop ) {
5083 if ( *m == AR.PolyFunVar ) {
5084 if ( m[1] < exp2 ) exp2 = m[1];
5090 if ( exp2 > 0 ) exp2 = 0;
5095 if ( exp2 > 0 ) exp2 = 0;
5108 *t++ = -SNUMBER; *t++ = 1;
5109 *t++ = -SNUMBER; *t++ = 1;
5111 else if ( exp1 > 0 ) {
5113 *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
5119 *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
5120 *t++ = exp1; *t++ = 1; *t++ = 1; *t++ = 3;
5122 *t++ = -SNUMBER; *t++ = 1;
5125 *t++ = -SNUMBER; *t++ = 1;
5127 *t++ = -SYMBOL; *t++ = AR.PolyFunVar;
5133 *t++ = 8; *t++ = SYMBOL; *t++ = 4; *t++ = AR.PolyFunVar;
5134 *t++ = -exp1; *t++ = 1; *t++ = 1; *t++ = 3;
5147void DropCoefficient(PHEAD WORD *term)
5150 WORD *t = term + *term;
5152 n = t[-1]; na = ABS(n);
5154 if ( n == 3 && t[0] == 1 && t[1] == 1 )
return;
5156 t[0] = 1; t[1] = 1; t[2] = 3;
5165void DropSymbols(PHEAD WORD *term)
5168 WORD *tend = term + *term, *t1, *t2, *tstop;
5169 tstop = tend - ABS(tend[-1]);
5171 while ( t1 < tstop ) {
5172 if ( *t1 == SYMBOL ) {
5175 while ( t2 < tend ) *t1++ = *t2++;
5198 WORD *t, *b, *bb, *tt, *m, *tstop;
5201 WORD buffer[7*NORMSIZE];
5204 *b++ = SYMBOL; *b++ = 2;
5206 tstop = t - ABS(t[-1]);
5208 while ( t < tstop ) {
5209 if ( *t == SYMBOL && t < tstop ) {
5210 for ( i = 2; i < t[1]; i += 2 ) {
5213 if ( bb[0] == t[i] ) {
5215 if ( bb[1] > MAXPOWER || bb[1] < -MAXPOWER ) {
5216 MLOCK(ErrorMessageLock);
5217 MesPrint(
"Power in SymbolNormalize out of range");
5218 MUNLOCK(ErrorMessageLock);
5224 bb[0] = bb[2]; bb[1] = bb[3]; bb += 2;
5229 else if ( bb[0] > t[i] ) {
5231 while ( m > bb ) { m[1] = m[-1]; m[0] = m[-2]; m -= 2; }
5240 *b++ = t[i]; *b++ = t[i+1];
5246 MLOCK(ErrorMessageLock);
5247 MesPrint(
"Illegal term in SymbolNormalize");
5248 MUNLOCK(ErrorMessageLock);
5253 buffer[1] = b - buffer;
5257 if ( AT.LeaveNegative == 0 ) {
5258 b = buffer; bb = b + b[1]; b += 3;
5261 MLOCK(ErrorMessageLock);
5262 MesPrint(
"Negative power in SymbolNormalize");
5263 MUNLOCK(ErrorMessageLock);
5275 b = buffer; tt = term + 1;
5276 if ( i > 2 ) { NCOPY(tt,b,i) }
5279 if ( i < 0 ) i = -i;
5280 *term -= (tstop-tt);
5294int TestFunFlag(PHEAD WORD *tfun)
5296 WORD *t, *tstop, *r, *rstop, *m, *mstop;
5297 if ( functions[*tfun-FUNCTION].spec <= 0 )
return(0);
5298 tstop = tfun + tfun[1];
5300 while ( t < tstop ) {
5301 if ( *t < 0 ) { NEXTARG(t);
continue; }
5303 if ( t[1] == 0 ) { t = rstop;
continue; }
5305 while ( r < rstop ) {
5306 m = r+1; mstop = r+*r; mstop -= ABS(mstop[-1]);
5307 while ( m < mstop ) {
5308 if ( *m == SUBEXPRESSION || *m == EXPRESSION || *m == DOLLAREXPRESSION )
return(1);
5309 if ( ( *m >= FUNCTION ) && ( ( m[2] & DIRTYFLAG ) == DIRTYFLAG )
5310 && ( *m != REPLACEMENT ) && TestFunFlag(BHEAD m) )
return(1);
5325int BracketNormalize(PHEAD WORD *term)
5327 WORD *stop = term+*term-3, *t, *tt, *tstart, *r;
5328 WORD *oldwork = AT.WorkPointer;
5331 termout = AT.WorkPointer = term+*term;
5335 tt = termout+1; t = term+1;
5336 while ( t < stop ) {
5337 if ( *t >= FUNCTION ) { i = t[1]; NCOPY(tt,t,i); }
5340 if ( tt > termout+1 && tt-termout-1 > termout[2] ) {
5341 r = termout+1; ii = tt-r;
5342 for ( i = 0; i < ii-FUNHEAD; i += FUNHEAD ) {
5343 for ( j = i+FUNHEAD; j > 0; j -= FUNHEAD ) {
5344 if ( functions[r[j-FUNHEAD]-FUNCTION].commute
5345 && functions[r[j]-FUNCTION].commute == 0 )
break;
5346 if ( r[j-FUNHEAD] > r[j] ) EXCH(r[j-FUNHEAD],r[j])
5352 tstart = tt; t = term + 1; *tt++ = DELTA; *tt++ = 2;
5353 while ( t < stop ) {
5354 if ( *t == DELTA ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5357 if ( tstart[1] > 2 ) {
5358 for ( r = tstart+2; r < tstart+tstart[1]; r += 2 ) {
5359 if ( r[0] > r[1] ) EXCH(r[0],r[1])
5362 if ( tstart[1] > 4 ) {
5363 r = tstart+2; ii = tstart[1]-2;
5364 for ( i = 0; i < ii-2; i += 2 ) {
5365 for ( j = i+2; j > 0; j -= 2 ) {
5366 if ( r[j-2] > r[j] ) {
5370 else if ( r[j-2] < r[j] )
break;
5372 if ( r[j-1] > r[j+1] ) EXCH(r[j-1],r[j+1])
5377 tt = tstart+tstart[1];
5379 else if ( tstart[1] == 2 ) { tt = tstart; }
5382 tstart = tt; t = term + 1; *tt++ = INDEX; *tt++ = 2;
5383 while ( t < stop ) {
5384 if ( *t == INDEX ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5387 if ( tstart[1] >= 4 ) {
5388 r = tstart+2; ii = tstart[1]-2;
5389 for ( i = 0; i < ii-1; i += 1 ) {
5390 for ( j = i+1; j > 0; j -= 1 ) {
5391 if ( r[j-1] > r[j] ) EXCH(r[j-1],r[j])
5395 tt = tstart+tstart[1];
5397 else if ( tstart[1] == 2 ) { tt = tstart; }
5400 tstart = tt; t = term + 1; *tt++ = DOTPRODUCT; *tt++ = 2;
5401 while ( t < stop ) {
5402 if ( *t == DOTPRODUCT ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5405 if ( tstart[1] > 5 ) {
5406 r = tstart+2; ii = tstart[1]-2;
5407 for ( i = 0; i < ii; i += 3 ) {
5408 if ( r[i] > r[i+1] ) EXCH(r[i],r[i+1])
5410 for ( i = 0; i < ii-3; i += 3 ) {
5411 for ( j = i+3; j > 0; j -= 3 ) {
5412 if ( r[j-3] < r[j] )
break;
5413 if ( r[j-3] > r[j] ) {
5418 if ( r[j-2] > r[j+1] ) EXCH(r[j-2],r[j+1])
5423 tt = tstart+tstart[1];
5425 else if ( tstart[1] == 2 ) { tt = tstart; }
5427 if ( tstart[2] > tstart[3] ) EXCH(tstart[2],tstart[3])
5431 tstart = tt; t = term + 1; *tt++ = SYMBOL; *tt++ = 2;
5432 while ( t < stop ) {
5433 if ( *t == SYMBOL ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5436 if ( tstart[1] > 4 ) {
5437 r = tstart+2; ii = tstart[1]-2;
5438 for ( i = 0; i < ii-2; i += 2 ) {
5439 for ( j = i+2; j > 0; j -= 2 ) {
5440 if ( r[j-2] > r[j] ) EXCH(r[j-2],r[j])
5444 tt = tstart+tstart[1];
5446 else if ( tstart[1] == 2 ) { tt = tstart; }
5449 tstart = tt; t = term + 1; *tt++ = SETSET; *tt++ = 2;
5450 while ( t < stop ) {
5451 if ( *t == SETSET ) { i = t[1]-2; t += 2; tstart[1] += i; NCOPY(tt,t,i); }
5454 if ( tstart[1] > 4 ) {
5455 r = tstart+2; ii = tstart[1]-2;
5456 for ( i = 0; i < ii-2; i += 2 ) {
5457 for ( j = i+2; j > 0; j -= 2 ) {
5458 if ( r[j-2] > r[j] ) {
5465 tt = tstart+tstart[1];
5467 else if ( tstart[1] == 2 ) { tt = tstart; }
5469 *tt++ = 1; *tt++ = 1; *tt++ = 3;
5470 t = term; i = *termout = tt - termout; tt = termout;
5472 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)